FastAPI 学习之路(三十八)Static Files

如果使用前后台不分离的开发方式,那么模版文件中使用的静态文件,比如css/js等文件的目录需要在后台进行配置,以便模版渲染是能够正确读取到这些静态文件的。那么我们如何处理呢?

首先安装依赖

pip install aiofiles

我们看下如何使用

        我们定义一个页面,展示一张图片

①:创建两个文件夹static和templates

 

②:分别放置一个home.html和test.png

        其中home.html代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<img src="{
  
  { url_for('static',path='/test.png') }}" style="width: 500px;height: 500px">

</body>
</html>

 ③:我们看下在fastapi中如何使用

from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi import FastAPI, Reque
<think>我们被要求详细解释FastAPI中的mount功能,包括其使用方法、作用以及注意事项。同时,需要参考提供的引用内容,并自然地添加引用标识。 根据引用内容,我们可以总结如下: 1. 挂载(mount)的作用是将一个完整的独立应用程序(可以是静态文件目录、另一个FastAPI应用、Starlette应用或任何ASGI/WSGI应用)添加到主应用的特定路径下,形成一个整合的应用。[^1][^2][^3] 2. 挂载与使用APIRouter不同,因为挂载的应用程序是完全独立的,主应用的OpenAPI文档不会包含挂载应用的内容。[^2][^3] 3. 挂载常用于静态文件服务(如使用StaticFiles)或者将多个独立的FastAPI应用组合起来(每个子应用有自己的文档)。[^2][^3][^4] 4. 挂载的示例:主应用可以挂载一个静态文件服务(StaticFiles)到路径"/static",这样所有以"/static"开头的请求都会由这个静态文件应用处理。[^2][^4]同样,也可以挂载另一个FastAPI子应用,比如主应用挂载一个子应用到"/subapi",那么访问"/subapi"及其子路径的请求都会交给子应用处理。[^3] 下面我们将详细展开: ### 📌 FastAPI 挂载(Mount)详解 #### 1. 什么是挂载? 挂载(Mount)是指将一个独立的WSGI或ASGI应用程序附加到主FastAPI应用的特定路径下。这个被挂载的应用将负责处理所有以该路径开头的请求。挂载的应用与主应用完全独立,包括文档(如OpenAPI/Swagger)也不会相互干扰。[^2][^3] #### 2. 挂载的作用 - **整合多个独立应用**:例如,将多个FastAPI子应用(每个子应用可能由不同团队开发)组合成一个整体。[^1][^3] - **提供静态文件服务**:快速设置静态文件(如图片、CSS、JavaScript)的访问路径,无需编写额外路由。[^2][^4] - **集成第三方应用**:可以挂载任何符合WSGI或ASGI标准的应用,如Dash应用、Flask应用等。 #### 3. 使用方法 ##### 3.1 挂载静态文件 使用`StaticFiles`类来挂载静态文件目录: ```python from fastapi import FastAPI from fastapi.staticfiles import StaticFiles app = FastAPI() # 将静态文件目录static挂载到/app/static路径 app.mount("/static", StaticFiles(directory="static"), name="static") ``` - `directory`:静态文件所在的本地目录。 - `name`:挂载应用的名称(FastAPI内部使用,可选)。 - 访问示例:`http://localhost:8000/static/image.png` 将返回`static/image.png`文件。[^4] ##### 3.2 挂载另一个FastAPI应用 假设有两个独立的FastAPI应用,主应用和子应用: ```python # 主应用 from fastapi import FastAPI app = FastAPI() @app.get("/main") def read_main(): return {"message": "Main app"} # 子应用 subapp = FastAPI() @subapp.get("/sub") def read_sub(): return {"message": "Sub app"} # 将子应用挂载到主应用的"/subapp"路径下 app.mount("/subapp", subapp) ``` - 此时,访问主应用的`/main`路径由主应用处理。 - 访问`/subapp/sub`路径则由子应用处理。[^3] ##### 3.3 挂载其他ASGI/WSGI应用 同样方法也可以挂载Starlette应用或其他ASGI应用: ```python from fastapi import FastAPI from starlette.applications import Starlette app = FastAPI() # 创建一个Starlette应用 starlette_app = Starlette() @starlette_app.route("/star") async def starlette_endpoint(request): return {"message": "Starlette app"} app.mount("/external", starlette_app) ``` #### 4. 注意事项 1. **路径独立性**:挂载的应用处理所有以指定路径开头的请求,因此主应用不会处理这些请求。[^2] 2. **文档隔离**:主应用的OpenAPI文档不会包含挂载应用的路由,挂载的子应用如果有自己的文档(如FastAPI子应用),则可以通过其独立路径访问(如`/subapi/docs`)。[^3] 3. **路径匹配优先级**:当同时存在多个挂载点时,FastAPI会按照挂载的先后顺序进行匹配(从最长的路径前缀开始?实际上,由于挂载是精确到路径前缀的,所以不会冲突,但要注意挂载路径不要重叠,比如先挂载`/static`,再挂载`/static/images`会导致后者被忽略?实际上,挂载是前缀匹配,且按添加顺序匹配,但通常我们确保挂载路径不重叠)。 4. **中间件影响**:挂载的应用可以有自己的中间件,但主应用的中间件不会自动作用于挂载的应用(除非在挂载前添加的全局中间件,因为中间件作用于整个ASGI树)。[^3] 然而,需要注意的是,在主应用上添加的中间件会作用于所有请求(包括挂载的子应用),因为挂载是主应用的一部分。而子应用自己的中间件只作用于子应用的请求。 5. **静态文件服务安全问题**:使用`StaticFiles`时,确保目录路径安全,避免暴露敏感文件。 #### 5. 示例:整合静态文件与子应用 ```python from fastapi import FastAPI from fastapi.staticfiles import StaticFiles app = FastAPI() subapp = FastAPI() # 主应用路由 @app.get("/") def home(): return "Main App" # 子应用路由 @subapp.get("/hello") def hello(): return "Hello from Sub App" # 挂载子应用 app.mount("/sub", subapp) # 挂载静态文件 app.mount("/assets", StaticFiles(directory="assets"), name="assets") ``` #### 6. 工作流程 ```mermaid graph LR A[主FastAPI应用] --> B[挂载点1: /sub] A --> C[挂载点2: /assets] B --> D[子应用处理所有/sub/*请求] C --> E[StaticFiles处理所有/assets/*请求] ``` ### 常见问题 1. **挂载与APIRouter的区别?** APIRouter用于模块化同一个FastAPI应用内的路由,而挂载用于集成完全独立的应用(包括静态文件服务、其他框架应用等)。挂载的应用不共享主应用的OpenAPI文档。[^2][^3] 2. **如何为挂载的子应用添加中间件?** 在子应用上直接添加中间件(如果子应用是FastAPI或Starlette应用): ```python from fastapi.middleware.cors import CORSMiddleware subapp.add_middleware(CORSMiddleware, ...) ``` 3. **静态文件挂载后前端如何访问?** 假设挂载路径为`/static`,文件`logo.png`在`static`目录下,则前端通过`/static/logo.png`访问。[^4] 4. **能否挂载多个静态文件目录?** 可以,挂载到不同路径即可: ```python app.mount("/images", StaticFiles(directory="images"), name="images") app.mount("/docs", StaticFiles(directory="pdfs"), name="pdfs") ``` §§相关问题§§ 1. 如何在挂载的子应用中使用中间件? 2. 挂载静态文件时如何设置缓存控制? 3. 如何挂载一个Flask应用到FastAPI? 4. 挂载的应用能否共享主应用的状态(如数据库连接池)? 5. 如何解决挂载路径冲突问题? </think>### 📌 FastAPI 挂载(Mount)详解 挂载(Mount)是 FastAPI 的核心功能之一,用于将**独立的子应用**集成到主应用中,使其处理特定路径下的所有请求。与 `APIRouter` 不同,挂载的应用完全独立,拥有自己的路由、中间件和文档系统。 --- #### ️ 作用与核心特性 1. **应用整合** 将静态文件服务、其他 FastAPI 应用或任意 ASGI/WSGI 应用(如 Starlette、Flask)挂载到主应用: ```python app.mount("/subapp", subapp) # 子应用处理所有 /subapp/* 请求[^3] ``` 2. **静态文件服务** 快速托管 CSS/JS/图片等静态资源: ```python from fastapi.staticfiles import StaticFiles app.mount("/static", StaticFiles(directory="static"), name="static")[^2][^4] ``` 3. **文档独立性** 挂载的子应用拥有独立的 OpenAPI 文档: - 主应用文档:`http://localhost:8000/docs` - 子应用文档:`http://localhost:8000/subapp/docs`[^3] --- #### 🚀 使用方法详解 ##### 场景1:挂载静态文件 ```python from fastapi import FastAPI from fastapi.staticfiles import StaticFiles app = FastAPI() # 挂载静态资源目录 app.mount("/static", StaticFiles(directory="static_files"), name="static"[^2]) # 前端访问示例:/static/logo.png -> static_files/logo.png ``` ##### 场景2:挂载子应用 ```python # ---------- 主应用 main.py ---------- from fastapi import FastAPI from subapp import subapp # 导入子应用 app = FastAPI() app.mount("/api/v1", subapp) # 挂载到 /api/v1 路径[^3] # ---------- 子应用 subapp.py ---------- from fastapi import APIRouter subapp = APIRouter() @subapp.get("/users") def get_users(): # 实际路径:/api/v1/users return [{"id": 1, "name": "Alice"}] ``` ##### 场景3:挂载第三方应用 ```python from starlette.applications import Starlette from fastapi import FastAPI # 创建 Starlette 应用 starlette_app = Starlette() @starlette_app.route("/external") async def external_endpoint(request): return {"service": "External API"} # 挂载到主应用 app = FastAPI() app.mount("/external", starlette_app) # 处理 /external/* ``` --- #### ️ 注意事项 1. **路径匹配规则** - 挂载路径按**添加顺序匹配**(类似中间件) - 避免路径重叠:`/static` 和 `/static/images` 会冲突[^2] 2. **文档隔离性** - 主应用的 OpenAPI 文档**不会包含**挂载的子应用路由[^3] - 如需统一文档,改用 `APIRouter` 3. **中间件作用域** - 主应用的中间件**会影响**挂载的子应用 - 子应用可单独添加中间件: ```python subapp.add_middleware(CORSMiddleware) # 仅作用于子应用 ``` 4. **静态文件安全** - 禁用目录遍历:`StaticFiles` 默认不允许访问上级目录 - 自定义 404 响应: ```python app.mount("/static", StaticFiles(directory="static", html=True), name="static") ``` --- #### 🔍 工作流程 ```mermaid graph LR A[客户端请求 /subapp/data] --> B[主FastAPI应用] B --> C{路径匹配} C -->|匹配 /subapp| D[挂载的子应用] D --> E[处理 /data 路由] E --> F[返回响应] ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值