feat(server): Web 服务化(FastAPI + SQLite + 内嵌零构建前端)
参赛成果物 03「交互界面 + 数据存储」落地:
- src/genesis/server/: store.py(SQLite 会话持久化)、service.py(会话化服务层:
上传→解析→确认→影响→确认→生成→QA)、app.py(api-design §2 核心端点 9 组)、
static/index.html(内嵌单页,零构建无 node_modules 依赖)
- scripts/serve.py 启动入口(--fake 离线引擎 / 默认真实 LLM)
- pyproject 加 fastapi/uvicorn/python-multipart
- 修复 qa_loop._build meta={} 导致真实模板 {{doc_title}} 等占位符残留 DocxInjectError
- README Web 服务说明 + service_url 登记指引;design.md §12.5 记录(含同步执行/
zip 既有系统/无 WebSocket 的诚实偏差标注)
- 测试:test_server_store/service/api 共 34 用例(TestClient 全链路 + zip 影响流程 + 错误分支)
全量 pytest 473 passed / 99.20%
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
"""Web 服务启动入口(S5)。
|
||||
|
||||
用法:
|
||||
python scripts/serve.py [--host 0.0.0.0] [--port 8000] [--fake]
|
||||
|
||||
- 默认真实 LLM 模式(需 .env 配置 GENESIS_INFERENCE__API_KEY,generate 时按需加载)
|
||||
- --fake 为离线确定性引擎(无需 key,适合评审演示环境)
|
||||
- 会话/文件/结果存储于 data/server/(SQLite + 上传快照,不入库)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
if str(ROOT / "src") not in sys.path:
|
||||
sys.path.insert(0, str(ROOT / "src"))
|
||||
|
||||
import uvicorn # noqa: E402
|
||||
|
||||
from genesis.server.app import create_app # noqa: E402
|
||||
|
||||
|
||||
def main() -> None:
|
||||
p = argparse.ArgumentParser(description="Genesis Web 服务")
|
||||
p.add_argument("--host", default="127.0.0.1")
|
||||
p.add_argument("--port", type=int, default=8000)
|
||||
p.add_argument("--fake", action="store_true", help="离线 Fake 引擎(无需 API key)")
|
||||
p.add_argument("--data-root", default=str(ROOT / "data" / "server"), help="会话/文件/结果存储目录")
|
||||
args = p.parse_args()
|
||||
|
||||
app = create_app(data_root=args.data_root, engine="fake" if args.fake else None)
|
||||
print(f"Genesis Web 服务启动: http://{args.host}:{args.port} (mode={'fake' if args.fake else 'real'})")
|
||||
uvicorn.run(app, host=args.host, port=args.port)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user