ในฐานะที่เป็นบริษัทที่ใช้ IIS สำหรับการปรับใช้เว็บไซต์และบริการต่างๆ เราประสบปัญหาในการปรับใช้บริการเว็บ Python ตาม FastAPIอย่างไรก็ตาม ปัญหานี้อาจไม่จำกัดเฉพาะ Python เรากำลังพยายามใช้ทั้ง httpPlatformHandler
โมดูลหรือตัวตายตัวแทนของมัน, the 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>
ทั้งสองโมดูลทำงานได้ดีและส่งต่อคำขอไปยัง ASGI เซิร์ฟเวอร์ ยูวิคอร์นตราบใดที่บริการเว็บทำงานโดยตรงภายใต้เส้นทางรูท /
(ระดับไซต์). อย่างไรก็ตาม ตอนนี้เราต้องการปรับใช้หนึ่งในบริการเว็บภายใต้เส้นทางเฉพาะ เช่น /api
(ระดับแอปพลิเคชัน). นี่คือจุดเริ่มต้นของปัญหาที่แท้จริง เนื่องจากแอปพลิเคชัน FastAPI ไม่รู้จักเส้นทาง /api
จึงตอบรับทุกคำขอราวกับว่า /api
ส่วนหนึ่งของเส้นทางเป็นของคำขอจริง
เอกสารประกอบของ FastAPI ประกอบด้วยบทเกี่ยวกับการเรียกใช้ ด้านหลังหนังสือมอบฉันทะ:
ในกรณีนี้ การมีพร็อกซีที่มีคำนำหน้าพาธแบบแยกส่วน หมายความว่าคุณสามารถประกาศพาธได้ที่ /แอป
ในรหัสของคุณ แต่คุณเพิ่มเลเยอร์ด้านบน (พร็อกซี) ที่จะทำให้แอปพลิเคชัน FastAPI ของคุณอยู่ภายใต้เส้นทางเช่น /api/v1
.
ในกรณีนี้คือเส้นทางเดิม /แอป
จะให้บริการจริงที่ /api/v1/แอป
.
แม้ว่ารหัสทั้งหมดของคุณจะถูกเขียนโดยสมมติว่ามีเพียง /แอป
.
และพร็อกซีจะ "ลอก" คำนำหน้าเส้นทางทันทีก่อนที่จะส่งคำขอไปยัง Uvicorn ทำให้ใบสมัครของคุณมั่นใจว่ากำลังให้บริการที่ /แอป
เพื่อให้คุณไม่ต้องอัปเดตรหัสทั้งหมดของคุณเพื่อรวมคำนำหน้า /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>
เราได้ดูที่ การกำหนดเส้นทางคำขอแอปพลิเคชัน โมดูลด้วย แต่ดูเหมือนว่าจะเกินความจำเป็นอย่างมากสำหรับกรณีการใช้งานที่เรียบง่ายเช่นนี้
นอกจากนี้ เรายังเพิ่งใช้ โมดูล FastCgi
ร่วมกับไมโครซอฟต์ wfastcgi
ไลบรารีสำหรับ Python แม้ว่าเราจะต้องแปลงแอปพลิเคชัน ASGI เป็นแอปพลิเคชัน WSGI ก่อน (ด้วยความช่วยเหลือของ a2wsgi
). เดอะ โมดูล FastCgi
แยกเส้นทางสำเร็จหลังจากกำหนดค่าคุณสมบัติ เส้นทาง
และ อย่างใดร่าง อนุญาต 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