ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

FastAPI 挂载 WSGI 应用实战:用 WSGIMiddleware 集成 Flask 与 Django

FastAPI 挂载 WSGI 应用实战:用 WSGIMiddleware 集成 Flask 与 Django FastAPI 挂载 WSGI 应用实战用 WSGIMiddleware 集成 Flask 与 Django【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapiFastAPI 本身是一个 ASGI 框架而 Flask、DjangoWerkzeug 部署模式等传统 Web 应用运行在 WSGI 协议之上。本文基于 FastAPI 官方文档《Including WSGI - Flask, Django, others》docs/ja/docs/advanced/wsgi.md讲解如何使用a2wsgi包的WSGIMiddleware将 WSGI 应用以子应用形式“挂载mount”到 FastAPI 实例下的某个路径前缀并给出完整的可运行示例、请求路由行为与验证结果。读完本文后你可以掌握在同一进程中混合部署 FastAPIASGI与 Flask/DjangoWSGI两种技术栈的具体方案并理解旧的fastapi.middleware.wsgi入口被废弃后如何平滑迁移。场景与原理为什么能在 ASGI 框架中运行 WSGI 应用FastAPI 的子应用挂载机制允许你把一个“完全独立的”应用挂到指定路径下由该子应用处理该路径下的所有请求其余请求仍由顶层 FastAPI 应用处理。这一机制在官方文档的子应用 - 挂载与反向代理后章节中已有说明而 WSGI 挂载是它的直接延伸。从协议层面看ASGI 应用是异步的基于协程WSGI 应用是同步的基于阻塞式调用。a2wsgi提供的WSGIMiddleware本质上是一个 ASGI 中间件它自身实现 ASGI 接口内部在接收请求后把 ASGI 的scope/receive/send三元组翻译为 WSGI 的environ字典和可迭代的响应体再调用被包裹的 WSGI 应用如 Flask 实例最后把 WSGI 响应转换回 ASGI 的http.response.start/http.response.body事件流发回客户端。正因为WSGIMiddleware实现了 ASGI 接口FastAPI 的app.mount()才能把它当作一个普通的 ASGI 子应用挂到路径前缀下。前置条件安装 a2wsgi使用WSGIMiddleware需要在项目中添加a2wsgi依赖例如使用uv$ uv add a2wsgi官方文档明确要求从a2wsgi包导入WSGIMiddleware而不是从 FastAPI 自身导入原因见后文“旧入口为何废弃”。当前仓库的测试依赖中也锁定了该包的版本区间pyproject.toml 的测试依赖组中声明了a2wsgi 1.9.0,2.0.0与flask 3.0.0,4.0.0可作为本文示例的参考版本前提。使用 WSGIMiddleware完整的可运行示例操作分为三步从a2wsgi导入WSGIMiddleware用该中间件包裹 WSGI 应用本例为 Flask通过app.mount()将其挂载到某个路径下。下面是一个完整的端到端示例与仓库中的 docs_src/wsgi/tutorial001_py310.py 一致from a2wsgi import WSGIMiddleware from fastapi import FastAPI from flask import Flask, request from markupsafe import escape flask_app Flask(__name__) flask_app.route(/) def flask_main(): name request.args.get(name, World) return fHello, {escape(name)} from Flask! app FastAPI() app.get(/v2) def read_main(): return {message: Hello World} app.mount(/v1, WSGIMiddleware(flask_app))要点解析flask_app Flask(__name__)创建普通的 Flask 实例其根路由/返回文本并用markupsafe.escape对查询参数做转义避免 XSS。app.mount(/v1, WSGIMiddleware(flask_app))把被中间件包裹的 Flask 应用挂载到/v1前缀下。挂载后所有以/v1开头的请求都会进入 Flask而/v1之前的路径前缀会被剥掉——Flask 的根路由/实际对外暴露为/v1/。未挂载的路径如/v2仍由顶层 FastAPI 处理返回 JSON。启动应用$ uv run fastapi dev旧入口为何废弃fastapi.middleware.wsgi 的现状官方文档特别提示早期推荐从fastapi.middleware.wsgi导入WSGIMiddleware但该入口现已废弃现推荐改用a2wsgi包用法保持不变。只需确保安装了a2wsgi并从a2wsgi正确导入WSGIMiddleware即可。从源码可以直接印证这一“废弃 纯重导出”的实现。fastapi/middleware/wsgi.py 全文仅有一行from starlette.middleware.wsgi import ( WSGIMiddleware as WSGIMiddleware, ) # pragma: no cover # noqa也就是说fastapi.middleware.wsgi如今只是对 Starlette 内置WSGIMiddleware的别名转发且被标记为pragma: no cover测试豁免表明官方已不再维护这条路径上的独立实现。迁移时的注意事项依赖管理上显式声明a2wsgi不要依赖 Starlette 的传递依赖所有from fastapi.middleware.wsgi import WSGIMiddleware改为from a2wsgi import WSGIMiddleware应用行为与用法包裹 WSGI 应用 mount挂载完全不变。验证请求路由的实际行为挂载后请求按路径前缀被切分到两个应用所有/v1/下的请求由Flask处理其余请求由FastAPI处理。分别访问两个端点可以看到对应结果。访问http://localhost:8000/v1/得到 Flask 的纯文本响应Hello, World from Flask!访问http://localhost:8000/v2得到 FastAPI 的 JSON 响应{ message: Hello World }仓库中自带的自动化测试 tests/test_tutorial/test_wsgi/test_tutorial001.py 用TestClient对上述两条路由做了断言可作为验收标准def test_flask(): response client.get(/v1/) assert response.status_code 200, response.text assert response.text Hello, World from Flask! def test_app(): response client.get(/v2) assert response.status_code 200, response.text assert response.json() {message: Hello World}这两个断言同时验证了两件事Flask 子应用的挂载与路由剥离正确/v1/命中 Flask 根路由以及顶层 FastAPI 路由不受挂载影响。小结WSGI 挂载的适用边界适用场景需要在 FastAPI 项目中复用现成的 Flask/Django 视图或遗留模块希望单一进程、单一部署单元同时服务新旧两套 API如/v1走旧 WSGI 栈、/v2走 FastAPI。实现方式a2wsgi的WSGIMiddleware包裹 WSGI 应用 app.mount(路径前缀, 中间件实例)/v1前缀内的请求全部交给 WSGI 应用处理。版本前提按官方文档安装a2wsgi仓库测试锁定a2wsgi 1.9.0,2.0.0避免使用已废弃的fastapi.middleware.wsgi导入路径。注意事项从源码结构看WSGIMiddleware是同步 WSGI 到异步 ASGI 的桥接层被包裹的 WSGI 应用运行在中间件的线程/事件循环调度之下如果原 WSGI 应用本身是长时间阻塞的重载逻辑桥接不会使其变快只解决“能不能在 FastAPI 里跑”的问题性能取舍仍取决于业务负载与部署策略。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进