文章目录
- [1.FastAPI 简介](#1.FastAPI 简介)
- [2.FastAPi 环境安装搭建](#2.FastAPi 环境安装搭建)
-
- [2.2 安装FastApi及其依赖](#2.2 安装FastApi及其依赖)
- [2.3 conda下载安装](#2.3 conda下载安装)
-
- 2.3.1安装
- [2.3.2 首次使用:接受服务条款](#2.3.2 首次使用:接受服务条款)
- [2.3.3 VS Code 中配置 conda](#2.3.3 VS Code 中配置 conda)
- [3. FastAPI 实战](#3. FastAPI 实战)
-
- [3.1 路径参数](#3.1 路径参数)
- [3.2 查询参数](#3.2 查询参数)
- [3.3 路径参数 + 查询参数混合](#3.3 路径参数 + 查询参数混合)
- [3.4 请求体](#3.4 请求体)
- [3.5 请求参数验证(类型注解方式)](#3.5 请求参数验证(类型注解方式))
- [3.6 查询参数 Query 的高级验证](#3.6 查询参数 Query 的高级验证)
- [3.7 路径参数 Path 的高级验证](#3.7 路径参数 Path 的高级验证)
- [3.8 Fied验证方式](#3.8 Fied验证方式)
- [3.9 FastAPI表单数据](#3.9 FastAPI表单数据)
- [3.10 异步处理请求](#3.10 异步处理请求)
- [3.11 异常处理](#3.11 异常处理)
- [3.12 响应模型](#3.12 响应模型)
- 4.文件上传
-
- [4.1 小文件上传](#4.1 小文件上传)
- [4.2 大文件上传](#4.2 大文件上传)
- [4.3 多文件上传](#4.3 多文件上传)
- [4.4 上传文件格式限制](#4.4 上传文件格式限制)
- [5. FastAPIrequest获取请求信息](#5. FastAPIrequest获取请求信息)
1.FastAPI 简介
1.FastAPI 是什么?
FastAPI 是一个现代化、高性能的 Python Web 框架,专用于构建 API。它底层基于 Starlette(异步 Web 框架)和 Pydantic(数据验证库),结合异步编程与 Python 类型提示,在开发效率和运行性能之间实现了很好的平衡。
2.FastAPI 核心优势
🚀 高性能
-
基于异步 I/O 架构,性能表现接近 Node.js 和 Go
-
搭配 Uvicorn(ASGI 服务器)运行,原生支持高并发请求
-
在诸多 Python Web 框架中,性能排名靠前(可引用 TechEmpower 基准测试数据)
📝 类型提示 + 自动数据校验
-
利用 Python 类型提示 + Pydantic 进行请求/响应数据校验,减少手写繁琐的验证逻辑
-
类型提示让代码更具可读性,同时 IDE 可以自动补全和类型检查,提升开发体验
示例代码:
php
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None # 可选字段
@app.post("/items/")
async def create_item(item: Item):
return item
提示:上面的代码会自动验证请求体格式(字段类型、必填/可选等),无需手动解析 JSON。
📚 自动生成 API 文档
-
内置 Swagger UI 和 ReDoc,代码写完即自动生成交互式 API 文档
-
极大降低前后端协作时的文档维护成本
⚡ 异步支持
- 原生支持 async / await 语法,方便编写高并发的 IO 密集型任务(数据库、外部 API 调用等)
3. 为什么选择 FastAPI?
| 维度 | 说明 |
|---|---|
| 开发效率高 | 类型提示 + 自动校验 + 自动文档 → 少写 |
| 性能优异 | 异步架构 + Uvicorn → 高并发场景下表现优秀 |
| 社区活跃 | 生态丰富,文档齐全,第三方扩展多 |
| 上手门槛低 | 熟悉 Python 类型提示即可快速上手 |
2.FastAPi 环境安装搭建
1 准备:创建虚拟环境
虚拟环境用于隔离项目依赖,避免污染全局环境。以下使用 conda 工具:
2.创建虚拟环境:
bash
conda create -n fastapi_env python=3.12.0
3.首次使用 conda 需要接受服务条款 (只需执行一次)
bash
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/msys2
如果没有安装conda参考2.2conda下载安装
4.激活虚拟环境
python
conda activate fastapi_env
5.退出虚拟环境
bash
conda deactivate
常见问题:conda 与项目不在同一盘符
如果 conda 安装在 G 盘,但项目在 F 盘,直接激活可能不成功。请按以下步骤操作:
bash
# 1. 切换到 conda 所在盘符
G:
# 2. 激活虚拟环境
conda activate fastapi_env
# 3. 切换回项目目录
F:
cd F:\配线架\backend
验证是否激活成功
激活后,运行以下命令确认:
javascript
where python
应该显示 G:\miniconda\envs\fastapi_evn\python.exe(或你新的环境路径)。
2.2 安装FastApi及其依赖
在虚拟环境中安装fastapi
bash
pip install "fastapi[standard]"
pip install uvicorn
查看是否安装成功 成功了列表中共有fastapi
bash
pip list
完整示例
python
# main.py
from fastapi import FastAPI
app = FastAPI()
# 根目录
@app.get("/")
async def root():
return {"message": "Hello FastAPI"}
# 加上这段可以启用python main.py 启动服务
if __name__ == '__main__':
import uvicorn # 启动uvicorn服务 可以通过python形式运行
uvicorn.run("main:app", host="127.0.0.1", port=8000,reload=True)
启动命令 (main:文件名,app:fastAPI启动的实例名)
bash
# 开发模式(推荐)- 代码修改后自动重载
uvicorn main:app --reload
# 生产模式 - 不自动重载,性能更好
uvicorn main:app
# FastAPI CLI 方式(需要 fastapi-cli)
fasetapi dev main.py
#通过python运行 需要有运行代码
python main.py
注意uvicorn main:app --reload 表示启动之前,自动更新代码内容
uvicorn main:app 这种启动之后不自动更新
查看 API 文档的说明可以加上:
启动成功后,访问:
bash
# 文档格格式 接口文档
Swagger UI:http://127.0.0.1:8000/docs
ReDoc:http://127.0.0.1:8000/redoc
接口文档

2.3 conda下载安装
2.3.1安装
1.下载安装包
官方下载链接:https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe
- 双击运行安装程序
双击下载的 .exe 文件,启动安装向导。
- 选择安装路径
推荐改为 无空格、无中文 的路径,例如G:\miniconda3,避免后续出现奇怪的问题。 - 安装选项 ⚠️ 重要!
在安装界面中,勾选以下两个选项:
bash
✅ Add Miniconda3 to my PATH environment variable(添加到系统环境变量)
✅ Register Miniconda3 as my default Python(注册为默认Python)
- 完成安装
点击 Install 等待完成,取消勾选"Learn more..."后点击 Finish。 - 验证安装
打开 命令提示符(cmd),输入以下命令:
bash
conda --version
如果显示版本号(如 conda 26.3.2),说明安装成功。
又可能在初次在vscode中进行创建虚拟环境报错如下

遇到的这个问题,根源是新版 conda 要求用户必须手动签署 Anaconda 官方仓库(main, r, msys2)的服务条款(Terms of Service, ToS)。
这是 Anaconda 公司在 2025 年下半年开始强制推行的新政策。因此,-y 参数无法绕过这个首次许可确认的过程,conda 命令会直接报错并停止。
要解决这个问题,你必须按照提示的命令,一次性接受所有三个频道的条款。请在同一个 Anaconda Prompt 终端中,依次、完整地执行以下三条命令
python
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/msys2
之后再去创建虚拟环境就会成功了
2.3.2 首次使用:接受服务条款
尤其在初次在 VS Code 中创建虚拟环境时,可能会遇到如下报错:

问题原因:
新版 conda 要求用户手动签署 Anaconda 官方仓库(main、r、msys2)的服务条款(Terms of Service, ToS)。
这是 Anaconda 公司从 2025 年下半年开始强制推行的新政策,-y 参数无法绕过。
解决方法:
在 Anaconda Prompt 终端中,依次、完整地执行以下三条命令:
bash
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/msys2
执行成功后,重新尝试创建虚拟环境即可。
2.3.3 VS Code 中配置 conda
如果在 VS Code 终端输入 conda --version 报错,按以下步骤配置:
第一步 :先关闭 VS Code 并重启,观察是否解决。
第二步:如无效,按下列步骤手动添加环境变量。
手动添加环境变量
1.按 Win + X → 选择 系统 → 点击 高级系统设置
2.点击 环境变量
3.在 系统变量 或 用户变量 中,找到 Path → 双击编辑
4.点击 新建,添加以下 两个路径:
| 路径 | 说明 |
|---|---|
| G:\miniconda3 | conda 主目录 |
| G:\miniconda3\Scripts | conda 可执行文件目录 |
5.点击 确定 →== 确定== → 确定
6.关闭 VS Code 和所有终端,重新打开
7.测试:打开任意终端(cmd/PowerShell/VS Code),输入 conda --version
注意:如果以上操作后仍无效,请重启电脑,确保环境变量全局生效。
3. FastAPI 实战
3.1 路径参数
路径参数是 URL 路径中的变量部分,FastAPI 会自动将路径参数解析为对应类型的变 量(不会自动变成查询参数)。
例如:http://127.0.0.1:8000/agrs/12/test
php
from fastapi import FastAPI
app=FastAPI()
# 路径参数
@app.get('/agrs/{id}/{name}')
def mian_root(id:int,name:str):
return {"id":id,name:name}
✅ 注意:路径参数是必填的,且类型声明(如 int)会自动进行校验和转换。
3.2 查询参数
查询字符串是键值对的结合,这些键值对位于URL的?之后,以&分割
例如:http://127.0.0.1:8000/query/?page=1&limit=10
php
@app.get('/query')
def page_limit(page: int, limit: int):
return {"page": page, "limit": limit}
✅ 查询参数默认可选,如果未提供则使用默认值 None(除非你设置了默认值)。
3.3 路径参数 + 查询参数混合
例如:http://127.0.0.1:8000/query/12?page=1&limit=10
python
@app.get('/query/{id}')
def page_limit(id: int, page: int, limit: int = 10):
return {"id": id, "page": page, "limit": limit}
💡 limit 设置了默认值 10,可选参数一般放在函数参数后面。
3.4 请求体
适合传递复杂、多字段的数据(如 POST 请求)。
方式一:字典形式(不推荐,无法校验)
php
from fastapi improt FastAPI
app=FastAPI()
@app.post('/users')
def getUsers(user:dict): #字典的形式传递请求体
return user
方式二:Pydantic BaseModel(推荐 ✅)
自动校验数据格式、类型提示、自动生成 API 文档。
php
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
age: int
pwd: str | None = None # 可选字段
sex: str
@app.post('/users')
def create_user(user: User):
return user
✅ FastAPI 会自动将 JSON 请求体映射为 User 对象,并做类型校验。
3.5 请求参数验证(类型注解方式)
使用 typing 模块中的类型注解,增强参数约束。
python
from fastapi import FastAPI
from typing import Union, Optional, List
app = FastAPI()
# Union:多种类型之一
@app.get('/items/{id}')
def get_item(id: Union[str, int] = 110):
return {"id": id}
# Optional:允许为 None
@app.get('/items2/{id}')
def get_item2(id: Optional[int] = None):
return {"id": id}
# 查询参数为列表
@app.get('/items3/')
def get_items(ids: List[int] = [1, 2, 3]):
return {"ids": ids}
📌 说明:
- Union[str, int]:参数可以是字符串或整数
- Optional[int] 等价于 Union[int, None]
- List[int]:查询参数 ids 可以多次传递,例如 /items3/?ids=1&ids=2&ids=3
3.6 查询参数 Query 的高级验证
Query 用于对查询参数添加额外的验证规则(如长度、大小、必填、别名、描述等)。
基础语法
python
from fastapi import FastAPI, Query
from typing import Union, Optional, List
app = FastAPI()
示例1:基本用法
python
@app.get('/query')
def read_query(id: str = Query()): # 👈 必须传递(无默认值)
return {"id": id}
请求:GET /query?id=123 ✅
请求:GET /query ❌(缺少参数)
示例 2:设置默认值
php
@app.get('/query')
def read_query(id: str = Query("123")): # 默认值 123(自动转成字符串 "123")
return {"id": id}
请求:GET /query → {"id": "123"}
示例 3:必填参数(用 ...)
python
@app.get('/query')
def read_query(id: str = Query(...)): # ... 表示必填
return {"id": id}
示例 4:字符串长度限制
python
@app.get('/query')
def read_query(id: str = Query(..., min_length=3, max_length=10)):
return {"id": id}
示例 5:数字大小限制
python
@app.get('/query')
def read_query(age: int = Query(..., gt=0, lt=10)): # 0 < age < 10
return {"age": age}
示例 6:别名(alias)
当查询参数名与 Python 变量名冲突时使用。
python
@app.get('/query')
def read_query(id: int = Query(..., alias='user_id')):
return {"id": id}
示例7:正则表达式
python
@app.get('/query')
def read_query(name: str = Query(..., regex=r'^a\d{2}$')): # 👈 加 r 前缀,避免转义问题
return {"name": name} # 👈 返回正确的变量名
注意:regex 参数在较新版本 FastAPI 中已改为 pattern,建议使用 pattern=r'^a\d{2}$'
示例8:添加描述信息(用于 API 文档)
python
@app.get('/query')
def read_query(id: int = Query(..., description='这是用户ID,必须为正整数')):
return {"id": id}
描述信息会显示在 FastAPI 自动生成的 Swagger 文档中(/docs)。
示例 8:标记为已废弃(deprecated)
python
@app.get('/query')
def read_query(id: int = Query(..., deprecated=True)):
return {"id": id}
在 API 文档中该参数会显示为废弃(但不影响使用)。
完整实战示例
python
from fastapi import FastAPI, Query
app = FastAPI()
@app.get('/items')
def search_items(
q: str = Query(..., min_length=2, max_length=20, description='搜索关键词'),
page: int = Query(1, ge=1, description='页码,从1开始'),
size: int = Query(10, ge=1, le=100, description='每页数量')
):
return {
"query": q,
"page": page,
"size": size
}
请求:GET /items?q=苹果&page=2&size=15
响应:{"query": "苹果", "page": 2, "size": 15}
3.7 路径参数 Path 的高级验证
路径参数应该定义在 URL 路径中,如 /path/{id}。
基础语法
python
from fastapi improt FastAPI,Path
app=FastAPI()
示例 1:必填参数(用 ...)
python
@app.get('/path/{id}')
def read_path(id: str = Path(...)): # ... 表示必填(路径参数本来就是必填的)
return {"id": id}
💡 路径参数默认就是必填 ,不提供会报 404。使用 Path(...) 更多是为了添加验证规则。
请求 : GET /path/123 ✅
请求 : GET /path/ ❌(404)
示例 2:设置默认值(⚠️ 路径参数不能有默认值)
python
# ❌ 错误写法 - 路径参数不能有默认值
@app.get('/path/{id}')
def read_path(id: str = Path("default")):
return {"id": id}
路径参数永远在 URL 中,无法省略,所以不能设置默认值。
示例 3:数字大小限制
python
@app.get('/path/{age}')
def read_path(age: int = Path(..., gt=0, le=150)):
return {"age": age}
请求: GET /path/25 ✅
请求: GET /path/200 ❌(大于150,参数校验失败)
示例 4:字符串长度限制
python
@app.get('/path/{name}')
def read_path(name: str = Path(..., min_length=2, max_length=20)):
return {"name": name}
请求: GET /path/张三 ✅
请求: GET /path/a ❌(长度不足2)
示例 5:别名(alias)- 路径参数不支持
python
python
# ❌ 路径参数不支持 alias,因为变量名直接对应 URL 路径中的名称
@app.get('/path/{user_id}')
def read_path(id: int = Path(..., alias='user_id')): # 这会报错
return {"id": id}
# ✅ 正确做法:变量名直接与路径参数名一致
@app.get('/path/{user_id}')
def read_path(user_id: int = Path(...)):
return {"user_id": user_id}
示例 6:正则表达式验证
python
@app.get('/path/{code}')
def read_path(code: str = Path(..., pattern=r'^[A-Z]{3}\d{3}$')): # 3个大写字母+3个数字
return {"code": code}
请求 : GET /path/ABC123 ✅
请求: GET /path/abc123 ❌(小写字母不符)
示例 7:添加描述信息
python
@app.get('/path/{user_id}')
def read_path(
user_id: int = Path(..., description='用户ID,必须是正整数', ge=1)
):
return {"user_id": user_id}
3.8 Fied验证方式
作为请求体
最常见的用法是将模型声明为路径操作函数的参数
python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.post("/items/")
async def create_item(item: Item):
# FastAPI 自动校验请求体,校验通过后赋值给 item 参数
return item
3.9 FastAPI表单数据
基本应用
python
from fastapi import FastAPI,Form
from pydantic import BaseModel
from typing import Annotated
app=FastAPI()
@app.post('/login')
def login(
username: Annotated[str, Form(...)],
password: Annotated[str, Form(...)]
):
return {"username": username, "password": password}
Annotated 就像给类型提示贴便利贴,可以附加额外信息(如验证规则、依赖等),让代码更清晰
3.10 异步处理请求
基础异步请求
python
@app.get('/user')
async def create_user(username:str=Form(...),pwd:str=Form(...)):
"""
创建用户:数据类型 Form
参数:
username: 用户名 必填,用户名称不能为空
pwd: 密码 必填,密码不能为空
"""
result = await some_function()
return {"username":username,"password":pwd}
3.11 异常处理
python
from fastapi import FastAPI, HTTPException
app=FastAPI()
@app.get("/users/{id}")
async def get_user(id: int):
if id < 0:
raise HTTPException(status_code=400, detail="ID不能为负数")
if id > 100:
raise HTTPException(status_code=404, detail="用户不存在")
return user
3.12 响应模型
python
from fastapi import FastAPI
from pydantic import BaseModel
class UserResponse(BaseModel):
id: int
name: str
# 不返回密码
@app.get("/users/{id}", response_model=UserResponse)
async def get_user(id: int):
return {"id": id, "name": "张三", "password": "hidden"}
4.文件上传
4.1 小文件上传
python
from fastapi import FastAPI,UploadFile,File
app=FastAPI()
@app.post('/UpdateLogo',tags=['文件上传'])
def upload(file: bytes = File(...)):
"""
小文件上传:数据类型 bytes 小于10M
参数:
file: 文件 必填,文件不能为空
"""
# 保存文件 小文件上传名称名称不可重名 并且保存到static文件夹下
with open(f'./static/logo.jpg', 'wb') as buffer:
buffer.write(file)
return {"filename": f"文件上传成功"}
小文件一般用于图片 大文件一般用于视频、logo、头像、图片预览等
4.2 大文件上传
安装 aiofiles
bash
pip install aiofiles
python
from fastapi import FastAPI,UploadFile,File
import aiofiles
app=FastAPI()
@app.post('/bigUpload',tags=['文件上传'])
async def upload(file: UploadFile = File(...)):
"""
大文件上传:数据类型 UploadFile
参数:
file: 文件 必填,文件不能为空
"""
# 保存文件
async with aiofiles.open(f'./static/{file.filename}', 'wb') as buffer:
while chunk := await file.read(1024 * 1024):
await buffer.write(chunk)
# buffer.write(await file.read())
return {"filename": file.filename}
4.3 多文件上传
python
# 多文件上传
from fastapi import FastAPI,Form,UploadFile,File
from typing import List
import aiofiles
import os
app=FastAPI()
@app.post('/uploadFiles', tags=['文件上传'])
async def uploadFiles(files: List[UploadFile] = File(...)):
"""
多文件上传:数据类型 List[UploadFile]
参数:
files: 文件列表(必填)
"""
# 确保上传目录存在
os.makedirs('./static', exist_ok=True)
saved_files = []
# 遍历保存文件
for file in files:
file_path = f'./static/{file.filename}'
# ✅ 使用异步上下文管理器
async with aiofiles.open(file_path, 'wb') as buffer:
# 分块写入大文件
while chunk := await file.read(1024 * 1024): # 每次读取1MB
await buffer.write(chunk) # ✅ 异步写入
saved_files.append(file.filename)
return {
"message": f"成功上传 {len(saved_files)} 个文件",
"filenames": saved_files
}
4.4 上传文件格式限制
python
from fastapi import FastAPI,Form,UploadFile,File
from typing import List
import aiofiles
import os
app=FastAPI()
@app.post('/upload', tags=['文件上传'])
async def upload(file: UploadFile = File(...)):
"""
限制文件上传的格式和大小:数据类型 UploadFile
参数:
file: 文件 必填,文件不能为空
"""
# 确保上传目录存在
os.makedirs('./static', exist_ok=True)
# 获取文件名
filename = file.filename
# 检查文件格式
allowed_extensions = ['.jpg', '.png', '.pdf']
if not any(filename.endswith(ext) for ext in allowed_extensions):
return {"error": "文件格式不正确"}
# 保存文件
file_path = f'./static/{filename}'
async with aiofiles.open(file_path, 'wb') as buffer:
chunk = await file.read(1024*1024)
while chunk:
buffer.write(chunk)
chunk = await file.read(1024*1024)
return {"filename": filename}
5. FastAPIrequest获取请求信息
python
from fastapi import FastAPI,Request
app=FastAPI()
# 获取用户的请求信息
@app.post('/getUserRequest',tags=['获取用户的请求信息'])
async def getRequest(resquest: Request):
"""
获取用户的请求信息
参数:
resquest: 请求对象
"""
return {
"client": resquest.client,
"请求头": resquest.headers,
"cookies": resquest.cookies,
"请求地址": resquest.url,
"请求方法": resquest.method,
"请求参数": resquest.query_params,
}