Spaces:
Running
Running
| title: XTC Backend | |
| emoji: 🚀 | |
| colorFrom: gray | |
| colorTo: indigo | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| # XTC Backend (Hugging Face 版) | |
| 从 Netlify 版迁移而来的 OpenAI / Gemini 兼容网关,部署到 Hugging Face Spaces。 | |
| > **重要**:本目录是迁移重写版,原 Netlify 后端代码保留在 `../openai-gemini-main-master/` 作为备用,未被覆盖。 | |
| ## 目录结构 | |
| ``` | |
| xtc-backend-hf/ | |
| ├── Dockerfile # HF Spaces Docker 镜像 | |
| ├── requirements.txt # Python 依赖 | |
| ├── .env.example # 环境变量样例 | |
| ├── app/ | |
| │ ├── main.py # FastAPI 应用装配 | |
| │ ├── config.py # 环境变量配置(pydantic-settings) | |
| │ ├── errors.py # 统一错误模型(兼容前端契约) | |
| │ ├── auth.py # access_key + JWT 临时令牌 | |
| │ ├── database.py # SQLite 初始化 | |
| │ ├── cache.py # 模型列表 TTL 缓存 | |
| │ ├── http_client.py # httpx 全局连接池 | |
| │ ├── admin_html.py # 后台 HTML(占位版) | |
| │ ├── api/ # FastAPI 路由 | |
| │ │ ├── health.py # /health | |
| │ │ ├── openai_compat.py# /v1/chat/completions /v1/embeddings /v1/models | |
| │ │ ├── xtc.py # /v1/xtc/providers /v1/xtc/models /v1/xtc/chat | |
| │ │ ├── pseudo_stream.py# /v1/xtc/chat/pseudo/start /v1/xtc/chat/pseudo/poll | |
| │ │ ├── image_fix.py # /v1/xtc/image/fix/test | |
| │ │ ├── admin.py # /admin/api/* | |
| │ │ ├── logs.py # /logs/api/*(合并原 xtc-log-receiver) | |
| │ │ └── _common.py # 共享工具 | |
| │ ├── adapters/ # 上游适配器 | |
| │ │ ├── gemini_api.py # Gemini 总入口 | |
| │ │ ├── openai.py # OpenAI 兼容透传 | |
| │ │ └── gemini/ # Gemini→OpenAI 转换子模块 | |
| │ │ ├── messages.py # messages ↔ contents | |
| │ │ ├── config.py # generation params | |
| │ │ ├── tools.py # tools / tool_choice | |
| │ │ ├── response.py # 非流式响应转换 | |
| │ │ └── stream.py # 流式 chunk 转换 | |
| │ ├── providers/ # 厂商解析与策略 | |
| │ │ ├── resolver.py # 解析厂商 | |
| │ │ ├── keypool.py # 多密钥轮询(持久化) | |
| │ │ └── policy.py # 白/黑名单 + glob | |
| │ ├── media/imagefix.py # 图片修正(Pillow) | |
| │ ├── models/config.py # Provider / AppConfig 数据模型 | |
| │ ├── services/ # 业务服务 | |
| │ │ ├── config_store.py # 配置存储(SQLite + HF Hub 同步) | |
| │ │ └── pseudo_store.py # 伪流式会话存储 | |
| │ └── utils/ # 工具 | |
| │ ├── thought.py # 思考链抽取 | |
| │ └── sse.py # SSE 解析 | |
| └── README.md | |
| ``` | |
| ## 与原 Netlify 版的差异 | |
| ### 简化(砍掉的复杂度) | |
| | 简化项 | 原因 | | |
| |---|---| | |
| | 环境变量配厂商(`XTC_PROVIDER_1_*` ... `XTC_PROVIDER_12_*`) | 后端有数据库,Admin API 直接写 | | |
| | 配置加密 `XTC_CONFIG_CRYPT_KEY` / `enc:v1:` | HF Secrets 加密 + 私有 Hub 仓库 + 容器内 SQLite 已够安全 | | |
| | `XTC_CONFIG_ENV_ONLY` / `XTC_ADMIN_REQUIRE_KEY_ON_PAGE` | 改用 JWT 登录态 | | |
| | `XTC_ACCESS_SHORT_KEY` / `XTC_ACCESS_PIN` | JWT 令牌已足够 | | |
| | 多平台入口(6 个) | 只跑 HF Docker | | |
| | Edge 路径 `/edge/*` | 无 Edge 概念 | | |
| | `runtimeEnv` + `process.env` + `Deno.env` 三段式 | 只用 `os.environ` | | |
| ### 保留(兼容契约,前端零改动) | |
| - OpenAI 兼容三件套:`/v1/chat/completions`、`/v1/embeddings`、`/v1/models` | |
| - XTC 简化接口:`/v1/xtc/providers`、`/v1/xtc/models`、`/v1/xtc/chat`、`/v1/xtc/chat/pseudo/*`、`/v1/xtc/image/fix/test` | |
| - 错误响应格式:`{ ok:false, error:{ code, message, status, retryable, hint, upstream?, details? } }` | |
| - 错误码集合:`bad_request/unauthorized/forbidden/not_found/request_timeout/quota_exceeded/internal_error/service_unavailable/upstream_timeout/model_disabled/server_misconfigured` | |
| - 图片修正三模式:`mirror_h` / `rotate_180` / `mirror_h_rotate_180` | |
| - 流式协议:OpenAI SSE、`stream_mode: simple`、伪流式 | |
| - 响应头:`x-xtc-provider` / `x-xtc-model` / `x-xtc-image-fix-mode` | |
| - Admin API 全部端点 | |
| ### 新增 | |
| - HF Hub 仓库配置同步(`HF_TOKEN` + `HF_CONFIG_REPO`) | |
| - JWT 临时令牌(替代内存 Map,多实例可用) | |
| - 多密钥 RR 计数器持久化到 SQLite | |
| - 伪流式会话存 SQLite(替代 Netlify Blobs) | |
| - 日志接收合并进主服务(`/logs/api/*`) | |
| - 用量统计表(`usage_log`) | |
| - 审计日志表(`audit_log`) | |
| ## 环境变量 | |
| 参考 [.env.example](file:///workspace/xtc-backend-hf/.env.example)。必填: | |
| - `XTC_ADMIN_KEY`:后台登录密钥 | |
| - `XTC_ACCESS_KEY`:前端长期密钥 | |
| - `XTC_JWT_SECRET`:JWT 签名密钥(签发临时令牌用) | |
| 可选种子(首次启动初始化): | |
| - `GEMINI_API_KEY` / `GEMINI_API_KEYS`(逗号分隔多 key) | |
| - `OPENAI_API_KEY` / `OPENAI_API_KEYS` | |
| - `OPENAI_BASE_URL` | |
| 可选 HF Hub 同步: | |
| - `HF_TOKEN`:访问 Hub 仓库的令牌 | |
| - `HF_CONFIG_REPO`:仓库名(如 `your-username/xtc-config`,建议设为 dataset 私有仓库) | |
| ## 本地运行 | |
| ```bash | |
| cd xtc-backend-hf | |
| python -m venv .venv && source .venv/bin/activate | |
| pip install -r requirements.txt | |
| pip install pillow-heif # 可选,HEIC 解码 | |
| # 配置环境变量 | |
| cp .env.example .env | |
| # 编辑 .env 设置 XTC_ADMIN_KEY / XTC_ACCESS_KEY / XTC_JWT_SECRET | |
| # 启动 | |
| uvicorn app.main:app --host 0.0.0.0 --port 7860 --reload | |
| ``` | |
| 访问: | |
| - 健康检查:http://localhost:7860/health | |
| - 后台:http://localhost:7860/admin | |
| - API 文档:http://localhost:7860/docs | |
| ## 部署到 Hugging Face Spaces | |
| 1. 在 HF 创建一个 **Docker SDK** 类型的 Space(私有推荐) | |
| 2. 在 Space Settings → Repository secrets 添加环境变量: | |
| - `XTC_ADMIN_KEY`、`XTC_ACCESS_KEY`、`XTC_JWT_SECRET` | |
| - 可选:`GEMINI_API_KEY`、`OPENAI_API_KEY`、`HF_TOKEN`、`HF_CONFIG_REPO` | |
| 3. 把本目录所有文件上传到 Space 仓库根目录(或用 GitHub Actions 同步) | |
| 4. HF 自动构建并启动,访问 `https://<space-name>.hf.space` | |
| ## 国内访问与保活(Cloudflare Workers 反代) | |
| ```javascript | |
| // CF Workers 脚本 | |
| addEventListener("fetch", e => e.respondWith(handle(e.request))); | |
| addEventListener("scheduled", e => e.waitUntil(keepalive())); | |
| const UPSTREAM = "https://your-space.hf.space"; | |
| async function handle(req) { | |
| const url = new URL(req.url); | |
| const upstream = new URL(UPSTREAM + url.pathname + url.search); | |
| const resp = await fetch(upstream, { | |
| method: req.method, headers: req.headers, body: req.body, | |
| }); | |
| return new Response(resp.body, resp); | |
| } | |
| async function keepalive() { | |
| try { await fetch(UPSTREAM + "/health"); } catch (e) {} | |
| } | |
| ``` | |
| 在 `wrangler.toml` 配置 Cron Triggers(每 24 小时一次): | |
| ```toml | |
| [triggers] | |
| crons = ["0 */24 * * *"] | |
| ``` | |
| ## 接口契约速查 | |
| ### OpenAI 兼容 | |
| ``` | |
| POST /v1/chat/completions # 头部 Authorization: Bearer <key> 或 x-xtc-access-key | |
| POST /v1/embeddings | |
| GET /v1/models | |
| ``` | |
| ### XTC 简化 | |
| ``` | |
| GET /v1/xtc/providers # { ok, defaultProviderId, providers[], count } | |
| GET /v1/xtc/models?provider=&all=1 # { ok, provider, models[], count } | |
| POST /v1/xtc/chat # 见下方字段 | |
| POST /v1/xtc/chat/pseudo/start # { ok, session_id, provider, model } | |
| GET|POST /v1/xtc/chat/pseudo/poll # { ok, status, deltas[], cursor, expires_in_sec } | |
| POST /v1/xtc/image/fix/test # 返回 PNG 二进制 | |
| ``` | |
| `/v1/xtc/chat` 成功响应: | |
| ```json | |
| { | |
| "ok": true, | |
| "provider": "gemini", | |
| "model": "gemini-2.5-flash", | |
| "thought": "...", | |
| "text": "...", | |
| "raw": "...", | |
| "usage": {}, | |
| "warning": "(可选)图片修正失败提示", | |
| "image_fix_mode": "mirror_h", | |
| "image_fixed": true, | |
| "image_fix_failed_count": 0, | |
| "image_camera_facing": "front" | |
| } | |
| ``` | |
| ### Admin API | |
| ``` | |
| POST /admin/api/login | |
| POST /admin/api/xtc-access-token | |
| GET /admin/api/tokens # 新增 | |
| POST /admin/api/tokens/revoke # 新增 | |
| GET /admin/api/config | |
| PUT /admin/api/config | |
| GET /admin/api/providers | |
| POST /admin/api/providers | |
| DELETE /admin/api/providers?id= | |
| GET /admin/api/provider-models?id= | |
| POST /admin/api/provider-settings | |
| POST /admin/api/default-provider | |
| POST /admin/api/test-chat | |
| ``` | |
| ### 日志(合并自 xtc-log-receiver) | |
| ``` | |
| POST /logs/api/log | |
| POST /logs/api/log/batch | |
| GET /logs/api/stats?hours=24 # admin | |
| GET /logs/api/logs?hours=24&level=&limit= # admin | |
| ``` | |
| ## 后续阶段 | |
| 本版仅完成 MVP(核心接口迁移),后续阶段: | |
| 1. **阶段 2**:Vue 3 SPA 重写后台(替换占位 HTML),加用量统计仪表盘、模型策略可视化 | |
| 2. **阶段 3**:HF Hub 多实例同步增强、Webhook 通知、速率限制 | |
| 3. **阶段 4**:会话持久化、文件解析(PDF/Word)、模型路由策略、RAG | |
| 详见 `../openai-gemini-main-master/迁移到HuggingFace分析报告.md`。 | |