ohmyapi commited on
Commit
8b4dc02
·
verified ·
1 Parent(s): 888cccd

Polish README for simple-mode HF deployment

Browse files
Files changed (1) hide show
  1. README.md +103 -79
README.md CHANGED
@@ -12,31 +12,52 @@ pinned: false
12
 
13
  当前 Space:<https://ohmyapi-c2api.hf.space>
14
 
15
- 这是一个基于 `pushzx/claude2api:latest` 的 Hugging Face Docker Space 包装层。它的目标很克制:
16
 
17
- - 让根路径 `/` 直接进入管理登录页 `/admin/login`
18
  - 保持 `/admin`、`/health`、`/v1/*` 等能力继续由上游 `claude2api` 提供
19
- - 不在 wrapper 层伪造持久化配置语义
20
 
21
- ## 当前访问行为
22
 
23
- 当前 Space 是 **public Space**,不是 private Space
24
 
25
- 这意味着
 
 
 
 
26
 
27
- - Hugging Face 本身**会**先拦住外部访问者
28
- - 任何人都可以直接访问 `https://ohmyapi-c2api.hf.space/`
29
- - 当前根路径会被 wrapper 直接 `302` 到 `/admin/login`
30
- - API 是否需要鉴权,取决于上游 `claude2api` 是否读取到了 `CLAUDE_API_KEY`
 
31
 
32
  当前线上已验证:
33
 
34
  - `/` → `302 /admin/login`
35
  - `/admin/login` 可正常打开
36
  - `/health` 返回 `200`
37
- - `/v1/models` 可正常访问
38
  - `/v1/messages` 未带正确 token 时返回 `401 Invalid API key`
39
- - 带正确 app token 时,`claude-sonnet-4-6` 已成功完成一次实际调用
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  ## 为什么 Hugging Face 环境变量能直接生效
42
 
@@ -47,7 +68,7 @@ Hugging Face 对 Docker Space 的处理方式不是“把变量写进仓库文
47
  - **Variables**
48
  - **Secrets**
49
 
50
- 作为真实运行时环境变量注入到容器进程里
51
 
52
  对这个仓库来说,等价于容器启动时直接拿到了例如:
53
 
@@ -59,7 +80,7 @@ ADMIN_PASS=...
59
  CLAUDE_SESSION_KEYS=...
60
  ```
61
 
62
- 所以只要上游 `claude2api` 在启动时通过 `os.Getenv(...)` 之类的方式读配置,它就会直接生效,不需要额外写入 `.env`、`config.yaml` 或别的文件。
63
 
64
  ### 当前已确认的 Space Variables
65
 
@@ -72,9 +93,9 @@ ADMIN_USER=admin
72
 
73
  Secrets 不会被 Hugging Face API 直接回显,但从线上行为可以确认至少存在并已生效:
74
 
75
- - `CLAUDE_API_KEY`:因为未带 token 调用 `/v1/messages` 会返回 `401 Invalid API key`
76
- - `CLAUDE_SESSION_KEYS`:因为模型已能实际完成调用
77
- - `ADMIN_PASS`:因为管理页已处于登录保护下
78
 
79
  ## 当前 wrapper 做了什么
80
 
@@ -92,73 +113,45 @@ Secrets 不会被 Hugging Face API 直接回显,但从线上行为可以确认
92
  - 现在用户访问根路径时,会直接进入真实可用的登录入口
93
  - 同时不需要去改上游镜像源码
94
 
95
- ## 当前是否配置了 PostgreSQL 持久化存储
96
 
97
  ### 结论
98
 
99
  **按当前已验证状态,不能认为这个 Space 已经配置并启用了 PostgreSQL 持久化存储。**
100
 
101
- 虽然你提供了这个 Neon 连接串:
102
-
103
- ```text
104
- postgresql://neondb_owner:npg_EhvAUwfT1Q0s@ep-late-sun-a4w4w406-pooler.us-east-1.aws.neon.tech/neondb?sslmode=require&channel_binding=require
105
- ```
106
-
107
- 但就目前线上可确认的信息来看,还不能据此得出“当前 Space 正在用 PostgreSQL 持久化”的结论。
108
 
109
  ### 原因
110
 
111
- 1. 当前 wrapper 仓库本身并没有把这个连接串写入任何被跟踪文件
112
- 2. Hugging Face 公开可读到的 Variables 里没有 `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_PASS` / `DB_NAME`
113
- 3. Secrets 无法通过公开 API 直接读出所以我不仅靠外部观察断言你已经Neon 连接串拆分后放进了 Space Secrets。
114
- 4. 当前线上已观察到的配置行为更像是:
115
- - 上游成功读取了 `CLAUDE_SESSION_KEYS`
116
- - 并使用 simple mode 就能完成调用
117
- 5. 之前的运行时验证还显示:
118
- - admin UI 中修改的 `api_key` 只在当前进程有效
119
- - 重启后回退到启动环境变量值
120
- 这也**不支持**“当前已经有稳定的持久化配置优先层”这一判断。
121
-
122
- ### 如果要真正启用 PostgreSQL
123
-
124
- 需要满足两个条件:
125
 
126
- 1. 上游 `claude2api` 本身支持通过环境变量连接外部 PostgreSQL
127
- 2. 你把对应数据库配置真实放进了 Hugging Face Space Secrets / Variables
 
128
 
129
- 个仓库现有文档,通常是:
 
130
 
131
- ```env
132
- DB_HOST=ep-late-sun-a4w4w406-pooler.us-east-1.aws.neon.tech
133
- DB_PORT=5432
134
- DB_USER=neondb_owner
135
- DB_PASS=...实际密码...
136
- DB_NAME=neondb
137
- ```
138
 
139
- 注意
140
 
141
- - 不能直接把完整连接串当成 `DB_HOST`
142
- - 当前 `.env.example` / README 的接口更偏向拆分字段,而不是单个 `DATABASE_URL`
143
- - 如果上游源码实际上不支持 Neon 这种外部 PG 持久化路径,或者虽然支持 PG 但启动优先级仍是 env 覆盖 runtime state,那么依然达不到你想要的“persisted-first”语义
144
 
145
- ## 关于 admin password / auth token 持久化的当前结论
 
 
146
 
147
- 目前已做过的验证结论是
148
 
149
- - `api_key` 可以在当前运行期通过管理接口并立即影响鉴权结果
150
- - 但容器重启后,会回退到启动环境变量 / HF Secrets
151
- - `admin_pass` 目前看**不能**通过现有 settings 路径真正更新生效
152
-
153
- 所以当前更准确的理解是:
154
-
155
- - Hugging Face Secrets / Variables = **启动配置源**
156
- - 上游 admin UI 的部分设置 = **运行期状态修改**
157
- - 两者目前**不是**一个可自动回写、可稳定持久继承的统一配置层
158
 
159
  ## 当前推荐的线上配置思路
160
 
161
- 如果你只是想把 Space 稳定跑起来:
162
 
163
  ### 必要 Secrets
164
 
@@ -173,22 +166,51 @@ LISTEN_ADDR=:7860
173
  ADMIN_USER=admin
174
  ```
175
 
176
- ### 如果后续要尝试 PostgreSQL 持久化
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
- 请单独把它当成一次上游运行时验证任务,而不是继续在 wrapper 层假设它已经存在。
 
 
179
 
180
- 建议验证顺序
181
 
182
- 1. Space Secrets / Variables 中补齐真实 DB 配置
183
- 2. 重启 Space
184
- 3. 通 admin UI 修改一个可观测配置
185
- 4. 再次重启 Space
186
- 5. 验证该配置是否仍然生效
187
- 6. 验证生效值底来自:
188
- - PostgreSQL 持久化层
189
- - 还是 HF Secrets / env
190
 
191
- 只有这组验证跑通后,才能把“已启用 PostgreSQL 持久化”写成正式能力。
 
 
 
 
192
 
193
  ## 当前仓库文件职责
194
 
@@ -203,7 +225,9 @@ ADMIN_USER=admin
203
  ```bash
204
  curl -I https://ohmyapi-c2api.hf.space/
205
  curl https://ohmyapi-c2api.hf.space/health
206
- curl https://ohmyapi-c2api.hf.space/v1/models
 
 
207
 
208
  curl https://ohmyapi-c2api.hf.space/v1/messages \
209
  -H "Content-Type: application/json" \
@@ -215,4 +239,4 @@ curl https://ohmyapi-c2api.hf.space/v1/messages \
215
  }'
216
  ```
217
 
218
- 如果最后一条返回正常消息体,就说明当前公开 Space、app token、以及 Claude session 这三层链路都已经打通。
 
12
 
13
  当前 Space:<https://ohmyapi-c2api.hf.space>
14
 
15
+ 这是一个围绕 `pushzx/claude2api:latest` 的 Hugging Face Docker Space 包装层。目标很克制:
16
 
17
+ - 让根路径 `/` 直接进入真实可用的管理登录页 `/admin/login`
18
  - 保持 `/admin`、`/health`、`/v1/*` 等能力继续由上游 `claude2api` 提供
19
+ - wrapper 只处理入口体验与反代,不在外层伪造持久化配置语义
20
 
21
+ ## 当前部署状态
22
 
23
+ 当前线上状态已经收敛为 **public Space + simple mode**
24
 
25
+ - Space 类型**public Space**
26
+ - 运行模式:**simple mode**
27
+ - 当前不启用 DB-backed 持久化
28
+ - 当前已从 Space Secrets 中移除:`DB_HOST`、`DB_PORT`、`DB_USER`、`DB_PASS`、`DB_NAME`、`PGSSLMODE`
29
+ - 当前根路径 `/` 会直接 `302` 到 `/admin/login`
30
 
31
+ 这样收敛的原因很明确:simple mode 已经稳定可用,而当前上游镜像的 DB-only 路径对 Neon / Supabase 这类强制 TLS 的托管 PostgreSQL 仍未验证通过,能在这里把它写成现成功能。
32
+
33
+ ## 当前访问行为
34
+
35
+ public Space 的含义是:**入口默认公开**,不是 **Secrets 自动公开**。
36
 
37
  当前线上已验证:
38
 
39
  - `/` → `302 /admin/login`
40
  - `/admin/login` 可正常打开
41
  - `/health` 返回 `200`
 
42
  - `/v1/messages` 未带正确 token 时返回 `401 Invalid API key`
43
+ - 带正确 app token 时,`claude-sonnet-4-6` 已成功完成实际调用
44
+ - `/v1/models` 可在带 token 的情况下返回模型列表
45
+
46
+ ## public Space 的风险边界
47
+
48
+ public Space 不会因为是 public 就把 Hugging Face Secrets 直接暴露出来,但它会让你的入口地址处于公网可探测状态。
49
+
50
+ 这意味着:
51
+
52
+ - `https://ohmyapi-c2api.hf.space/` 这类地址任何人都能访问与探测
53
+ - Hugging Face Space Secrets **不会**被页面或公开 API 直接回显
54
+ - 真正更常见的泄露面是:把 token / session 写进仓库文件、前端页面、日志、导出的配置或本机历史文件
55
+ - public Space 是否安全,关键不在于“是否 public”,而在于:
56
+ - app 自身接口是否强制鉴权
57
+ - `CLAUDE_API_KEY` / `CLAUDE_SESSION_KEYS` 是否只保留在服务端运行时环境
58
+ - 仓库与页面输出里是否完全不出现真实 secret
59
+
60
+ 换句话说,public Space **不会自动泄露 session**,但如果 app token 泄露、接口未加保护,别人就能直接消费你的服务。
61
 
62
  ## 为什么 Hugging Face 环境变量能直接生效
63
 
 
68
  - **Variables**
69
  - **Secrets**
70
 
71
+ 直接注入成容器进程的真实运行时环境变量。
72
 
73
  对这个仓库来说,等价于容器启动时直接拿到了例如:
74
 
 
80
  CLAUDE_SESSION_KEYS=...
81
  ```
82
 
83
+ 因此,只要上游 `claude2api` 在启动时通过 `os.Getenv(...)` 或等价方式读配置,它就会直接生效,不需要额外写入 `.env`、`config.yaml` 或其它文件。
84
 
85
  ### 当前已确认的 Space Variables
86
 
 
93
 
94
  Secrets 不会被 Hugging Face API 直接回显,但从线上行为可以确认至少存在并已生效:
95
 
96
+ - `CLAUDE_API_KEY`
97
+ - `CLAUDE_SESSION_KEYS`
98
+ - `ADMIN_PASS`
99
 
100
  ## 当前 wrapper 做了什么
101
 
 
113
  - 现在用户访问根路径时,会直接进入真实可用的登录入口
114
  - 同时不需要去改上游镜像源码
115
 
116
+ ## 当前为什么不启用 PostgreSQL 持久化
117
 
118
  ### 结论
119
 
120
  **按当前已验证状态,不能认为这个 Space 已经配置并启用了 PostgreSQL 持久化存储。**
121
 
122
+ 更准确地说:当前线上已经明确收敛为 **simple mode only**,不是“正在尝试 DB-only 但尚未成功”。
 
 
 
 
 
 
123
 
124
  ### 原因
125
 
126
+ 1. 只要存在 `CLAUDE_SESSION_KEYS`,上游就可以走 simple mode,并且当前已验证可稳定提供 API 能力
127
+ 2. 当前 Hugging Face Space runtime 已确认 `storage.current = None` `storage.requested = None`,因此容器内本地 PostgreSQL 不能视为正式持久化层
128
+ 3. 对当前上游镜像的排查显示DB-only 路径很可PostgreSQL DSN 拼成:
 
 
 
 
 
 
 
 
 
 
 
129
 
130
+ ```text
131
+ host=%s port=%s user=%s password=%s dbname=%s sslmode=disable
132
+ ```
133
 
134
+ 会与 Neon / Supabase 这类强制 TLS 的托管 PostgreSQL 冲突。
135
+ 4. 因此,即使文档里存在“可连接外部数据库”的描述,也不能把它等同于“当前镜像已支持外部托管 PG 持久化”。
136
 
137
+ ### 为什么 local PostgreSQL 不能当成 HF 持久化
 
 
 
 
 
 
138
 
139
+ 如果你打算在 Hugging Face Space 容器里直接放一个“本地 PostgreSQL”,要先明确一件事**默认情况下,这不等于可靠持久化。**
140
 
141
+ 原因是:
 
 
142
 
143
+ 1. Docker Space 默认使用的是容器自身的可写层,而不是天然持久卷。
144
+ 2. 如果没有单独申请 Hugging Face persistent storage,并把数据库目录明确挂到持久路径,本地 PG 数据在 restart / rebuild / redeploy 后都可能丢失。
145
+ 3. 当前这个 Space 没有启用 persistent storage,因此“容器内本地 PG”不能当成正式配置持久化方案。
146
 
147
+ 因此
148
 
149
+ - 本地 PG 适合临时调试不适合承担当前 Space 的正式配置持久化
150
+ - 真正需要稳定持久化,应优先使用外部 PostgreSQL,或者先补齐 HF persistent storage,再验证上游是否支持对应数据目录语义
 
 
 
 
 
 
 
151
 
152
  ## 当前推荐的线上配置思路
153
 
154
+ 如果你只是想把 Space 稳定跑起来,当前推荐就是保持 simple mode
155
 
156
  ### 必要 Secrets
157
 
 
166
  ADMIN_USER=admin
167
  ```
168
 
169
+ ### 当前不启用的配置
170
+
171
+ 以下 DB 相关项当前视为**暂不启用**,不要再把它们当成线上必需配置:
172
+
173
+ - `DB_HOST`
174
+ - `DB_PORT`
175
+ - `DB_USER`
176
+ - `DB_PASS`
177
+ - `DB_NAME`
178
+ - `PGSSLMODE`
179
+
180
+ ## 当前已验证可调用的模型
181
+
182
+ 带正确 app token 时,以下模型已通过真实 `/v1/messages` 请求验证,可以正常返回结果:
183
+
184
+ - `claude-sonnet-4-5`
185
+ - `claude-haiku-4-5`
186
+ - `claude-sonnet-4-6`
187
+ - `claude-haiku-4-6`
188
+ - `claude-3-5-sonnet-20241022`
189
+ - `claude-3-5-haiku-20241022`
190
+ - `claude-3-sonnet-20240229`
191
+ - `claude-3-haiku-20240307`
192
+
193
+ 以下模型虽然会出现在 `/v1/models` 列表里,但当前实测返回的是 `403 model_not_available`:
194
 
195
+ - `claude-opus-4-5`
196
+ - `claude-opus-4-6`
197
+ - `claude-3-opus-20240229`
198
 
199
+ 这也说明一件事**`/v1/models` 返回的是“当前镜像声明支持的模型列表”,真正能否调用仍然取决于当前 session / account 的实际可用性。**
200
 
201
+ ## 关于 admin password / auth token 持久化的当前结论
202
+
203
+ 目前已做的验证结论是:
204
+
205
+ - `api_key` 可以在当前运行期通过管理接口更新,并立即影响鉴权结果
206
+ - 但容器重启后,会回退启动时环境变量 / HF Secrets 的值
207
+ - `admin_pass` 目前看**不能**通过现有 settings 路径真正更新并持久生效
 
208
 
209
+ 所以当前更准确的理解是:
210
+
211
+ - Hugging Face Secrets / Variables = **启动配置源**
212
+ - 上游 admin UI 的部分设置 = **运行期状态修改**
213
+ - 两者目前**不是**一个可自动回写、可稳定持久继承的统一配置层
214
 
215
  ## 当前仓库文件职责
216
 
 
225
  ```bash
226
  curl -I https://ohmyapi-c2api.hf.space/
227
  curl https://ohmyapi-c2api.hf.space/health
228
+
229
+ curl https://ohmyapi-c2api.hf.space/v1/models \
230
+ -H "Authorization: Bearer $CLAUDE_API_KEY"
231
 
232
  curl https://ohmyapi-c2api.hf.space/v1/messages \
233
  -H "Content-Type: application/json" \
 
239
  }'
240
  ```
241
 
242
+ 如果最后一条返回正常消息体,就说明当前公开 Space、app token、以及 Claude session 这三层链路都已经打通。