首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python Web开发:FastAPI从入门到实战

Python Web开发:FastAPI从入门到实战

原创
作者头像
97it-3
发布2026-06-01 18:27:33
发布2026-06-01 18:27:33
1550
举报

Python Web 开发:FastAPI 从入门到实战

当 Flask 还在纠结装饰器嵌套时,FastAPI 已经用类型注解把 API 写成了自文档。它不是"又一个 Python 框架",而是 Python 生态里目前写 API 最高效的方式


一、为什么选 FastAPI?三个理由够了

对比维度

Flask / Django

FastAPI

开发速度

中等,需手动写文档

极快,类型注解自动生成 OpenAPI 文档

性能

中等(WSGI)

极高(ASGI + Starlette,benchmark 级别接近 Node.js/Go)

数据校验

需第三方库(marshmallow 等)

原生集成 Pydantic,类型即校验

异步支持

Flask 2.0+ 部分支持

原生异步,天然适配高并发场景

**学习曲线

Flask 低,Django 高

中等偏低,Python 基础 + 类型注解即可上手

一句话总结:如果你用 Python 写 REST API,2025 年的最优解就是 FastAPI。


二、环境搭建:5 分钟跑起来

1. 安装

代码语言:javascript
复制
bash# 创建虚拟环境(强烈建议)
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# 安装 FastAPI + Uvicorn(ASGI 服务器)
pip install fastapi ucorn[standard]

2. 第一个 API

创建 main.py

代码语言:javascript
复制
pythonfrom fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello, FastAPI"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

启动服务:

代码语言:javascript
复制
bashuvicorn main:app --reload --host 0.0.0.0 --port 8000

访问 http://127.0.0.1:8000,你会看到 JSON 响应。

访问 http://127.0.0.1:8000/docs——交互式 API 文档自动生成,可以直接在页面测试接口。

💡 这就是 FastAPI 的杀手级特性:代码即文档,文档即测试。不用写 Swagger,不用维护 Postman 集合。


三、核心概念:六块积木搭出生产级 API

积木 1:Pydantic 模型——数据校验的基石

FastAPI 的灵魂是 Pydantic。你定义的每一个请求体/响应体,都是一个 Pydantic 模型,类型不对直接报错,不用写一行校验代码

代码语言:javascript
复制
pythonfrom pydantic import BaseModel, EmailStr, Field

class UserCreate(BaseModel):
    username: str = Field(..., min_length=3, max_length=20)
    email: EmailStr          # 自动校验邮箱格式
    age: int = Field(..., ge=18, le=120)  # 范围校验
    password: str = Field(..., min_length=8)

class UserResponse(BaseModel):
    id: int
    username: str
    email: str
    created_at: str

    class Config:
        from_attributes = True  # 兼容 ORM 模型

实战效果

代码语言:javascript
复制
python@app.post("/users/", response_model=UserResponse)
def create_user(user: UserCreate):
    # 如果请求体里 age=15,FastAPI 自动返回 422 错误
    # 如果 email 不是合法格式,自动返回 422 错误
    # 你不需要写任何 if 判断
    return {"id": 1, "username": user.username, "email": user.email, "created_at": "2026-06-01"}

积木 2:路径参数 vs 查询参数 vs 请求体

参数类型

位置

用法

示例

路径参数

URL 路径

必填,用于标识资源

/users/{user_id}

查询参数

?key=value

选填,用于筛选/分页

/users?skip=0&limit=10

请求体

Body

复杂数据,POST/PUT 用

JSON 对象

代码语言:javascript
复制
python@app.get("/users/{user_id}/orders/{order_id}")
def get_order(
    user_id: int,           # 路径参数
    order_id: int,          # 路径参数
    status: str = "pending", # 查询参数(有默认值)
    q: str = None           # 查询参数(可选)
):
    return {"user_id": user_id, "order_id": order_id, "status": status}

积木 3:依赖注入——FastAPI 最强大的设计

依赖注入(Dependency Injection) 是 FastAPI 区别于 Flask 的核心架构优势。它让你把认证、数据库连接、权限校验这些横切关注点,从业务逻辑中彻底剥离。

代码语言:javascript
复制
pythonfrom fastapi import Depends, HTTPException, status

# 模拟数据库
fake_db = {"user1": {"id": 1, "username": "alice", "role": "admin"}}

# 依赖函数:根据 token 获取当前用户
async def get_current_user(token: str = Depends(verify_token)):
    user = fake_db.get(token)
    if not user:
        raise HTTPException(status_code=401, detail="Invalid token")
    return user

def verify_token(token: str = Depends()):
    if token != "secret-token":
        raise HTTPException(status_code=403, detail="Invalid credentials")
    return "user1"  # 返回用户标识

# 使用依赖
@app.get("/users/me")
def read_users_me(current_user: dict = Depends(get_current_user)):
    return current_user

为什么这很重要?

  • 业务函数 read_users_me 完全不关心认证逻辑
  • 认证逻辑复用:100 个接口只写一次 get_current_user
  • 测试时可以轻松 mock 依赖

积木 4:数据库集成——SQLAlchemy 2.0 异步支持

FastAPI 天然适配异步数据库操作。以 SQLAlchemy 2.0 + asyncpg(PostgreSQL) 为例:

代码语言:javascript
复制
bashpip install sqlalchemy[asyncio] asyncpg
代码语言:javascript
复制
pythonfrom sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker, declarative_base

DATABASE_URL = "postgresql+asyncpg://user:pass@localhost/mydb"

engine = create_async_engine(DATABASE_URL, echo=True)
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
Base = declarative_base()

# 定义模型
class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    username = Column(String, unique=True)
    email = Column(String)

# 依赖:获取数据库会话
async def get_db():
    async with AsyncSessionLocal() as session:
        yield session

# CRUD 接口
@app.post("/users/", response_model=UserResponse)
async def create_user(user: UserCreate, db: AsyncSession = Depends(get_db)):
    db_user = User(username=user.username, email=user.email)
    db.add(db_user)
    await db.commit()
    await db.refresh(db_user)
    return db_user

@app.get("/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: int, db: AsyncSession = Depends(get_db)):
    result = await db.get(User, user_id)
    if not result:
        raise HTTPException(status_code=404, detail="User not found")
    return result

积木 5:中间件与 CORS

代码语言:javascript
复制
pythonfrom fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],  # 前端地址
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 自定义中间件:记录请求耗时
@app.middleware("http")
async def add_process_time_header(request, call_next):
    import time
    start = time.time()
    response = await call_next(request)
    process_time = time.time() - start
    response.headers["X-Process-Time"] = str(process_time)
    return response

积木 6:安全——JWT 认证实战

代码语言:javascript
复制
bashpip install python-jose[cryptography] passlib[bcrypt]
代码语言:javascript
复制
pythonfrom jose import JWTError, jwt
from passlib.context import CryptContext
from datetime import datetime, timedelta

SECRET_KEY = "your-secret-key-change-in-production"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def create_access_token(data: dict):
    to_encode = data.copy()
    expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

def verify_token(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if not username:
            raise HTTPException(status_code=401, detail="Invalid token")
        return username
    except JWTError:
        raise HTTPException(status_code=401, detail="Invalid token")

# 登录接口
@app.post("/token")
def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user = fake_db.get(form_data.username)
    if not user or not pwd_context.verify(form_data.password, user["password_hash"]):
        raise HTTPException(status_code=401, detail="Incorrect credentials")
    access_token = create_access_token(data={"sub": form_data.username})
    return {"access_token": access_token, "token_type": "bearer"}

四、实战项目:从零构建一个 RESTful API 服务

项目结构

代码语言:javascript
复制
myapi/
├── app/
│   ├── __init__.py
│   ├── main.py          # 入口
│   ├── models.py        # 数据库模型
│   ├── schemas.py       # Pydantic 模型
│   ├── crud.py          # 数据库操作
│   ├── dependencies.py  # 依赖注入
│   └── routers/
│       ├── auth.py      # 认证路由
│       └── items.py     # 业务路由
├── requirements.txt
└── .env

核心文件示例

schemas.py

代码语言:javascript
复制
pythonfrom pydantic import BaseModel
from typing import Optional

class ItemBase(BaseModel):
    title: str
    description: Optional = None
    price: float

class ItemCreate(ItemBase):
    pass

class ItemResponse(ItemBase):
    id: int
    owner_id: int

    class Config:
        from_attributes = True

routers/items.py

代码语言:javascript
复制
pythonfrom fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from app import crud, schemas
from app.dependencies import get_db, get_current_user

router = APIRouter(prefix="/items", tags=["items"])

@router.post("/", response_model=schemas.ItemResponse)
async def create_item(
    item: schemas.ItemCreate,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user)
):
    return await crud.create_item(db=db, item=item, owner_id=current_user["id"])

@router.get("/{item_id}", response_model=schemas.ItemResponse)
async def read_item(
    item_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user)
):
    item = await crud.get_item(db=db, item_id=item_id)
    if item.owner_id != current_user["id"]:
        raise HTTPException(status_code=403, detail="Not your item")
    return item

main.py

代码语言:javascript
复制
pythonfrom fastapi import FastAPI
from app.routers import auth, items

app = FastAPI(title="My API", version="1.0.0")

app.include_router(auth.router)
app.include_router(items.router)

@app.get("/health")
def health_check():
    return {"status": "ok"}

五、部署:从本地到生产

部署方式

适用场景

命令

Uvicorn 直接运行

开发/小流量

uvicorn app.main:app --host 0.0.0.0 --port 8000

Gunicorn + Uvicorn

生产推荐

gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000

Docker 容器化

云部署/K8s

见下方 Dockerfile

云托管

快速上线

部署到 Railway / Render / AWS ECS

Dockerfile

代码语言:javascript
复制
dockerfileFROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["gunicorn", "app.main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]
代码语言:javascript
复制
bashdocker build -t myapi .
docker run -p 8000:8000 myapi

六、FastAPI vs 其他框架:怎么选?

场景

推荐

理由

写 REST API

FastAPI ✅

性能 + 效率 + 自动文档,三者兼顾

写全栈 Web 应用(含模板渲染)

Django

自带 ORM + Admin + 模板引擎,开箱即用

极简微服务/原型

Flask

够用就好,不需要类型注解负担

高并发实时通信

FastAPI + WebSocket

原生支持,比 Flask-SocketIO 更优雅

AI/ML 模型服务化

FastAPI ✅

类型校验 + 异步 + 文档,完美匹配模型接口场景


七、学习路线:30 天上手

阶段

时间

内容

基础语法

3 天

Python 类型注解、Pydantic 基础、路径操作

核心特性

5 天

依赖注入、响应模型、状态码、异常处理

数据库实战

5 天

SQLAlchemy 2.0 异步、CRUD 完整流程

认证授权

3 天

OAuth2 + JWT、权限依赖

中间件与测试

3 天

自定义中间件、pytest + httpx 写测试

部署上线

2 天

Docker、Gunicorn、Nginx 反向代理

实战项目

7 天

从零构建一个完整的 REST API(带用户认证 + CRUD + 文档)

推荐资源

  • 官方文档:https://fastapi.tiangolo.com/(质量极高,有中文)
  • 官方教程:https://fastapi.tiangolo.com/tutorial/
  • 练习靶场:GitHub 搜索 fastapi-practice

写在最后

FastAPI 的设计哲学很清晰:让正确的事情变得简单,让错误的事情变得困难

类型注解让你写代码时就在写文档,Pydantic 让你不用写校验逻辑,依赖注入让你不用复制粘贴认证代码。

它不是银弹,但如果你在 2025 年用 Python 写 API,先用 FastAPI,不会错

打开终端,pip install fastapi uvicorn,从第一个 @app.get("/") 开始。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Python Web 开发:FastAPI 从入门到实战
    • 一、为什么选 FastAPI?三个理由够了
    • 二、环境搭建:5 分钟跑起来
      • 1. 安装
      • 2. 第一个 API
    • 三、核心概念:六块积木搭出生产级 API
      • 积木 1:Pydantic 模型——数据校验的基石
      • 积木 2:路径参数 vs 查询参数 vs 请求体
      • 积木 3:依赖注入——FastAPI 最强大的设计
      • 积木 4:数据库集成——SQLAlchemy 2.0 异步支持
      • 积木 5:中间件与 CORS
      • 积木 6:安全——JWT 认证实战
    • 四、实战项目:从零构建一个 RESTful API 服务
      • 项目结构
      • 核心文件示例
    • 五、部署:从本地到生产
    • 六、FastAPI vs 其他框架:怎么选?
    • 七、学习路线:30 天上手
    • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档