基于FastAPI的AI智能体Web系统构建(一)
·
目录
一.FastAPI介绍
FastAPI 是目前 Python ASGI 原生异步框架里使用量、社区生态、下载量最高的主流框架
- 底层基于轻量 ASGI 框架 Starlette,原生 ASGI、默认 async/await,主打高性能 API 开发、类型校验、自动 OpenAPI 文档、适配 AI / 模型部署场景,社区活跃度极高、企业应用非常广泛(大模型后端、微服务、流式接口)
- 其他重要 ASGI 异步框架
- Quart:语法高度兼容 Flask 的纯 ASGI 异步微框架,适合 Flask 老项目迁移全异步
- Starlette:底层轻量 ASGI 基础框架(FastAPI 的基座),适合自建轻量异步服务
- Litestar / Sanic / BlackSheep:高性能备选 ASGI 异步框架,各有侧重但整体普及度不及 FastAPI
- Django(ASGI 模式):属于混合架构(非从头原生 ASGI),不是纯异步框架
- ASGI 服务器≠框架:Uvicorn/Hypercorn/Daphne 是 ASGI 服务器,不是开发框架,不要混淆
- 一句话总结:做 API/AI 后端首选 FastAPI,是当下最主流的原生 ASGI 异步 Web 框架
flask 和 Django 现在支持异步了吗?
Flask
- ✅ 有部分异步支持(从 Flask 2.0 版本开始):可以编写
async def异步视图、错误处理器、请求钩子(before_request/after_request 等),需要安装flask[async],用 ASGI 服务器(如 Uvicorn/Hypercorn)运行才能真正发挥异步价值Flask - ❗ 不是原生全栈异步框架:底层基础架构最初是 WSGI 同步模型,并非从头到尾 asyncio 架构;默认 WSGI 运行时无法实现真正协程并发。如需完整异步体验,官方生态可参考 Quart(语法和 Flask 高度兼容的纯 ASGI 异步框架)
Django
- ✅ 支持异步(从 Django 3.1 开始引入异步视图、ASGI 部署能力,后续版本持续完善)Django
- 可写
async def异步视图、中间件、信号、缓存、ORM 异步接口,支持 ASGI 部署(Uvicorn/Daphne)实现全异步请求栈 - 提供
sync_to_async/async_to_sync工具做同步 / 异步代码适配,逐步完善异步 ORM、表单、模板等组件(新版持续完善中) - WSGI 模式也能跑异步视图,但性能不佳,必须 ASGI 部署才能获得完整异步收益Django
- 可写
- ❗ 不是一开始就是纯异步架构:还有部分老组件是同步实现,存在异步安全限制,不能直接在异步上下文随意调用旧同步接口,会报
SynchronousOnlyOperation错误,需要适配处理Django
总结
- 两者都支持 async/await 异步写法和 ASGI 部署,但都不属于原生从头设计的纯异步框架
- Flask:异步视图可用,但整体架构仍以 WSGI 同步为基础,异步能力有限
- Django:具备成熟 ASGI + 异步视图 / ORM 能力,但仍有历史同步组件需要适配
- 追求极致全栈异步开发:FastAPI、Quart 这类原生 ASGI 框架会更合适
FastAPI 是一个现代、高性能的 Python Web 框架,用于构建 API 。 它基于 Starlette (异步 Web 框架)和 Pydantic (数据验证 库),结合了异步编程和类型提示,兼顾开发效率与运行性能。
文档 : https://fastapi.tiangolo.com
源码 : https://github.com/tiangolo/fastapi
FastAPI 的核心优势
高性能:
FastAPI 基于异步 I/O ,性能接近 Node.js 和 Go 。 使用 Uvicorn ( ASGI 服务器),支持高并发请求。
性能对比(基于 TechEmpower 等基准测试,简化为每秒请求 数):
FastAPI : ~3000 请求 / 秒(异步,轻量)
Flask : ~1000 请求 / 秒(同步,受 WSGI 限制)
Django : ~800 请求 / 秒(同步, ORM 和中间件开销较大)
类型提示提升开发效率:
FastAPI 使用 Python 类型提示(通过 Pydantic )进行数据验证,减少手动校验代码。
类型提示使代码更易读, IDE (如 VSCode )提供自动补全和错误提示。
示例:定义一个带类型提示的 API 端点:
提示上述代码自动验证请求体中的 name (字符串)、 price (浮点数)和 is_offer (布尔值,可选),无需手动解析 JSON 。
自动生成 API 文档 :
FastAPI 内置 Swagger UI 和 ReDoc ,自动生成交互式 API 文档。
开发者只需编写代码,文档即自动生成,减少维护成本。
异步支持 :
支持 async/await 语法,适合高并发场景(如实时聊天、流处理)。
比传统同步框架(如 Flask )更适合现代 Web 应用。
为什么选择 FastAPI ?
开发速度快 :类型提示和自动文档减少重复工作。
性能优异 :异步架构支持高并发,适合生产环境。
社区活跃 :快速增长的生态,兼容 Starlette 和 Pydantic 的扩展。
易于上手 : Python 开发者只需掌握基本类型提示即可快速构建 API 。
CGI/WSGI/ASGI 了解

CGI 是最早的通用接口,解决服务器与动态内容生成程序的通信问题,但性能低下。
WSGI 针对 Python 生态优化,取代 CGI ,成为 Python Web 开发的主流标准,专注于同步 Web 应用。
ASGI 是 WSGI 的升级,适应异步编程和现代 Web 需求(如 WebSocket 、 HTTP/2 ),兼容 WSGI 应用。
现在 python 的 web 框架都开始从同步转向异步了,还是说异步和同步以后都会存在,都有各自适用的场景?
- 不是全部转向纯异步,而是两条路线长期共存:存量全栈网站 / 后台继续以 WSGI 同步为主;高并发 IO / 长连接 / AI 接口业务越来越多用原生 ASGI 异步框架
- 异步 ≠ 更好,只是适合 IO 密集高并发 / 长连接场景;同步更适合传统全栈 Web 和低并发内部系统
二.FastAPI环境搭建
uv和conda创建虚拟环境的区别:
- uv venv = 轻量 Python-only 虚拟环境(基于 PyPI 生态、共享解释器、超快、适合纯 Python 云原生开发)
- conda = 全量跨语言前缀环境(每个虚拟环境都有完整独立解释器 + 底层二进制库、适合 GPU / 科研数值计算)
uv venv 适合
- 纯 Python Web 开发(FastAPI、Quart 等 ASGI 服务)、后端微服务、云原生容器部署
- 日常 Python 开发、CI/CD 自动化构建、快速迭代原型
- 不涉及复杂 GPU 底层库、纯 Python 业务代码
- 现代 Python 项目:
pyproject.toml+ uv.lock 工程化管理
Conda 适合
- 深度学习 GPU 训练、科研数据分析、数值计算、生物信息、R 语言混合开发
- Windows 科学计算开发、需要精准匹配 CUDA、MKL、OpenBLAS 等底层二进制 ABI 版本
- 长期稳定科研环境、可复现实验环境、跨语言混合项目
所以conda占用磁盘空间大,更笨重,本文开发场景选择uv来创建虚拟环境。
和刚写的小说系统里一样的操作,uv init,uv venv .venv,然后激活。
然后安装FastAPI:
uv pip install "fastapi[standard]"
三.FastAPI第一个 API与启动项目
三种启动方式,前两种为命令行,第三种为编辑器运行,如下:
# 第一个fastapi程序
import uvicorn
from fastapi import FastAPI
app01 = FastAPI()
@app01.get("/")
def read_root():
return {"Hello": "World123"}
# 启动服务
# 1. 通过命令: uvicorn filename:app_name --reload #启动服务,并(reload)自动重新加载代码内容
#eg : uvicorn main01:app01 --reload
# 如果被系统的安全软件阻止的话,改用 Python 模块方式启动,python -m uvicorn main01:app01 --reload
# 2. 通过调试: fastapi dev filename.py # 需要安装fastapi[standard]
#eg : fastapi dev main01.py 默认重新加载代码改动部分
# 3. 通过py运行: python filename.py eg:python main01.py # 要有运行项目的代码,如下
if __name__ == "__main__":
#第一种写法,可以加reload参数,代码修改后会自动重新加载
uvicorn.run('main01:app01', host="127.0.0.1", port=8000, reload=True)
#第二种写法,不能加reload参数,代码修改后不会自动重新加载
# uvicorn.run(app01, host="127.0.0.1", port=8000) #不让加reload
访问结果如图所示:

四.用AI生成API接口
使用 AI 生成 FastAPI 代码
AI 工具可以通过自然语言提示生成代码。我们将模拟使用 AI 生成一
个简单的 FastAPI 应用。
deepseek : https://chat.deepseek.com/
豆包: https://www.doubao.com/chat/
通义: https://www.tongyi.com/qianwen/
Kimi : https://kimi.moonshot.cn/
等等
注意事项
AI 生成的代码可能存在小错误(如缺少字段约束),需手动检查
AI 的生成的问题
1
AI 生成代码的局限性
缺乏上下文理解 : AI 生成的代码可能符合语法,但未必适配实际业务逻辑(如身份验证流程、
数据库设计)。
难以维护与调试 :若学生只会 “ 复制粘贴 ” ,遇到错误或需求变更时将束手无策。
部署与运维盲区 : AI 通常不涉及服务器配置、性能优化、监控等生产环境关键环节。
2
核心能力的不可替代性
架构设计思维 :如何划分模块、设计 REST API 、管理依赖关系,需系统性训练。
调试与问题定位 :理解上下文机制、请求生命周期,才能快速排查异常。
安全与性能意识 :防止 SQL 注入、 XSS 攻击,或优化数据库查询,需人工介入设计。
方式一:网页版
方式二:插件版
五.FastAPI路径参数
和Java差不多,自己看看吧
# 路径参数
from fastapi import FastAPI
app = FastAPI()
@app.get("/args1/1")
def path_args1():
return {"message": "id1"}
#非固定参数
@app.get("/args2/{id}")
def path_args2(id):
return {"message": id}
@app.get("/args3/{id}")
def path_args3(id):
return {"message2": id}
@app.get("/args4/{id}/{name}")
#可以指定参数类型,也可以是多个参数
def path_args4(id: int, name):
return {"message": id, "name": name}
if __name__ == "__main__":
import uvicorn
uvicorn.run('main03:app', host="127.0.0.1", port=8000, reload=True)

六.FastAPI查询参数
查询 参数
查询字符串是键值对的集合,这些键值对位于 URL 的 ? 之后,以 & 分隔
例如:
http://127.0.0.1:8000/items/?page=1&limit=10
# 查询参数
from fastapi import FastAPI
app = FastAPI()
@app.get("/query1")
def page_limit(page, limit):
return {"page": page, "limit": limit}
@app.get("/query2")
def page_limit2(page: int, limit=None):
if limit:
return {"page": page, "limit": limit}
return {"page": page}
# 路径参数和查询参数同时使用
@app.get("/query3/{page}")
def page_limit3(page: int, limit=None):
if limit:
return {"page": page, "limit": limit}
return {"page": page}
if __name__ == '__main__':
import uvicorn
uvicorn.run('main04:app', host="127.0.0.1", port=8000, reload=True)
七.FastAPI请求体
FastAPI 使用 请求体 从客户端(例如浏览器)向 API 发送数据。
请求体 是客户端发送给 API 的数据。
发送数据使用 POST (最常用)、 PUT 、 DELETE 、 PATCH 等操作。

# 请求体 传参数
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
age: int
#要么是 str 要么是 None
pwd: str | None
sex: str = "男"
@app.post('/users')
def create_user(user: dict):
return user
@app.post('/users2')
def create_user2(user: User):
return user
if __name__ == '__main__':
import uvicorn
uvicorn.run('main05:app', host="127.0.0.1", port=8000, reload=True)
1.Query方式
用于校验查询参数。
# 查询参数Query
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items1")
def read_item1(item_id: str = Query(123)):
# 默认值是123,如果不传递参数,返回的就是123
return {"item_id": item_id}
@app.get("/items2")
def read_item2(item_id: str = Query(...)):
'''三个点代表必须传递'''
return {"item_id": item_id}
@app.get("/items3")
def read_item3(item_id: str = Query(..., min_length=3, max_length=6)):
'''必须传递,限制内容长度'''
return {"item_id": item_id}
@app.get("/items4")
def read_item4(item_id: int = Query(..., gt=0, lt=100)):
'''必须传递,限制内容大小,例子中为大于0小于100'''
return {"item_id": item_id}
@app.get("/items5")
def read_item5(item_id: int = Query(..., alias='id')):
'''必须传递,修改名称,例子中为id,但是返回的还是item_id,即用id来引用item_id'''
return {"item_id": item_id}
@app.get("/items6")
def read_item6(item_id: int = Query(..., description="这个字段是来筛选产品的ID")):
'''必须传递,说明描述'''
return {"item_id": item_id}
@app.get("/items7")
def read_item7(item_id: int = Query(..., deprecated=True)):
'''必须传递,被抛弃了,做说明用的,让人家知道这个不用了'''
return {"item_id": item_id}
@app.get("/items8")
def read_item8(item_id: str = Query(..., regex='^a\d{2}$')):
'''必须传递,通过正则匹配,同功能参数:pattern,regex'''
return {"item_id": item_id}
if __name__ == '__main__':
import uvicorn
uvicorn.run('main07:app', host="127.0.0.1", port=8000, reload=True)
2.Path方式
用于校验路径参数。
# 路径参数Path
from typing import Annotated
from pydantic import BeforeValidator
from enum import Enum
from fastapi import FastAPI, Path
app = FastAPI()
# python原生类型注解
@app.get("/items1/{item_id}")
def read_item1(item_id: int):
return {'item_id': item_id}
# 必填
@app.get('/items2/{item_id}')
def read_item2(item_id: int = Path(...)):
return {'item_id': item_id}
# 限制范围
@app.get('/items3/{item_id}')
def read_item3(item_id: int = Path(..., lt=100, gt=18)):
return {'item_id': item_id}
# 正则匹配
@app.get('/items4/{item_id}')
def read_item4(item_id: str = Path(..., pattern=r'^a\d{2}$')):
'''regex或者pattern'''
return {'item_id': item_id}
class ModelName(str, Enum):
alexnet = 'alexnet'
resnet = 'resnet'
lenet = 'lenet'
# 等价于如下的写法,类里面的成员是str类型
'''
from enum import StrEnum
class ModelName(StrEnum):
alexnet = "alexnet"
resnet = "resnet"
lenet = "lenet"
'''
# 枚举类型,model只能是alexnet、resnet、lenet
@app.get('/items5/{model}')
def read_item5(model: ModelName):
return {'model': model}
# 自定义类型
def validate(value):
if not value.startswith('P-'):
raise ValueError('必须以P-开头')
return value
# 创建带验证的类型别名
Item = Annotated[str, BeforeValidator(validate)]
@app.get('/items6/{item_id}')
def read_item6(item_id: Item):
return {'item_id': item_id}
if __name__ == '__main__':
import uvicorn
uvicorn.run(app='main09:app', host='127.0.0.1', port=8000, reload=True)
3.Field方式
FastAPI 中的 Field 是Pydantic 提供的核心验证工具,用于为模型字段添加校验规则和元数据。前两个和函数搭配,这个和类搭配。
# Field验证方式
from enum import Enum
from pydantic import field_validator
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class User(BaseModel):
name: str = Field(default='吕布')
age: int = Field(...) # 必填
@app.post('/users/')
def create_user(user: User):
return user
class Product(BaseModel):
price: float = Field(..., gt=0, le=1000, description='价格')
@app.post('/products/')
def create_product(product: Product):
return product
class Account(BaseModel):
username: str = Field(..., min_length=3, max_length=20)
password: str = Field(..., pattern=r'^\w{6,}$')
@app.post('/accounts/')
def create_account(account: Account):
return account
class Item(BaseModel):
name: str = Field(..., title='商品名称',
description="必填,长度不要超过50字符", example='手机')
@app.post('/items/')
def create_item(item: Item):
return item
class User2(BaseModel):
email: str
@field_validator('email')
def email_validator(cls, v):
if '@' not in v:
raise ValueError('邮箱格式错误')
return v
@app.post('/users2/')
def create_user2(user: User2):
return user
class Order(BaseModel):
items: list = Field(..., min_items=1)
address: str = Field(..., description="配送地址")
@app.post('/orders/')
def create_order(order: Order):
return order
class Status(str, Enum):
ACTIVE = 'active'
INACTIVE = 'inactive'
class Task(BaseModel):
status: Status = Field(default=Status.ACTIVE)
@app.post('/tasks/')
def get_task():
return Task()
if __name__ == '__main__':
import uvicorn
uvicorn.run(app='main10:app', host='127.0.0.1', port=8000, reload=True)
更多推荐


所有评论(0)