86 lines
4.5 KiB
Markdown
86 lines
4.5 KiB
Markdown
|
|
# TraceStudio — 服务器代码风格与工程约定
|
|||
|
|
|
|||
|
|
本文档为后端(`server/`)代码库的风格指南与工程约定,目的是保证多人协作时代码一致性、可维护性与安全性。遵循本指南可简化静态分析、代码审查和自动化测试。
|
|||
|
|
|
|||
|
|
**适用范围**
|
|||
|
|
- 路径: `server/`, `server/app/`, 以及与后端紧密相关的自定义节点目录 `server/custom_nodes/`。
|
|||
|
|
- 语言: Python 3.11+
|
|||
|
|
|
|||
|
|
**一、总体原则**
|
|||
|
|
- 简洁明确: 优先清晰可读的实现,避免过度抽象。
|
|||
|
|
- 明确契约: 所有 HTTP 接口应使用 Pydantic 模型定义输入/输出契约。
|
|||
|
|
- 安全优先: 文件路径、上传、代码执行(自定义节点)必须进行严格校验与最小权限操作。
|
|||
|
|
|
|||
|
|
**二、代码风格**
|
|||
|
|
- 遵循 PEP8,并在提交前运行 `ruff`(用于 lint)和 `black`(用于格式化)。
|
|||
|
|
- 类型注解: 函数与公有接口应使用类型注解;异步函数使用 `async def` 并返回具体类型或 `-> Any`。
|
|||
|
|
- 命名约定:
|
|||
|
|
- 文件/模块: `snake_case.py`
|
|||
|
|
- 类: `PascalCase`
|
|||
|
|
- 变量/函数: `snake_case`
|
|||
|
|
- 常量: `UPPER_SNAKE`
|
|||
|
|
- 日志与调试: 使用 `logging` 模块,避免 `print`(仅在开发脚本或 CLI 初始化中短期使用)。
|
|||
|
|
|
|||
|
|
**三、项目结构与职责**
|
|||
|
|
- `server/main.py`: 应只负责应用初始化(FastAPI app 创建、CORS、路由 include、startup/shutdown 事件注册)。
|
|||
|
|
- `server/app/api/`: 放置所有路由文件(按功能分组,例如 `endpoints_upload.py`, `endpoints_graph.py`, `endpoints_custom_nodes.py`)。每个路由文件应只包含路由及与路由相关的轻量逻辑,复杂逻辑放在 `app/core/`。
|
|||
|
|
- `server/app/core/`: 核心服务、执行器、节点实现与工具函数。该目录应是无外部 HTTP 依赖的纯 Python 逻辑,便于单元测试。
|
|||
|
|
- `cloud/custom_nodes/`: 用户可编辑的自定义节点放置处。该目录需要单独的安全扫描与备份策略。
|
|||
|
|
|
|||
|
|
**四、API 与模型约定**
|
|||
|
|
- 使用 `pydantic.BaseModel` 定义请求体与响应模型。保持模型命名清晰(例如 `NodeSchema`, `GraphExecuteRequest`, `FileInfo`)。
|
|||
|
|
- 在 router 函数中对外只返回标准 JSON 可序列化类型;遇到复杂对象(如 Polars DataFrame)应转换为带 `__type` 标记的序列化对象。
|
|||
|
|
|
|||
|
|
示例约定:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
from pydantic import BaseModel
|
|||
|
|
|
|||
|
|
class FileInfo(BaseModel):
|
|||
|
|
name: str
|
|||
|
|
path: str
|
|||
|
|
type: str
|
|||
|
|
size: Optional[int]
|
|||
|
|
|
|||
|
|
@router.get('/files/info')
|
|||
|
|
async def get_file_info(path: str) -> FileInfo:
|
|||
|
|
...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**五、异步与并发**
|
|||
|
|
- 网络 I/O(文件流、上传/下载、数据库调用)优先使用 `async`/`await`。
|
|||
|
|
- CPU 密集型操作(大规模数据处理)应移到后台任务或使用专门进程/线程池(例如 `concurrent.futures.ProcessPoolExecutor`),避免阻塞事件循环。
|
|||
|
|
|
|||
|
|
**六、安全策略**
|
|||
|
|
- 所有外部路径输入必须被 `sanitize_path`(规范化)并通过 `is_safe_path` / `NodeValidator.is_safe_filename` 验证。
|
|||
|
|
- 自定义节点代码在保存或上传时应做静态分析(`validate_node_code`),并在加载前备份旧版本。
|
|||
|
|
- 严禁在未经批准的上下文中直接执行用户上传的 Python 代码,运行时应该有沙箱、权限限制或审计日志(当前实现为“可加载但需谨慎”)。
|
|||
|
|
|
|||
|
|
**七、测试与 CI**
|
|||
|
|
- 单元测试: 把纯逻辑放在 `server/app/core/` 以利于测试,使用 `pytest` 编写测试(目录: `server/tests/`)。
|
|||
|
|
- 集成测试: 提供针对主要路由的集成测试,使用 `httpx.AsyncClient` 或直接调用 FastAPI 的 TestClient。
|
|||
|
|
- 建议在 CI 中运行命令:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
pip install -r server/requirements.txt
|
|||
|
|
ruff check server --fix
|
|||
|
|
black server
|
|||
|
|
pytest -q
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**八、依赖管理与运行**
|
|||
|
|
- 使用 `requirements.txt`(已在 `server/requirements.txt`)或 `pyproject.toml` + `poetry` 管理依赖。
|
|||
|
|
- 推荐在 Conda 环境中使用 Python 3.11(项目 README 已包含样例启动脚本 `start.ps1`)。
|
|||
|
|
|
|||
|
|
**九、日志与监控**
|
|||
|
|
- 使用 `logging` 且在 `main.py` 中配置基本 logger(分级输出到控制台,生产建议使用文件/外部日志服务)。
|
|||
|
|
- 在关键操作(文件上传、节点加载、工作流执行)中加入审计日志(包含 user, filename, action, timestamp)。
|
|||
|
|
|
|||
|
|
**十、文档与开发者体验**
|
|||
|
|
- 所有公共函数与类应有 docstring,API 路由中应包含简短注释(目的、参数、错误码)。
|
|||
|
|
- 在 `docs/` 下维护 API 文档(已生成 `docs/server/api.md`)和代码风格文档。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
文件: [server/main.py](server/main.py#L1-L1)
|