FastAPI基础程序、路由、请求与响应
一、FastAPI介绍
FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,专为在 Python 中构建 RESTful API 而设计。使用 Python 3.8+ 并基于标准的 Python 类型提示。建立在 Starlette 和 Pydantic 之上,利用类型提示进行数据处理,并自动生成API文档。于 2018 年 12 月 5 日发布第一版本,以其易用性、速度和稳健性在开发者中间迅速流行起来。支持异步编程,可在生产环境中运行。
FastAPI 特点
- 高性能: 基于Starlette和Pydantic,利用异步(asynchronous)编程,提供出色的性能。
- 自动文档生成: 自动生成交互式API文档,支持Swagger UI和ReDoc,让API的理解和测试更加直观。
- 类型注解支持: 利用Python的类型提示,提供更严格的输入验证和更好的代码提示。
- 异步支持: 支持异步请求处理,使得处理IO密集型任务更加高效。
FastAPI 适用场景
- 构建API后端: 用于构建RESTful API,支持前后端分离的Web应用。
- 微服务架构: 可以作为微服务的后端框架,支持快速开发和部署。
- 数据处理API: 适用于处理数据,接收和返回JSON数据。
- 实时通信: 支持WebSocket,适用于实时通信场景。
为什么选择 FastAPI?
- Pythonic: 使用Python的自然语法和类型提示,降低学习曲线。
- 性能优越: 利用异步编程和底层的Starlette框架,提供卓越的性能。
- 文档友好: 自动生成交互式文档,减少文档维护的工作量。
- 生态系统: 基于Python生态系统,可以方便地集成各种库和工具。
二、FastAPI 异步支持
FastAPI 的异步(asynchronous)特性是其高性能和高并发处理能力的核心之一。要理解 FastAPI 的异步,可以从以下几个方面入手:
2.1.什么是异步?
async / await 语法来实现异步:import asyncio async def fetch_data(): print("开始获取数据...") await asyncio.sleep(2) # 模拟一个耗时的 I/O 操作 print("数据获取完成!") return {"data": "some data"}
2.2.FastAPI 如何支持异步?
async def,FastAPI 会自动识别并以异步方式运行它。同步 vs 异步路由示例:
from fastapi import FastAPI app = FastAPI() # 同步路由(阻塞) @app.get("/sync") def sync_route(): time.sleep(2) # 阻塞整个线程 return {"message": "同步完成"} # 异步路由(非阻塞) @app.get("/async") async def async_route(): await asyncio.sleep(2) # 不阻塞事件循环 return {"message": "异步完成"}
2.3. 为什么异步能提高性能?
- 在传统同步 Web 服务器(如 Flask + WSGI)中,每个请求通常由一个线程处理。如果该请求需要等待 I/O(比如查数据库),线程就“卡住”了,不能处理其他请求。
- 而在异步模型(ASGI)中,一个事件循环可以同时管理成百上千个“协程”(coroutines)。当某个协程在等待 I/O 时,事件循环立即切换到其他协程继续工作。
- 这使得 FastAPI 在高并发 I/O 密集型场景下(如 API 网关、微服务通信)性能远超传统同步框架。
同步:执行需要10s

@app.get("/sync") def func_sync(): start = time.time() for in range(10): time.slep(1) end = time.time() return {"time": f'{end-start:.2f}s'}
异步:执行只需要1s:

@app.get("/async") async def func_async(): start = time.time() task = [asyncio.slep(1) for in range(10)] awit asyncio.gather(*task) end = time.time() return {"time": f'{end-start:.2f}s'}
2.4.什么时候用异步?
- 调用外部 API(用
httpx.AsyncClient) - 访问数据库(用
asyncpg,databases,SQLAlchemy 1.4+ async) - 文件读写(用
aiofiles) - 任何 I/O 密集型任务
- CPU 密集型任务(如图像处理、复杂计算)——此时异步无帮助,反而可能因上下文切换降低性能。这类任务应交给线程池或进程池(可用
loop.run_in_executor)。
2.5.混合使用同步与异步
- 如果是
def(同步),FastAPI 会在线程池中运行它,避免阻塞事件循环。 - 如果是
async def(异步),则直接在事件循环中运行。
三、FastAPI 安装
使用 FastAPI 框架搭建 Web 服务
3.1.创建项目
- 虚拟环境
conda create -n web_api_dev python=3.13
安装 FastAPI 很简单,这里我们使用 pip 命令来安装。
pip install fastapi
也可以使用以下命令直接安装 FastAPI 及所有可选依赖(推荐):
pip install "fastapi[all]"
这会安装:
fastapi- FastAPI 框架uvicorn[standard]- ASGI 服务器python-multipart- 表单和文件上传支持jinja2- 模板引擎python-jose- JWT 令牌支持passlib- 密码哈希bcrypt- 密码加密python-dotenv- 环境变量支持
这样我们就安装完成了。
- FastAPI框架

3.2.运行项目
3.2.1.run 项目
- 使用pycharm选择fastapi框架创建项目后,会默认创建main文件,生成示例代码如下,只需要在pycharm中点击运行按钮,即可运行项目

- 运行后如下:

- 浏览器访问跟路径:

- 访问交互式文档:http://127.0.0.1:8000/docs

这时候是属于热部署,在启动后你直接修改代码,也可以看到内容:这里在helloword后面添加123,在浏览器访问
- 先添加内容

- 浏览器访问:

3.2.2.uvicorn
运行项目:
uvicorn main:app --reload
注意:
- --reload:更改代码后自动重启服务器
- main:指的需要运行的py文件名
- app:指的是FastAPI实例对象名称

3.3.访问交互式文档
FastAPI 提供了内置的交互式 API 文档,使开发者能够轻松了解和测试 API 的各个端点。
这个文档是自动生成的,基于 OpenAPI 规范,支持 Swagger UI 和 ReDoc 两种交互式界面。
通过 FastAPI 的交互式 API 文档,开发者能够更轻松地理解和使用 API,提高开发效率
在运行 FastAPI 应用时,Uvicorn 同时启动了交互式 API 文档服务。
3.3.1. Swagger UI 风格
默认情况下,你可以通过访问 http://127.0.0.1:8000/docs 来打开 Swagger UI 风格的文档:
http://127.0.0.1:8000/docs

Swagger UI 提供了一个直观的用户界面,用于浏览 API 的各个端点、查看请求和响应的结构,并支持直接在文档中进行 API 请求测试。通过 Swagger UI,你可以轻松理解每个路由操作的输入参数、输出格式和请求示例。
3.3.2.ReDoc 风格的文档
通过 http://127.0.0.1:8000/redoc 来打开 ReDoc 风格的文档。

ReDoc 是另一种交互式文档界面,具有清晰简洁的外观。它使得开发者能够以可读性强的方式查看 API 的描述、请求和响应。与 Swagger UI 不同,ReDoc 的设计强调文档的可视化和用户体验。
四、FastAPI 基本路由
路由就是 URL 地址和处理函数之间的映射关系,它决定了当用户访问某个特定网址时,服务器应该执行哪段代码来返回结果。
4.1.路由说明
FastAPI 的路由定义基于 Python 的装饰器模式

from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"message": "Hello World"}
代码说明:
FastAPI():创建 FastAPI 应用实例。@app.get("/"):使用@app.get装饰器创建一个处理根路径的路由。async def root():路由处理函数,返回一个包含 {"message": "hello world"} 的字典。
同一段接口逻辑,根据参数不同返回不同的数据

说明:
- 参数就是客户端发送请求时附带的额外信息和指令
- 参数的作用是让同一个接口能根据不同的输入,返回不同的输出,实现动态交互
4.2.参数分类
在请求中参数分为:
- 路径参数
- 查询参数
- 请求体

4.2.1.路径参数
路径参数说明
- 位置:URL 路径的一部分 /book/{id}
- 作用:指向唯一的、特定的资源
- 方法:GET

输出:

路径参数 - 类型注解 Path
FastAPI 允许为参数声明额外的信息和校验,导入 FastAPI 的 Path 函数,Path 是一个用于为 路径参数(path parameters) 声明额外信息、元数据和校验规则的函数。它属于 FastAPI 的“依赖项”系统的一部分,与 Query、Body、Header 等类似,但专门用于处理 URL 路径中的变量。
Path 支持的常用参数:
| 参数 | 说明 |
|---|---|
default |
默认值(路径参数不能有默认值,所以通常用 ...) |
alias |
OpenAPI 中显示的别名(较少用于路径参数) |
title |
参数标题(用于文档) |
description |
参数描述 |
gt, ge |
大于、大于等于(数值) |
lt, le |
小于、小于等于(数值) |
min_length, max_length |
字符串/列表最小/最大长度 |
regex(旧) / pattern(新) |
正则表达式匹配 |
deprecated |
标记为废弃 |
案例:添加两个方法,实现路由参数
from fastapi import FastAPI, Path app = FastAPI() @app.get("/book/{id}") async def get_book(id: int = Path(..., ge=1, le=100, description="书籍id, 取值在1-100之间")): return {"id": id, "title": f"这是第{id}本书"} @app.get("/author/{book_author}") async def get_author_name(book_author: str = Path(min_length=2, max_length=20, description="书籍作者名")): return {"msg": f"这是{book_author}作者"}
打开接口文档:

4.2.2.查询参数
声明的参数不是路径参数时,路径操作函数会把该参数自动解释为查询参数(就是URL参数),
查询参数:
- 位置:URL? 之后k1=v1&k2=v2
- 作用:对资源集合进行过滤、排序、分页等操作
- 方法:GET
示例:

调用执行:

查询参数 - 类型注解 Query
FastAPI Query() 函数完整参数详解表,如下:
导入 FastAPI 的 Query 函数,使用案例:
from fastapi import FastAPI, Query app = FastAPI() @app.get("/new/new_list") async def get_new_list( skip: int = Query(0, ge=1, le=100, description="跳过的记录数"), limit: int = Query(10, ge=1, le=100, description="返回的记录数") ): return {"skip": skip, "limit": limit}
执行调用:

4.2.3.请求体
在HTP协议中,一个完整的请求由三部分组成:
① 请求行:包含方法、URL、协议版本
② 请求头:元数据信息(Content-Type、Authorization等)
③ 请求体:实际要发送的数据内容
请求体:
- 位置:HTP 请求的消息体(body)中;
- 作用:创建、更新资源携带大量数据,如:JSON;
- 方法:POST、PUT 等;
案例:
# 1.定义类型:需要继承BaseModel class User(BaseModel): username: str password: str # 2.添加类型注解 @app.post("/register") async def register(user: User): """ 定义注册接口 :param user: :return: """ return user
输出:

请求体参数 - 类型注解 Field
Field 是 Pydantic(特别是 v2 版本)中用于定义模型字段元数据和验证规则的核心函数。它允许你为 Pydantic 模型(BaseModel)中的每个字段添加默认值、验证约束、文档说明、别名、示例等信息。
Field 常用参数(与 FastAPI 的 Query/Body 共享)
| 参数 | 说明 | 示例 |
|---|---|---|
default |
默认值 | Field("guest") |
default_factory |
动态默认值(如 list) |
Field(default_factory=list) |
alias |
外部使用的字段名(如 JSON key) | Field(alias="user_id") |
description |
字段描述(用于文档) | Field(description="用户邮箱") |
gt, ge, lt, le |
数值范围 | Field(ge=1, le=100) |
min_length, max_length |
字符串/列表长度 | Field(min_length=5) |
pattern |
正则匹配(字符串) | Field(pattern=r"^\d{3}-\d{2}$") |
examples / openapi_examples |
示例值(OpenAPI) | Field(examples=["test@example.com"]) |
deprecated |
标记弃用 | Field(deprecated=True) |
json_schema_extra |
扩展 JSON Schema | Field(json_schema_extra={"unit": "years"}) |
from pydantic import BaseModel, Field # 1.定义类型:需要继承BaseModel class User(BaseModel): username: str = Field(min_length=8, max_length=20, description="用户名, 8~20个字符") password: str = Field(min_length=6, max_length=15, description="密码,6~15位")
五、FastAPI 请求和响应
在 FastAPI 中,请求(Request)和响应(Response)是与客户端交互的核心。FastAPI 提供了强大的工具来解析请求数据,并根据需要生成规范的响应。

HTTP 的请求-响应模型通常由以下几个步骤组成:
-
建立连接:客户端与服务器之间建立连接。在传统的 HTTP 中,这是基于 TCP/IP 协议的。最近的 HTTP/2 和 HTTP/3 则使用了更先进的传输层协议,例如基于 TCP 的二进制协议(HTTP/2)或基于 UDP 的 QUIC 协议(HTTP/3)。
-
发送请求:客户端向服务器发送请求,请求中包含要访问的资源的 URL、请求方法(GET、POST、PUT、DELETE 等)、请求头(例如,Accept、User-Agent)以及可选的请求体(对于 POST 或 PUT 请求)。
-
处理请求:服务器接收到请求后,根据请求中的信息找到相应的资源,执行相应的处理操作。这可能涉及从数据库中检索数据、生成动态内容或者简单地返回静态文件。
-
发送响应:服务器将处理后的结果封装在响应中,并将其发送回客户端。响应包含状态码(用于指示请求的成功或失败)、响应头(例如,Content-Type、Content-Length)以及可选的响应体(例如,HTML 页面、图像数据)。
-
关闭连接:在完成请求-响应周期后,客户端和服务器之间的连接可以被关闭,除非使用了持久连接(如 HTTP/1.1 中的 keep-alive)。
5.1.响应类型
默认情况下,FastAPI 会自动将路径操作函数返回的 Python 对象(字典、列表、Pydantic 模型等),经由 jsonable_ncoder 转换为JSON 兼容格式,并包装为 JSONResponse 返回。这省去了手动序列化的步骤,让开发者能更专注于业务逻辑。如果需要返回非 JSON 数据(如 HTML、文件流),FastAPI 提供了丰富的响应类型来返回不同数据
@app.get("/") async def root(): return {"message": "Hello World"}
fastapi响应类型说明:
| 响应类型 | 用途 | 示例 |
|---|---|---|
JSONResponse |
默认响应,返回JSON数据 | return {"key": "value"} |
HTMLResponse |
返回HTML内容 | return HTMLResponse(html_content) |
PlainTextResponse |
返回纯文本 | return PlainTextResponse("text") |
FileResponse |
返回文件下载 | return FileResponse(path) |
StreamingResponse |
流式响应 | 生成器函数返回数据 |
RedirectResponse |
重定向 | return RedirectResponse(url) |
5.2.响应类型设置方式
- 方式一:装饰器中指定响应类,场景:固定返回类型(HTML、纯文本等)
from fastapi import FastAPI from starlette.responses import HTMLResponse app = FastAPI() @app.get("/html", response_class=HTMLResponse) async def get_html(): html = """ <html> <body> <h1>这是HTML页面</h1> </body> </html> """ return html
- 方式二:返回响应对象,场景:文件下载、图片、流式响应
from fastapi import FastAPI from starlette.responses import FileResponse app = FastAPI() @app.get("/file") async def get_file(): """ 返回文件 :return: """ file_path = "./static/fI5ntUNpK.png" return FileResponse(file_path)
FileRsponse 是 FastAPI 提供的专门用于高效返回文件内容(如图片、PDF、Excel、音视频等)的响应类。它能够智能处理文件路径、媒体类型推断、范围请求和缓存头部,是服务静态文件的推荐方式。
5.3.自定义响应数据格式
response_model 是路径操作装饰器(如 @app.get或 @app.post)的关键参数,它通过一个 Pydantic 模型来严格定义和约束 API 端点的输出格式。这一机制在提供自动数据验证和序列化的同时,更是保障数据安全性的第一道防线。
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class News(BaseModel): """ 新闻模型 """ id: int title: str content: str @app.get("/news/{id}", response_model=News) async def get_news(id: int): """ 获取新闻 :param id: :return: """ return {"id": id, "title": f"这是第{id}条新闻", "content": f"这是第{id}条新闻的内容"}

五、异常处理
对于客户端引发的错误(4x,如资源未找到、认证失败),应使用 fastapi.HTPException 来中断正常处理流程,并返回标准错误响应。
from fastapi import FastAPI, HTTPException from pydantic import BaseModel app = FastAPI() class News(BaseModel): """ 新闻模型 """ id: int title: str content: str @app.get("/news/{id}", response_model=News) async def get_news(id: int): """ 获取新闻 :param id: :return: """ ids = [1, 2, 3, 4, 5] if id not in ids: # 404, 返回错误信息 raise HTTPException(status_code=404, detail=f"当前{id}新闻不存在") return {"id": id, "title": f"这是第{id}条新闻", "content": f"这是第{id}条新闻的内容"}



浙公网安备 33010602011771号