Как компания, использующая IIS для развертывания нескольких веб-сайтов и служб, мы каким-то образом пытаемся развернуть веб-службу Python на основе FastAPI, однако эта проблема может не ограничиваться Python. Мы пытаемся использовать либо httpPlatformHandler
модуль или его преемник, AspNetCoreModuleV2
модуль.
Конфигурация для httpPlattformHandler
модуль сейчас выглядит так:
<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>
Конфигурация для AspNetCoreModuleV2
модуль очень похож, так как он работает почти так же:
<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>
Оба модуля работают нормально и пересылают запросы на АСГИ сервер увикорнесли веб-служба работает непосредственно по корневому пути /
(уровень сайта). Однако теперь мы хотим развернуть одну из веб-служб по определенному пути, например /api
(уровень приложения). Вот тут-то и начинается настоящая проблема, потому что приложение FastAPI не знает пути /api
поэтому он отвечает на все запросы, как если бы /api
часть пути принадлежит фактическому запросу.
Документация FastAPI содержит главу о запуске за прокси:
В данном случае наличие прокси с удаленным префиксом пути означает, что вы можете объявить путь по адресу
/app
в вашем коде, но затем вы добавляете слой сверху (прокси), который поместит ваше приложение FastAPI по пути, например/api/v1
.В этом случае исходный путь
/app
на самом деле будет подан в/api/v1/app
.Несмотря на то, что весь ваш код написан при условии, что есть только
/app
.И прокси-сервер будет «снимать» префикс пути на лету перед передачей запроса в Uvicorn, чтобы ваше приложение было уверено, что оно обслуживается на
/app
так что вам не нужно обновлять весь свой код, чтобы включить префикс/api/v1
.
Теперь вопрос заключается в том, как настроить IIS для применения этого разделения пути перед маршрутизацией запроса к httpPlatformHandler
или AspNetCoreModuleV2
модуль.
Мы попытались использовать URL переписать как в приведенном ниже примере, но переписывание, похоже, происходит до маршрутизации в приложение, в результате чего запросы больше не направляются в приложение FastAPI:
<rewrite>
<rules>
<rule name="Proxy" stopProcessing="true">
<match url="^api/(.*)" />
<action type="Rewrite" url="/{R:1}" />
</rule>
</rewrite>
</rules>
Мы взглянули на Маршрутизация запросов приложений module тоже, но это кажется огромным излишеством для такого простого варианта использования.
В качестве примечания, мы недавно также использовали FastCgiModule
в сочетании с Microsoft wfastcgi
библиотека для Python, даже если бы нам пришлось сначала преобразовать приложение ASGI в приложение WSGI (с помощью a2wsgi
). FastCgiModule
успешно удалил путь после настройки свойств path
и как-то схематично 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>
К сожалению, мы не можем продолжать использовать этот подход, особенно из-за перехода с ASGI на WSGI.
iis переписать питон