feat(web): FastAPI 脚手架(strangler 迁移起点)

新增 web/ 包,与 Flask 应用并存、共享 core/:
- web/app.py     create_app 工厂;已迁移路由挂 /api/v1,可挂遗留 Flask 兜底
- web/main.py    uvicorn 入口(sys.path 补项目根)
- web/response.py 响应工具,与 Flask APIResponse 的 JSON 契约逐字段对齐
- web/routers/system.py 迁移样板:/api/v1/health、/api/v1/api/info
- requirements-fastapi.txt 迁移目标依赖(不影响当前生产 Flask 部署)

验证:
- 奇偶校验(.zcode/refactor/parity.py)Flask /health vs FastAPI /api/v1/health、
  /api/info vs /api/v1/api/info —— 状态码/顶层键/响应体全一致
- uvicorn 真实启动 200;Flask fallback 挂载下 /api/v1/* 走 FastAPI、/* 走 Flask 同为 200

当前仅样板端点;生产服务器切换与状态统一见后续迁移阶段。
This commit is contained in:
snowy-yang committed 2026-09-26 00:17:56 +08:00
1 parent c2a8da3e43
commit 41356e89c4
7 files changed
+198

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
"""响应工具:与 Flask 侧 APIResponse 的 JSON 契约逐字段对齐。
Flask 的 APIResponse.success/error 返回 (dict, status) 元组,由 Flask 序列化。
FastAPI 侧改为直接返回 JSONResponse,但**包体结构完全一致**:
success: {"status": sc, "success": true, "message": msg, ["data": ...]}
error: {"status": sc, "success": false, "message": msg, ["error_code": ...]}
这样前端无需任何改动即可同时对接两个框架。
"""
from typing import Any
from fastapi.responses import JSONResponse
def success(data: Any = None, message: str = 'success', status_code: int = 200) -> JSONResponse:
"""成功响应(对应 Flask APIResponse.success)"""
body = {
'status': status_code,
'success': True,
'message': message,
}
if data is not None:
body['data'] = data
return JSONResponse(content=body, status_code=status_code)
def error(message: str, status_code: int = 400, error_code: str = None) -> JSONResponse:
"""错误响应(对应 Flask APIResponse.error)"""
body = {
'status': status_code,
'success': False,
'message': message,
}
if error_code:
body['error_code'] = error_code
return JSONResponse(content=body, status_code=status_code)