Как компания, использующая 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>
Оба модуля работают нормально и пересылают запросы на АСГИ сервер увикорн, если веб-служба работает непосредственно по корневому пути /
(уровень сайта). Однако теперь мы хотим развернуть одну из веб-служб по определенному пути, например. /апи
(уровень приложения). Вот тут-то и начинается настоящая проблема, потому что приложение FastAPI не знает пути /апи
, поэтому он отвечает на все запросы, как если бы /апи
часть пути принадлежит фактическому запросу.
Документация FastAPI содержит главу о запуске за прокси:
В данном случае наличие прокси с удаленным префиксом пути означает, что вы можете объявить путь по адресу /приложение
в вашем коде, но затем вы добавляете слой сверху (прокси), который поместит ваше приложение FastAPI по пути, например /апи/v1
.
В этом случае исходный путь /приложение
на самом деле будет подан в /API/v1/приложение
.
Несмотря на то, что весь ваш код написан при условии, что есть только /приложение
.
И прокси-сервер будет «снимать» префикс пути на лету перед передачей запроса в Uvicorn, чтобы ваше приложение было уверено, что оно обслуживается на /приложение
, так что вам не нужно обновлять весь свой код, чтобы включить префикс /апи/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
успешно удалил путь после настройки свойств дорожка
и как-то схематично разрешитьPathInfo
:
<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.