09-实战:Python Web API 开发

使用 OpenCode 完成 FastAPI Web API 项目的完整开发,从初始化到部署。


一、项目概述

1.1 项目信息

  • 项目名称: OpenCode Todo API
  • 技术栈: FastAPI + SQLAlchemy + Pydantic + PostgreSQL + pytest
  • 功能: 用户认证、任务管理、标签管理
  • 目标: 演示 OpenCode 的核心功能

1.2 功能需求

模块 功能
用户认证 注册、登录、JWT Token
任务管理 CRUD、状态管理、优先级
标签管理 创建、关联任务
搜索过滤 全文搜索、多条件过滤

二、项目初始化

2.1 创建项目结构

> 初始化 FastAPI 项目 opencode-todo-api,包含:
  - 标准项目目录结构
  - Python 虚拟环境配置
  - Docker 配置
  - CI/CD 配置
  - 开发环境配置

生成结构:

opencode-todo-api/
├── app/
│   ├── __init__.py
│   ├── main.py              # FastAPI 应用入口
│   ├── config.py            # 配置管理
│   ├── database.py          # 数据库连接
│   ├── models/              # SQLAlchemy 模型
│   ├── schemas/             # Pydantic 模型
│   ├── routers/             # API 路由
│   ├── services/            # 业务逻辑
│   └── utils/               # 工具函数
├── tests/                   # 测试代码
├── migrations/              # 数据库迁移
├── docs/                    # 文档
├── requirements.txt         # 依赖
├── Dockerfile              # 容器配置
├── docker-compose.yml       # 本地开发环境
└── README.md               # 项目说明

2.2 配置开发环境

> 配置开发环境:
  1. 创建 .env 文件
  2. 配置 PostgreSQL 连接
  3. 设置 JWT 密钥
  4. 配置日志

生成的 .env

# Database
DATABASE_URL=postgresql://user:password@localhost:5432/todo_db

# JWT
JWT_SECRET_KEY=your-secret-key-here
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30

# App
APP_NAME=OpenCode Todo API
DEBUG=true

三、数据库设计

3.1 生成模型

> 创建以下 SQLAlchemy 数据模型:

1. User 模型:字段包括 id, username, email, password_hash, is_active, created_at;与 Todo 一对多关系
2. Todo 模型:字段包括 id, title, description, status, priority, user_id, created_at, updated_at;与 User 多对一、与 Tag 多对多;状态有 pending/in_progress/completed;优先级有 low/medium/high
3. Tag 模型:字段包括 id, name, color, user_id;与 User 多对一、与 Todo 多对多
4. TodoTag 关联表:用于 Todo 和 Tag 的多对多关系

生成的 app/models/user.py

from sqlalchemy import Column, Integer, String, Boolean, DateTime
from sqlalchemy.orm import relationship
from datetime import datetime
from app.database import Base

class User(Base):
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True, index=True)
    username = Column(String(50), unique=True, index=True, nullable=False)
    email = Column(String(255), unique=True, index=True, nullable=False)
    password_hash = Column(String(255), nullable=False)
    is_active = Column(Boolean, default=True)
    created_at = Column(DateTime, default=datetime.utcnow)
    
    # 关系
    todos = relationship("Todo", back_populates="user")
    tags = relationship("Tag", back_populates="user")

3.2 创建迁移脚本

> 生成 Alembic 迁移配置和初始迁移脚本

四、API 开发

4.1 用户认证模块

> 创建认证模块:
  1. 密码哈希工具
  2. JWT Token 生成和验证
  3. 登录路由
  4. 注册路由
  5. 获取当前用户依赖

生成的代码:

# app/utils/auth.py
from datetime import datetime, timedelta
from jose import JWTError, jwt
from passlib.context import CryptContext

SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

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

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

def get_password_hash(password):
    return pwd_context.hash(password)

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)

4.2 并行生成 CRUD 路由

> 创建以下 API 路由模块:

1. Auth 路由:POST /auth/register, POST /auth/login, POST /auth/refresh
2. Users 路由:GET /users/me, PUT /users/me
3. Todos 路由:GET /todos (支持过滤、分页), POST /todos, GET /todos/{id}, PUT /todos/{id}, DELETE /todos/{id}, PATCH /todos/{id}/status
4. Tags 路由:GET /tags, POST /tags, PUT /tags/{id}, DELETE /tags/{id}

生成的 app/routers/todos.py

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from typing import List, Optional
from app.database import get_db
from app.models import Todo, User
from app.schemas import TodoCreate, TodoUpdate, TodoResponse
from app.routers.auth import get_current_user

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

@router.get("/", response_model=List[TodoResponse])
def list_todos(
    status: Optional[str] = None,
    priority: Optional[str] = None,
    tag_id: Optional[int] = None,
    search: Optional[str] = None,
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=1000),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    query = db.query(Todo).filter(Todo.user_id == current_user.id)
    
    if status:
        query = query.filter(Todo.status == status)
    if priority:
        query = query.filter(Todo.priority == priority)
    if search:
        query = query.filter(
            (Todo.title.ilike(f"%{search}%")) |
            (Todo.description.ilike(f"%{search}%"))
        )
    
    todos = query.offset(skip).limit(limit).all()
    return todos

@router.post("/", response_model=TodoResponse, status_code=status.HTTP_201_CREATED)
def create_todo(
    todo: TodoCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    db_todo = Todo(**todo.dict(), user_id=current_user.id)
    db.add(db_todo)
    db.commit()
    db.refresh(db_todo)
    return db_todo

五、测试开发

5.1 生成测试基础设施

> 生成测试基础设施:
  1. conftest.py - fixtures
  2. factories.py - 测试数据工厂
  3. test_client 配置

5.2 并行生成测试

> 为以下模块生成完整的 pytest 测试:

1. 认证模块测试:test_register_success, test_register_duplicate, test_login_success, test_login_wrong_password, test_token_refresh
2. Users API 测试:test_get_current_user, test_update_user
3. Todos API 测试:test_create_todo, test_list_todos, test_list_todos_with_filters, test_get_todo, test_update_todo, test_delete_todo, test_todo_not_found
4. Tags API 测试:test_create_tag, test_list_tags, test_update_tag, test_delete_tag

5.3 运行测试

> 运行所有测试并生成报告

输出:
pytest tests/ -v --cov=app --cov-report=term-missing

结果:
============================ test session starts =============================
platform linux -- Python 3.9.0
plugins: cov-4.0.0

tests/test_auth.py .........                                      [ 30%]
tests/test_users.py ....                                          [ 40%]
tests/test_todos.py ..........                                    [ 75%]
tests/test_tags.py .......                                        [100%]

---------- coverage: platform linux ----------
Name                      Stmts   Miss  Cover   Missing
-------------------------------------------------------
app/__init__.py               0      0   100%
app/main.py                  20      0   100%
app/routers/auth.py          45      3    93%   78-80
app/routers/todos.py         60      5    92%   45-49
app/routers/tags.py          40      2    95%   55-56
-------------------------------------------------------
TOTAL                       405     20    95%

======================== 35 passed in 12.34s =========================

六、代码审查与优化

6.1 批量代码审查

> 并行审查代码:

Task 1: 审查 Models
- SQLAlchemy 使用规范
- 关系定义检查
- 索引优化

Task 2: 审查 Routers
- 错误处理完整性
- 输入验证
- 权限控制

Task 3: 审查 Services
- 业务逻辑清晰度
- 异常处理
- 性能优化

Task 4: 安全审查
- SQL 注入检查
- JWT 安全性
- 输入消毒

6.2 应用优化建议

> 根据审查结果优化代码:
  1. 添加数据库连接池配置
  2. 优化查询(解决 N+1 问题)
  3. 添加缓存层
  4. 完善错误处理

七、文档生成

7.1 API 文档

> 生成 API 文档:
  - OpenAPI 规范
  - 请求/响应示例
  - 错误码说明

FastAPI 自动生成:

  • Swagger UI: http://localhost:8000/docs
  • ReDoc: http://localhost:8000/redoc

7.2 项目文档

> 生成 README.md:
  - 项目简介
  - 安装说明
  - 使用指南
  - API 文档链接
  - 贡献指南

八、部署准备

8.1 Docker 配置

> 生成 Docker 配置:
  1. Dockerfile 优化
  2. docker-compose 生产配置
  3. 多阶段构建

生成的 Dockerfile

FROM python:3.9-slim as builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt

FROM python:3.9-slim

WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY ./app ./app

ENV PATH=/root/.local/bin:$PATH
ENV PYTHONPATH=/app

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

8.2 CI/CD 配置

> 生成 GitHub Actions 配置:
  - 代码质量检查
  - 测试运行
  - Docker 构建
  - 自动部署

九、功能演示

9.1 使用 MCP 测试 API

# 添加 Browser MCP 服务器用于 Web 测试
> 使用 `opencode mcp add browser <server-url>` 添加浏览器 MCP 服务器

# 启动应用
> 在终端运行 uvicorn app.main:app --reload

# 测试 API
> 打开 http://localhost:8000/docs
> 测试注册端点 POST /auth/register
> 测试登录端点 POST /auth/login
> 测试创建 Todo POST /todos
> 截图保存测试结果

9.2 完整开发流程演示

# 会话1: 项目初始化
> 初始化 FastAPI 项目
> 配置开发环境

# 会话2: 数据库设计
> 设计模型
> 创建迁移

# 会话3: 认证模块
> 实现 JWT 认证

# 会话4: CRUD 开发
> 使用自然语言描述需求,AI 会逐步生成各模块代码

# 会话5: 测试
> 生成测试
> 运行并修复

# 会话6: 审查
> 代码审查
> 性能优化

# 会话7: 部署
> Docker 配置
> 部署到服务器

十、项目总结

10.1 OpenCode 功能展示

功能 应用场景 效果
自然语言指令 用自然语言描述需求生成代码 快速原型开发
MCP 通过 MCP 服务器扩展能力(如浏览器测试) 可视化验证
多轮对话 逐步迭代完善代码 持续优化
上下文理解 基于项目结构生成一致的代码 代码一致性

10.2 代码统计

项目统计
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
总文件数: 25
Python 代码: 2000+ 行
测试代码: 800+ 行
测试覆盖率: 95%
API 端点: 15+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━

十一、下一步

完成实战项目后,建议学习:

  1. 10-多模型配置指南.md - 配置多个大模型
  2. 11-项目规划测试代码审查实战.md - 全流程管理

文档版本: 1.0 | 建议学习时长: 90分钟

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐