Как компания, использующая 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.