FastAPI 是一个基于 Python 3.7+ 并使用 类型注解(Type Hints) 的现代、高性能 Web API 框架。其核心设计理念是使开发者能够以最少的代码构建出高效、可维护、具备自动化文档能力的 API 服务。
FastAPI 由 Sebastián Ramírez 创建,依托 Python 的 类型注解 (Python Type Hint)、Pydantic (数据验证库)和 Starlette(异步 Web 框架)构建,具有极高的开发效率和性能表现。
创建FastAPI项目

Interpreter type(解释器类型) 指的是:
你希望 PyCharm 使用哪一种 Python 环境来运行这个 FastAPI 项目。
- Project venv(项目虚拟环境)------最常用、最推荐
含义:
-
PyCharm 会在你的项目目录下自动创建一个
.venv虚拟环境 -
这个环境独立于你的系统 Python
-
所有依赖(fastapi、uvicorn、langchain 等)都只装在这个项目里,不会影响其它项目
- Base conda(使用 Conda 环境)
含义:
-
如果你安装了 Anaconda/Miniconda
-
PyCharm 允许你使用 conda 的虚拟环境作为解释器
适合人群:
-
深度学习用户(因为 conda 更方便安装 numpy/pytorch 等科学库)
-
已经习惯管理 conda 环境的用户
如果你没用 conda,不要选这个。
- Custom environment(自定义解释器)
含义:
-
允许你手动选择某一个 python.exe
-
可以指向:
-
系统 Python
-
自己已经创建的外部 venv
-
一个共享环境
-
服务器远程 Python
-
适合场景:
-
你已经提前创建好虚拟环境
-
或你想多个项目共用一个 Python 环境
命令行启动API项目
直接点启动(会是热加载不需要手动设置)

使用命令行

bash
uvicorn main:app --reload
用 Uvicorn 启动一个 FastAPI 应用,并开启自动热重载功能。
需要注意的是
main:app = 在 main.py 文件中,找到一个叫 app 的 FastAPI 对象

因加了 --reload,Uvicorn 会自动监听代码变动,只要你保存 main.py,它会自动重启服务。
交互式文档
bash
127.0.0.1:8000/docs
这里可以看到所有接口,并且直接测试,非常方便。

路由
路由(Route)= 请求路径(URL) 和 后端处理函数之间的映射关系。
简单讲:
用户访问哪个 URL
→ 后端应该执行哪个函数
→ 返回什么内容
这个"地址到函数"的连接,就是路由。
如何定义路由?

装饰器(Decorator)
就是以 @ 开头的这一行:
python
@app.get("/")
装饰器的作用:给下面的函数加上"额外的行为"
在 FastAPI 中,这种额外行为就是:
-
把这个函数注册为一个 API 接口
-
指定接口的 URL 路径
-
指定接口的请求方法(GET / POST / PUT / DELETE)
说白了:
装饰器 = "这个函数被 FastAPI 接管,变成一个 API 接口"
参数


路径参数
路径参数(Path Parameter)就是 URL 路径的一部分,用于表示某个特定资源。

例如:
bash
/book/1
/book/666
/book/9527
这里 /book/xxxx 的 xxxx 就是路径参数,用来代表某一本书的 ID。
在 FastAPI 中,你用 {变量名} 的方式声明路径参数:
bash
/book/{id}
需要注意的是:
路径里写什么变量名,函数参数就必须写同名变量。
python
@app.get("/book/{id}")
async def get_book(id: int):
...
路径里是 {id},你就必须写 id。
如果你改路径:
python
@app.get("/book/{book_id}")
async def get_book(book_id: int):
...
路径参数的特点
| 特点 | 说明 |
|---|---|
| 必填 | URL 必须提供该值 |
| 不需要问号 | 和 Query 参数不同,不用像 ?id=1 |
| 类型自动转换 | 写了 id: int 就会自动验证 |
| 自动文档 | Swagger 会自动显示参数 |
路路径参数 - 类型注解Path
FastAPI 的路径参数(Path Parameter)使用 Path() 进行类型注解与校验。
1. 什么是 Path()?
Path() 是 FastAPI 提供的一个用于:
-
设置路径参数的默认值
-
添加校验规则
-
编写说明(description)
-
添加范围限制
的特殊函数。
它用于 路径参数(Path Parameter)增强版校验。
类似于:
-
Query()用于 Query 参数 -
Body()用于 Body 参数
而 Path() 专门给 路径参数 用。
2. Path() 支持的常用参数
数字相关
| 参数 | 描述 |
|---|---|
| gt | 必须大于 |
| ge | 大于等于 |
| lt | 小于 |
| le | 小于等于 |
字符串相关
| 参数 | 描述 |
|---|---|
| min_length | 最少长度 |
| max_length | 最大长度 |
| regex | 正则表达式 |
文档相关
| 参数 | 描述 |
|---|---|
| description | 文档描述 |
| example | Swagger 显示示例值 |
| title | 字段标题 |
3. 数值范围校验 id 只能在 1 ~ 100 之间
python
from fastapi import FastAPI, Path
@app.get("/book/{id}")
async def get_book(
id: int = Path(..., gt=0, lt=101, description="书籍id,取值范围1-100")
):
return {"id": id, "title": f"这是第{id}本书"}
4. 字符串长度校验字符串最少 2 个字符,最多10个字符
python
@app.get("/author/{name}")
async def get_name(
name: str = Path(..., min_length=2, max_length=10)
):
return {"msg": f"这是{name}的信息"}
查询参数

查询参数是 URL 中 ? 之后的 key=value 参数。
例如:
bash
/news/news_list?skip=0&limit=10
这些:
-
skip=0 -
limit=10
就是 查询参数。
它们不是路径的一部分(不像 /book/{id}),而是用于筛选、分页、排序等功能。
示例:
python
@app.get("/news/news_list")
async def get_news_list(
skip: int = Query(default=0, description="跳过的记录数", lt=100),
limit: int = Query(default=10, description="返回的记录数")
):
return {"skip": skip, "limit": limit}
查询参数的类型注解Query
python
skip: int = Query(...)
limit: int = Query(...)
-
Query()是 FastAPI 提供的一个"参数声明工具":-
声明这是 Query 参数 (出现在
?后面) -
可以设置默认值、校验规则、描述信息等
-
Query 的常用参数(重点记这些就够用)
1. default(默认值 / 是否必填)
python
# 有默认值,str 不传也可以
q: str | None = Query(default="hello")
# 必填(没有默认值,使用 ...)表示参数必填
q: str = Query(default=...)
-
default=...或直接写...表示:必填 -
有默认值 → 可选参数
str | None 的含义
这是 Python 的「联合类型」写法:
bash
A | B → 表示可以是 A 类型,也可以是 B 类型
表示:
q 可以是字符串 (str),也允许为空 (None)
2. 数值范围校验(gt / ge / lt / le)
只对数值类型有用:
python
age: int = Query(..., ge=18, le=60)
含义:
-
ge=18:age ≥ 18 -
le=60:age ≤ 60
其他几种:
| 参数 | 含义 |
|---|---|
gt |
> 某值 |
ge |
≥ 某值 |
lt |
< 某值 |
le |
≤ 某值 |
3. 字符串长度与正则校验
python
keyword: str = Query(
default="",
min_length=2,
max_length=20,
regex="^[a-zA-Z0-9]+$",
description="搜索关键字,只能是字母或数字"
)
-
min_length:最小长度 -
max_length:最大长度 -
regex:必须匹配该正则表达式
4. 文档相关(title / description / example)
python
q: str | None = Query(
default=None,
title="搜索关键字",
description="用于模糊搜索的关键词",
example="fastapi"
)
-
title:字段标题(Swagger 中显示) -
description:字段说明 -
example:示例值(Swagger 参数输入框里的 Example)
这些完全是 为了生成更专业的接口文档。
5. alias:别名(前端参数名与后端变量名不一致时)
有时 URL 传的是 user_id,但你想在代码里叫 uid:
python
uid: int = Query(..., alias="user_id")
适用于:前后端约定的参数名已经定死,但你又想在后端用更合适的变量名。
请求体参数

请求体(body) = HTTP 请求中真正要发送的内容
它不是 URL,也不是 Query 参数,而是被放在 HTTP 消息体中。

请求体参数的类型注解Filed

Field 是什么?
在 Pydantic 模型(BaseModel) 中,Field() 用来:
-
为字段添加描述(description)
-
添加默认值
-
添加示例值
-
添加校验规则(长度、范围)
-
添加别名(alias)
-
控制字段是否必填
-
控制是否出现在 docs 中
它的作用和 Query/Path 类似,但 Field 专门用于 Pydantic 模型字段。
python
class User(BaseModel):
username: str = Field(default="张三", min_length=2, max_length=10, description="用户名,长度要求2-10个字")
password: str = Field(min_length=3, max_length=20)
响应类型
FastAPI 的默认行为:
只要你 return 一个 Python 对象(dict、list、Pydantic Model),FastAPI 会自动转成 JSON 返回。

路由返回什么,就决定了响应类型:
| 你 return 的内容 | FastAPI 默认行为 |
|---|---|
| dict / list / model | 自动 JSON |
| HTMLResponse | 返回 HTML |
| PlainTextResponse | 返回 text/plain |
| FileResponse | 返回文件下载 |
| StreamingResponse | 流式输出 |
| RedirectResponse | 302 重定向 |
只有当你需要"非 JSON 数据"时,才需要使用特殊响应。
两种设置响应类型的方式
FastAPI 允许两种方式指定返回内容的类型:
方式 1:在装饰器里指定 response_class
适用于:固定返回格式(HTML、纯文本、XML 等)
示例:
python
from fastapi.responses import HTMLResponse
@app.get("/html", response_class=HTMLResponse)
async def get_html():
return "<h1>这是标题</h1>"
作用:
-
FastAPI 会自动把 return 的内容当成 HTML
-
自动设置
Content-Type: text/html -
浏览器渲染为 HTML,而不是 JSON 字符串
非常适合:
-
返回静态 HTML 页面
-
返回纯文本
-
返回 XML
-
固定格式数据
方式 2:直接返回响应对象(Response 对象)
适用于:根据情况返回不同格式的内容,例如文件、图片、流式响应。
例如文件下载:
python
from fastapi.responses import FileResponse
@app.get("/file")
async def get_file():
file_path = "./files/1.jpeg"
return FileResponse(file_path)
作用:
-
返回一个文件(下载或显示)
-
自动设置 MIME-Type(图片、视频、PDF)
-
自动处理二进制数据
-
可以应对不同场景:图片、文件、视频、流式输出
适用于:
-
文件下载(PDF、TXT、ZIP)
-
图片展示
-
视频流
-
ChatGPT 类流式文本输出(StreamingResponse)
-
自定义响应(自己写 header)
自定义响应格式

response_model 是什么?
response_model 是 FastAPI 路由装饰器的参数:
python
@app.get("/xxx", response_model=模型类)
它的作用是:
用 Pydantic 模型来严格定义 API 返回的数据格式,并自动执行数据验证与过滤。
也就是说:
-
你返回什么由你决定(return xxx)
-
但最终返回给前端的数据会按照 response_model 进行格式化、验证、过滤
这是 FastAPI 的安全保证机制之一。
python
@app.get("/news/{id}", response_model=News)
async def get_news(id: int):
return {
"id": id,
"title": f"这是第{id}本书",
"content": "这是一本好书"
}
关键点:
-
response_model=News告诉 FastAPI:最终返回给前端的格式必须是 News(少一个字段都不行)
-
即使你 return 的是 dict
FastAPI 也会自动把它转换成 News 模型 → 最终 JSON
异常处理
场景说明
"对于客户端引发的错误(4xx,如资源未找到、认证失败),应使用
fastapi.HTTPException来中断正常处理流程,并返回标准错误响应。"
也就是:
当用户的请求不合法 时(比如访问了不存在的 id),你应该主动抛出 HTTPException,而不是让程序莫名其妙报错或返回 500。

引入 HTTPException
python
from fastapi import HTTPException
这是 FastAPI 提供的一个专门用于返回 HTTP 错误的异常类。
抛出 HTTPException
python
raise HTTPException(status_code=404, detail="当前id不存在")
含义:
-
status_code=404告诉客户端:HTTP 状态码是 404 Not Found(资源不存在)
-
detail="当前id不存在"返回给前端的具体错误信息,会出现在响应 JSON 里:
bash{ "detail": "当前id不存在" }抛出后,这个函数会立即终止 ,不会再往下执行
return {"id": id}。
什么时候用 HTTPException?
典型 4xx 场景:
-
404:资源不存在(id 不存在、路由未找到)
-
400:参数错误、请求格式不合法
-
401:未认证(缺少 token)
-
403:已登录但无权限
-
422:自动校验失败(FastAPI 自己抛)