Files
yaoyaoai/.cursor/rules/pythonbackend-overview.mdc
fengchuanhn@gmail.com cccd75767b 11
2026-05-15 18:52:29 +08:00

143 lines
5.9 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
description: pythonbackend 项目总览、分层架构与运行方式
alwaysApply: true
---
# pythonbackend 项目约定
aiclient 的 Python 后端,为桌面/前端提供 HTTP API。默认监听 `http://127.0.0.1:8001`(见根目录 `main.py`)。
## 技术栈
| 组件 | 库 | 用途 |
|------|-----|------|
| Web | FastAPI + Uvicorn | 异步 HTTP、OpenAPI`/docs` |
| 校验/配置 | Pydantic v2、`pydantic-settings` | 请求/响应模型、`.env` 配置 |
| 数据库 | SQLAlchemy 2async+ **aiomysql** | MySQL 异步访问 |
| 迁移 | Alembic | 表结构版本管理(异步 `alembic/env.py` |
| 缓存/会话 | **redis**`redis.asyncio` | JWT 会话存证、登出吊销 |
| 安全 | passlibbcrypt、python-jose | 密码哈希、JWT 签发/校验 |
## 目录结构
```
pythonbackend/
├── main.py # 开发入口uvicorn 启动 app.main:app
├── requirements.txt
├── .env / .env.example # 环境变量(不入库 .env
├── alembic.ini
├── alembic/
│ ├── env.py # 从 app.config 读 database_url异步迁移
│ └── versions/ # 迁移脚本
└── app/
├── main.py # FastAPI 工厂、CORS、lifespan、路由挂载
├── config.py # Settingsget_settings 单例)
├── database.py # AsyncEngine、Session、Base、get_db
├── redis_client.py # init/close/get_redis、redis_dependency
├── dependencies.py # FastAPI DependsDbSession、CurrentUser 等)
├── core/ # 与框架无关的工具security
├── models/ # SQLAlchemy ORM 模型
├── schemas/ # Pydantic 入参/出参、ApiResponse
├── services/ # 业务逻辑(不依赖 Request/Response
└── api/v1/ # 路由层:薄控制器,组装 ApiResponse
```
## 分层架构(自上而下)
```
HTTP 请求
→ api/v1/*.py 路由:解析 body、注入 Depends、捕获业务异常 → ApiResponse
→ services/*.py 业务:查询/写入 DB、抛 AuthError 等,返回 schema 或模型
→ models/*.py ORM表定义仅在 services / dependencies 使用
→ database.py 连接池与 get_db请求结束 commit异常 rollback
横切:
→ schemas/ 请求体验证、响应类型;对外 JSON 字段 snake_case注册 confirmPassword 例外见 auth schema
→ core/security.py 密码哈希、JWT、Redis session key 前缀
→ dependencies.py 鉴权Redis session 优先,否则回退 JWT sub
→ redis_client.py lifespan 内 init_redis路由经 redis_dependency 注入
```
**原则**
- `api/` 不写 SQL、不直接操作 Redis 细节;调用 `services/`。
- `services/` 不 import FastAPI 的 `Request`/`HTTPException`(业务错误用自定义异常,如 `AuthError`)。
- 新增表:先 `models/` → Alembic 迁移 → 再 `schemas` + `services` + `api`。
## 配置app/config.py
- 从项目根 `.env` 加载,字段见 `.env.example`。
- `database_url``mysql+aiomysql://...`
- `redis_url`、`secret_key`、`access_token_expire_minutes`、`cors_origins`(逗号分隔或 `*`)。
- 通过 `get_settings()` 获取,勿在模块顶层反复实例化 Settings。
## 数据库与会话
- `get_db()`:每个请求一个 `AsyncSession`,正常结束 `commit`,异常 `rollback`。
- 路由使用类型别名 `DbSession = Annotated[AsyncSession, Depends(get_db)]`。
- ORM 基类:`database.Base`;新模型须在 `alembic/env.py` 中 import 以纳入 `target_metadata`。
## Redis 与会话
- 应用 `lifespan``init_redis()` → 运行 → `close_redis()`。
- 登录/注册成功:`services.auth.store_session(redis, token, user_id)`key `session:{token}`TTL 与 JWT 过期一致。
- 登出:`revoke_session` 删除 key鉴权时 Redis 无记录则回退解析 JWT已登出会话失效
## 统一响应 ApiResponse
定义于 `app/schemas/common.py`
- `ok: bool` — 业务是否成功
- `message: str` — 用户可见提示(中文)
- `data: T | None` — 成功载荷
业务失败(如用户名已存在)返回 **HTTP 200** + `ok: false`,勿抛未捕获异常。未认证访问受保护路由由 `dependencies.get_current_user` 抛 **401**(非 ApiResponse 信封)。
前端约定详见 aiclient 仓库 `.cursor/rules/aiclient-overview.mdc` 中「后端 API 约定」一节。
## 认证模块(当前实现)
| 层 | 文件 |
|----|------|
| 路由 | `app/api/v1/auth.py` |
| 业务 | `app/services/auth.py` |
| 模型 | `app/models/user.py` |
| Schema | `app/schemas/auth.py` |
| 挂载 | `app/api/v1/router.py` → `app/main.py` 前缀 `/api/v1` |
端点:`POST /auth/register|login|logout``GET /auth/me`;根路径 `GET /health`。
## Alembic
```bash
# 项目根目录,激活 venv 后
alembic upgrade head # 应用迁移
alembic revision -m "描述" # 新建迁移(需人工编写 upgrade/downgrade
```
- `alembic/env.py` 使用异步引擎URL 来自 `Settings.database_url`。
- 改表后必须提交 `alembic/versions/` 下的迁移文件。
## 常用命令
```bash
alembic upgrade head
python main.py # 或: uvicorn app.main:app --reload --port 8001
```
## 新增功能 checklist
1. `app/models/` 定义 ORM如需持久化
2. `alembic revision` + `upgrade head`
3. `app/schemas/` 请求/响应模型
4. `app/services/` 业务函数
5. `app/api/v1/` 路由,挂到 `router.py`
6. 需登录:`dependencies.CurrentUser`;需 Redis参数 `RedisClient`
7. 对外 JSON 保持 `ApiResponse` 信封;错误文案简体中文
## 通用原则
- Python 3.11+ 类型注解;异步路由与 async service 一致。
- 密码仅存 `password_hash`,禁止日志或响应中输出明文密码。
- 生产环境必须修改 `SECRET_KEY`,勿提交 `.env`。