在“FastAPI系列03:FastAPI路由” 一节中,我们详细分析了在HTTP 请求与Python 函数响应中起到关键作用的路由系统的工作原理和细节。本节,我们讨论在FastAPI中处理HTTP请求的另一个核心功能——挂载(mount),它可以将静态文件目录、另一个 FastAPI 应用、Starlette 应用以及其他 WSGI 或 ASGI 应用挂载到主应用的特定路径下以完成应用整合。
• 允许在主应用下运行独立的应用。
• 不同应用之间可以有独立的路由和中间件。
• 可用于划分功能模块或集成第三方服务。
• 路由:处理具体路径的请求。
• 挂载:将整个应用挂载到特定路径下,路径下的请求交由该应用处理。
可以使用 app.mount() 将另一个 FastAPI 应用挂载到指定路径下。
from fastapi import FastAPI
app = FastAPI()
sub_app = FastAPI()
@sub_app.get("/hello")
async def read_hello():
return {"message": "Hello from sub app"}
# 挂载 sub_app 到 /sub
app.mount("/sub", sub_app)
@app.get("/")
async def read_root():
return {"message": "Welcome to the main app"}
请求示例:
• GET / → { “message”: “Welcome to the main app” }
• GET /sub/hello → { “message”: “Hello from sub app” }
说明:
• app.mount(“/sub”, sub_app):将子应用挂载到 /sub 路径。
• 子应用的路径 /hello 实际上变成了 /sub/hello。
FastAPI 提供了 StaticFiles,用于提供静态文件(如 HTML、CSS、JS、图片等)。
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
app = FastAPI()
# 挂载静态文件到 /static
app.mount("/static", StaticFiles(directory="static"), name="static")
说明:
• directory=“static”:指定本地的 static 目录。
• app.mount():将静态文件映射到 /static 路径。
• 请求 /static/image.png 会尝试从 ./static/image.png 获取文件。
FastAPI 基于 Starlette 构建,因此也支持直接挂载 Starlette 应用。
from fastapi import FastAPI
from starlette.applications import Starlette
from starlette.responses import JSONResponse
app = FastAPI()
# 创建一个 Starlette 应用
starlette_app = Starlette()
@starlette_app.route("/star")
async def star_route(request):
return JSONResponse({"message": "Hello from Starlette app"})
# 挂载到 /starlette
app.mount("/starlette", starlette_app)
示例请求:
• GET /starlette/star → { “message”: “Hello from Starlette app” }
FastAPI 还支持挂载其他 WSGI 和 ASGI 应用,如 Django 和 Flask。
挂载 Django 应用:
from fastapi import FastAPI
from django.core.wsgi import get_wsgi_application
app = FastAPI()
django_app = get_wsgi_application()
app.mount("/django", django_app)
挂载 Flask 应用:
from fastapi import FastAPI
from flask import Flask
flask_app = Flask(__name__)
@flask_app.route("/")
def hello():
return "Hello from Flask!"
app = FastAPI()
app.mount("/flask", flask_app)