Là một công ty sử dụng IIS để triển khai một số trang web và dịch vụ, bằng cách nào đó, chúng tôi gặp khó khăn khi triển khai một dịch vụ web Python dựa trên API nhanh, tuy nhiên vấn đề này có thể không chỉ giới hạn ở Python. Chúng tôi đang cố gắng sử dụng một trong hai httpPlatformHandler
mô-đun hoặc người kế nhiệm của nó, AspNetCoreModuleV2
mô-đun.
Cấu hình cho httpPlattformHandler
mô-đun trông như thế này ngay bây giờ:
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatform"
path="*"
verb="*"
modules="httpPlatformHandler"
resourceType="Unspecified"/>
</handlers>
<httpPlatform processPath=".\venv\Scripts\python.exe"
arguments="-m uvicorn test:app --port %HTTP_PLATFORM_PORT%"
stdoutLogEnabled="true"
stdoutLogFile=".\python.log"/>
</system.webServer>
</configuration>
Cấu hình cho AspNetCoreModuleV2
module rất giống nhau vì nó dường như hoạt động khá giống nhau:
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore"
path="*"
verb="*"
modules="AspNetCoreModuleV2"
resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath=".\venv\Scripts\python.exe"
arguments="-m uvicorn test:app --port %ASPNETCORE_PORT%"
stdoutLogEnabled="true"
stdoutLogFile=".\python.log"/>
</system.webServer>
</configuration>
Cả hai mô-đun đều hoạt động tốt và chuyển tiếp các yêu cầu tới ASGI người phục vụ trứng sống, miễn là dịch vụ web chạy trực tiếp dưới đường dẫn gốc /
(cấp trang web). Tuy nhiên, bây giờ chúng tôi muốn triển khai một trong các dịch vụ web theo một đường dẫn cụ thể, ví dụ: /api
(cấp ứng dụng). Đây là nơi vấn đề thực sự bắt đầu, vì ứng dụng FastAPI không biết đường dẫn /api
, vì vậy nó trả lời tất cả các yêu cầu như thể /api
một phần của đường dẫn thuộc về yêu cầu thực tế.
Tài liệu về FastAPI chứa một chương về cách chạy đằng sau một proxy:
Trong trường hợp này, có proxy với tiền tố đường dẫn bị tước nghĩa là bạn có thể khai báo đường dẫn tại /ứng dụng
trong mã của bạn, nhưng sau đó, bạn thêm một lớp ở trên cùng (proxy) sẽ đặt ứng dụng FastAPI của bạn theo một đường dẫn như /api/v1
.
Trong trường hợp này, đường dẫn ban đầu /ứng dụng
thực sự sẽ được phục vụ tại /api/v1/ứng dụng
.
Mặc dù tất cả mã của bạn được viết giả sử chỉ có /ứng dụng
.
Và proxy sẽ nhanh chóng "tước" tiền tố đường dẫn trước khi truyền yêu cầu tới Uvicorn, hãy đảm bảo rằng ứng dụng của bạn đang phục vụ tại /ứng dụng
, để bạn không phải cập nhật tất cả mã của mình để bao gồm tiền tố /api/v1
.
Câu hỏi bây giờ là làm cách nào để định cấu hình IIS để áp dụng tính năng tách đường dẫn này trước khi định tuyến yêu cầu tới httpPlatformHandler
hoặc là AspNetCoreModuleV2
mô-đun.
Chúng tôi đã cố gắng sử dụng Viết lại URL mô-đun như trong ví dụ bên dưới, nhưng quá trình viết lại dường như diễn ra trước khi định tuyến đến ứng dụng, khiến các yêu cầu không được định tuyến đến ứng dụng FastAPI nữa:
<rewrite>
<rules>
<rule name="Proxy" stopProcessing="true">
<match url="^api/(.*)" />
<action type="Rewrite" url="/{R:1}" />
</rule>
</rewrite>
</rules>
Chúng tôi đã xem xét Định tuyến yêu cầu ứng dụng module cũng vậy, nhưng nó có vẻ là quá mức cần thiết cho một trường hợp sử dụng đơn giản như vậy.
Như một lưu ý phụ, gần đây chúng tôi cũng đã sử dụng FastCgiModule
kết hợp với Microsoft wfastcgi
thư viện cho Python, ngay cả khi trước tiên chúng tôi phải chuyển đổi ứng dụng ASGI thành ứng dụng WSGI (với sự trợ giúp của a2wsgi
). Các FastCgiModule
tước thành công đường dẫn sau khi định cấu hình thuộc tính con đường
và bằng cách nào đó sơ sài allowPathInfo
:
<configuration>
<system.webServer>
<handlers>
<add name="FastCGI"
path="api/"
allowPathInfo="true"
verb="*"
modules="FastCgiModule"
scriptProcessor="<path-created-by-wfastcgi>"
resourceType="Unspecified"
requireAccess="Script" />
</handlers>
</system.webServer>
<appSettings>
<add key="WSGI_HANDLER" value="my_api.wsgi_app" />
</appSettings>
</configuration>
Rất tiếc, chúng tôi không thể tiếp tục sử dụng phương pháp này, đặc biệt là do việc chuyển đổi từ ASGI sang WSGI.