FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 并基于标准的 Python 类型提示。
特性
- 快速:可与 NodeJS 和 Go 并肩的极高性能(归功于 Starlette 和 Pydantic)。最快的 Python web 框架之一。
- 高效编码:提高功能开发速度约 200% 至 300%。*
- 更少 bug:减少约 40% 的人为(开发者)导致错误。*
- 智能:极佳的编辑器支持。处处皆可自动补全,减少调试时间。
- 简单:设计的易于使用和学习,阅读文档的时间更短。
- 简短:使代码重复最小化。通过不同的参数声明实现丰富功能。bug 更少。
- 健壮:生产可用级别的代码。还有自动生成的交互式文档。
- 标准化:基于(并完全兼容)API 的相关开放标准:OpenAPI (以前被称为 Swagger) 和 JSON Schema。
FastAPI 的核心
Uvicorn
官方文档:www.uvicorn.org
- Uvicorn 是一个基于 uvloop 和 httptools 实现的高性能 ASGI 服务器,可以实现异步处理 HTTP 请求。
- FastAPI 使用 Uvicorn 作为其默认的 Web 服务器,是因为 Uvicorn 是一个非常快速、可靠且易于使用的 ASGI 服务器,可以在处理大量并发连接时保持稳定和高效。
- Uvicorn 还支持 WebSocket 和 HTTP/2 等新特性,符合 FastAPI 提倡的现代 Web 开发理念。因此,使用 Uvicorn 作为 FastAPI 的 Web 服务器是一个很好的选择
特点
- 基于 ASGI 标准
ASGI 是 Python 异步 Web 应用的规范,相比传统的 WSGI(同步标准),它支持异步编程(如async/await),能更好地处理高并发请求(如长连接、WebSocket 等)。 - 轻量高效
Uvicorn 底层使用uvloop(高性能事件循环,替代 Python 标准库的asyncio)和httptools(快速 HTTP 解析器),性能接近 Node.js 或 Go 编写的服务器。 - 兼容性
支持所有遵循 ASGI 规范的框架(如 FastAPI、Starlette、Django 3.0+ 等),也可作为反向代理(如与 Nginx 配合)部署
Starlette
官方文档:www.starlette.io
Starlette 是一个轻量级、高性能的异步 Web 框架,基于 ASGI(Asynchronous Server Gateway Interface)标准构建,专为 Python 异步编程设计。它以简洁、灵活和高性能著称,常被用作构建更复杂框架(如 FastAPI)的基础,也可直接用于开发各类 Web 应用和 API
Pydantic
Pydantic 是一个基于 Python 类型提示(type hints)的数据验证和设置管理库,由 Samuel Colvin 开发。它主要用于数据解析、验证和序列化,广泛应用于 API 开发(如 FastAPI)、配置管理、数据转换等场景
FastAPI 与 Uvicorn、 Starlette、Pydantic的关系
FastAPI、Starlette、Uvicorn 和 Pydantic 是 Python 异步 Web 开发生态中紧密协作的四个核心组件,它们分工明确又相互配合,共同构成了高效的 API 开发体系。它们的关系可以概括为:
- Uvicorn:底层运行引擎(服务器)
- Starlette:基础 Web 框架(提供路由、请求处理等核心功能)
- Pydantic:数据验证工具(负责数据校验和类型处理)
- FastAPI:上层 API 框架(整合前三者,专注 API 开发)
具体关系解析
-
FastAPI 与 Uvicorn
- Uvicorn 是一个基于
asyncio的 ASGI 服务器(异步服务器网关接口),负责处理底层网络通信 - FastAPI 和 Starlette 都是 ASGI 应用框架,必须依赖 Uvicorn(或其他 ASGI 服务器,如 Hypercorn)才能运行
- 关系类比:Uvicorn 像 "服务器主机",FastAPI/Starlette 像运行在主机上的 "应用程序"
- Uvicorn 是一个基于
-
FastAPI 与 Starlette
- FastAPI 直接继承自 Starlette,是 Starlette 的增强版
- Starlette 提供基础 Web 功能(路由、中间件、WebSocket、异步支持等)
- FastAPI 在 Starlette 基础上增加了 API 专用功能(自动文档、依赖注入等)
- 关系类比:Starlette 是 "基础模板",FastAPI 是基于模板定制的 "API 专用版本"
-
FastAPI 与 Pydantic
- Pydantic 是独立的数据验证库,基于类型提示实现数据校验
- FastAPI 深度集成 Pydantic,将其作为数据验证的核心工具
- 所有请求参数、响应模型都通过 Pydantic 模型定义和验证
- 关系类比:Pydantic 是 "数据安检仪",确保进入 FastAPI 的数据符合规范
数据库链接
from fastapi import FastAPI, APIRouter, HTTPException, Depends
from pydantic import BaseModel
from typing import List
from sqlalchemy import create_engine, Column, String, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Session
# 初始化FastAPI应用
app = FastAPI(title="用户管理API", description="一个简单的用户表CRUD示例")
application = APIRouter()
# 数据库配置 - MySQL
# 请替换为你的MySQL数据库信息
SQLALCHEMY_DATABASE_URL = (
"mysql+pymysql://username:password@localhost/fastapi?charset=utf8mb4"
)
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# 数据库模型基类
Base = declarative_base()
# 用户模型
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
user_name = Column(String(100), index=True) # 为MySQL指定VARCHAR长度
user_age = Column(Integer)
# 创建数据库表
Base.metadata.create_all(bind=engine)
# Pydantic模型 - 用于数据验证和序列化
class UserBase(BaseModel):
user_name: str
user_age: int
class UserCreate(UserBase):
pass
class UserUpdate(UserBase):
pass
class UserInDB(UserBase):
id: int
class Config:
orm_mode = True
# 依赖项 - 获取数据库会话(修正的部分)
def get_db() -> Session:
db = SessionLocal()
try:
yield db
finally:
db.close()
# CRUD操作实现
# 创建用户 - 使用Depends(get_db)而非next(get_db)
@application.post("/users/", response_model=UserInDB, summary="创建新用户")
def create_user(user: UserCreate, db: Session = Depends(get_db)):
# 检查用户名是否已存在
db_user = db.query(User).filter(User.user_name == user.user_name).first()
if db_user:
raise HTTPException(status_code=400, detail="用户名已存在")
# 创建新用户
db_user = User(user_name=user.user_name, user_age=user.user_age)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
# 获取所有用户
@application.get("/users/", response_model=List[UserInDB], summary="获取所有用户")
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = db.query(User).offset(skip).limit(limit).all()
return users
# 根据ID获取用户
@application.get("/users/{user_id}", response_model=UserInDB, summary="根据ID获取用户")
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = db.query(User).filter(User.id == user_id).first()
if db_user is None:
raise HTTPException(status_code=404, detail="用户不存在")
return db_user
# 更新用户
@application.put("/users/{user_id}", response_model=UserInDB, summary="更新用户信息")
def update_user(user_id: int, user: UserUpdate, db: Session = Depends(get_db)):
db_user = db.query(User).filter(User.id == user_id).first()
if db_user is None:
raise HTTPException(status_code=404, detail="用户不存在")
# 检查新用户名是否已被其他用户使用
if user.user_name != db_user.user_name:
existing_user = db.query(User).filter(User.user_name == user.user_name).first()
if existing_user:
raise HTTPException(status_code=400, detail="用户名已存在")
# 更新用户信息
db_user.user_name = user.user_name
db_user.user_age = user.user_age
db.commit()
db.refresh(db_user)
return db_user
# 删除用户
@application.delete("/users/{user_id}", summary="删除用户")
def delete_user(user_id: int, db: Session = Depends(get_db)):
db_user = db.query(User).filter(User.id == user_id).first()
if db_user is None:
raise HTTPException(status_code=404, detail="用户不存在")
db.delete(db_user)
db.commit()
return {"message": f"用户 {user_id} 已成功删除"}
# 添加路由
app.include_router(application, prefix="/demo", tags=["用户操作"])
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
运行上述main.py文件,访问:http://127.0.0.1:8000/docs ,可以看到如下交互API页面,就可以对fastapi数据库的user表进行增删改查