CassiopeiaCode commited on
Commit
2bce35b
·
1 Parent(s): e2ab8a3

docs: 更新README文档,美化前端UI

Browse files
Files changed (1) hide show
  1. README.md +229 -148
README.md CHANGED
@@ -1,221 +1,302 @@
1
- # v2 OpenAI 兼容服务(FastAPI + 前端)
2
 
3
- 本目录提供一个独立于 v1 Python 版本,实现 FastAPI 后端与纯静态前端,功能包括:
4
- - 账号管理(SQLite 存储,支持登录/删除/刷新/自定义 other 字段,支持启用/禁用 enabled 开关)
5
- - OpenAI Chat Completions 兼容接口(流式与非流式)
6
- - 自动刷新令牌(401/403 时重试一次)
7
- - URL 登录(设备授权,前端触发,最长等待5分钟自动创建账号并可选启用)
8
- - 将客户端 messages 整理为 “{role}:\n{content}” 文本,替换模板中的占位内容后调用上游
9
- - OpenAI Key 白名单授权:仅用于防止未授权访问;账号选择与 key 无关,始终从“启用”的账号中随机选择
10
 
11
- 主要文件:
12
- - [v2/app.py](v2/app.py)
13
- - [v2/replicate.py](v2/replicate.py)
14
- - [v2/templates/streaming_request.json](v2/templates/streaming_request.json)
15
- - [v2/frontend/index.html](v2/frontend/index.html)
16
- - [v2/requirements.txt](v2/requirements.txt)
17
- - [v2/.env.example](v2/.env.example)
18
 
19
- 数据库:运行时会在 v2 目录下创建 data.sqlite3(accounts 表内置 enabled 列,只从 enabled=1 的账号中选取)。
 
 
 
 
 
 
20
 
21
- ## 1. 安装依赖
22
 
23
- 建议使用虚拟环境:
24
 
25
  ```bash
 
26
  python -m venv .venv
27
- .venv\Scripts\pip install -r v2/requirements.txt
28
- ```
29
 
30
- 若在 Unix:
 
 
31
 
32
- ```bash
33
- python3 -m venv .venv
34
  source .venv/bin/activate
35
- pip install -r v2/requirements.txt
36
  ```
37
 
38
- ## 2. 配置环境变量
39
-
40
- 复制示例文件生成 .env:
41
 
42
  ```bash
43
- copy v2\.env.example v2\.env # Windows
44
- #
45
- cp v2/.env.example v2/.env # Unix
46
- ```
47
-
48
- 配置 OPENAI_KEYS(OpenAI 风格 API Key 白名单,仅用于授权,与账号无关)。使用逗号分隔:
49
 
50
- 示例:
51
- ```env
52
- OPENAI_KEYS="key1,key2,key3"
53
  ```
54
 
55
- 提示:
56
- - OPENAI_KEYS 为空或未设置,则处于开发模式,不校验 Authorization
57
- - Key 仅用于访问控制,不能也不会映射到任意 AWS 账号。
 
58
 
59
- 重要:
60
- - 所有请求在通过授权后,会在“启用”的账号集合中随机选择一个账号执行业务逻辑。
61
- - OPENAI_KEYS 校验失败返回 401;当白名单为空时不校验。
62
- - 若没有任何启用账号,将返回 401。
63
- 前端与服务端通过 Authorization: Bearer {key} 进行授权校验(仅验证是否在白名单);账号选择与 key 无关。
64
-
65
- ## 3. 启动服务
66
-
67
- 使用 uvicorn 指定 app 目录启动(无需将 v2 作为包安装):
68
 
69
  ```bash
70
- python -m uvicorn app:app --app-dir v2 --reload --port 8000
71
  ```
72
 
73
  访问:
74
- - 健康检查:http://localhost:8000/healthz
75
- - 前端控制台:http://localhost:8000/
 
 
76
 
77
- ## 4. 账号管理
78
 
79
- - 前端在 “账号管理” 面板支持:列表、创建、删除、刷新、快速编辑 label/accessToken、启用/禁用(enabled)
80
- - 也可通过 REST API 操作(返回 JSON)
81
 
82
- 创建账号:
 
 
 
 
 
83
 
 
 
 
84
  ```bash
85
- curl -X POST http://localhost:8000/v2/accounts ^
86
- -H "content-type: application/json" ^
87
- -d "{\"label\":\"main\",\"clientId\":\"...\",\"clientSecret\":\"...\",\"refreshToken\":\"...\",\"accessToken\":null,\"enabled\":true,\"other\":{\"note\":\"可选\"}}"
 
 
 
 
 
 
88
  ```
89
 
90
- 列表:
91
-
92
  ```bash
93
  curl http://localhost:8000/v2/accounts
94
  ```
95
 
96
- 更新(切换启用状态):
97
-
98
  ```bash
99
- curl -X PATCH http://localhost:8000/v2/accounts/{account_id} ^
100
- -H "content-type: application/json" ^
101
- -d "{\"enabled\":false}"
102
  ```
103
 
104
- 刷新令牌:
105
-
106
  ```bash
107
  curl -X POST http://localhost:8000/v2/accounts/{account_id}/refresh
108
  ```
109
 
110
- 删除:
111
-
112
  ```bash
113
  curl -X DELETE http://localhost:8000/v2/accounts/{account_id}
114
  ```
115
 
116
- 无需在 .env 为账号做映射;只需在数据库创建并启用账号即可参与随机选择。
117
-
118
- ### URL 登录(设备授权,5分钟超时)
119
-
120
- - 前端已在“账号管理”面板提供“开始登录”和“等待授权并创建账号”入口,打开验证链接完成登录后将自动创建账号(可选启用)。
121
- - 也可直接调用以下 API:
122
- - POST /v2/auth/start
123
- - 请求体(可选):
124
- - label: string(账号标签)
125
- - enabled: boolean(创建后是否启用,默认 true)
126
- - 返回:
127
- - authId: string
128
- - verificationUriComplete: string(浏览器打开该链接完成登录)
129
- - userCode: string
130
- - expiresIn: number(秒)
131
- - interval: number(建议轮询间隔,秒)
132
- - POST /v2/auth/claim/{authId}
133
- - 阻塞等待设备授权完成,最长 5 分钟
134
- - 成功返回:
135
- - { "status": "completed", "account": { 新建账号对象 } }
136
- - 超时返回 408,错误返回 502
137
- - GET /v2/auth/status/{authId}
138
- - 返回当前状态 { status, remaining, error, accountId },remaining 为预计剩余秒数
139
- - 流程建议:
140
- 1. 调用 /v2/auth/start 获取 verificationUriComplete,并在新窗口打开该链接
141
- 2. 用户在浏览器完成登录
142
- 3. 调用 /v2/auth/claim/{authId} 等待创建账号(最多 5 分钟);或轮询 /v2/auth/status/{authId} 查看状态
143
-
144
- ## 5. OpenAI 兼容接口
145
-
146
- 接口:POST /v1/chat/completions
147
-
148
- 请求体(示例,非流式):
149
 
 
 
 
 
 
 
 
 
 
 
150
  ```json
151
  {
152
- "model": "claude-sonnet-4",
153
- "stream": false,
154
- "messages": [
155
- {"role":"system","content":"你是一个乐于助人的助手"},
156
- {"role":"user","content":"你好,请讲一个简短的故事"}
157
- ]
158
  }
159
  ```
160
 
161
- 授权与账号选择:
162
- - 若配置了 OPENAI_KEYS,则 Authorization: Bearer {key} 必须在白名单中,否则 401。
163
- - 若 OPENAI_KEYS 为空或未设置,开发模式下不校验 Authorization。
164
- - 账号选择策略:在所有 enabled=1 的账号中随机选择;若无可用账号,返回 401。
165
- - 被选账号缺少 accessToken 时,自动尝试刷新一次(成功后重试上游请求)。
 
 
 
 
 
166
 
167
- 非流式调用(以 curl 为例):
168
 
169
  ```bash
170
- curl -X POST http://localhost:8000/v1/chat/completions ^
171
- -H "content-type: application/json" ^
172
- -H "authorization: Bearer key1" ^
173
- -d "{\"model\":\"claude-sonnet-4\",\"stream\":false,\"messages\":[{\"role\":\"user\",\"content\":\"你好\"}]}"
 
 
 
 
 
 
 
174
  ```
175
 
176
- 流式(SSE)调用:
177
 
178
  ```bash
179
- curl -N -X POST http://localhost:8000/v1/chat/completions ^
180
- -H "content-type: application/json" ^
181
- -H "authorization: Bearer key2" ^
182
- -d "{\"model\":\"claude-sonnet-4\",\"stream\":true,\"messages\":[{\"role\":\"user\",\"content\":\"讲一个笑话\"}]}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  ```
184
 
185
- 响应格式严格遵循 OpenAI Chat Completions 标准:
186
- - 非流式:返回一个 chat.completion 对象
187
- - 流式:返回 chat.completion.chunk 的 SSE 片段,最后以 data: [DONE] 结束
188
 
189
- ## 6. 历史构造与请求复刻
 
 
 
190
 
191
- - 服务将 messages 整理为 “{role}:\n{content}” 文本
192
- - 替换模板 [v2/templates/streaming_request.json](v2/templates/streaming_request.json) 中的占位 “你好,你必须讲个故事”
193
- - 然后按 v1 思路重放请求逻辑,但不依赖 v1 代码,具体实现见 [v2/replicate.py](v2/replicate.py)
 
194
 
195
- ## 7. 自动刷新令牌
 
 
196
 
197
- - 请求上游出现 401/403 时,会尝试刷新一次后重试
198
- - 也可在前端手动点击某账号的 “刷新Token” 按钮
199
 
200
- ## 8. 前端说明
 
 
 
 
 
 
201
 
202
- - 页面路径:[v2/frontend/index.html](v2/frontend/index.html),由后端根路由 “/” 提供
203
- - 功能:管理账号(含启用开关) + 触发 Chat 请求(支持流式与非流式显示)
204
- - 在页面顶部设置 API Base 与 Authorization(OpenAI Key)
 
205
 
206
- ## 9. 运行排错
 
207
 
208
- - 导入失败:使用 --app-dir v2 方式启动 uvicorn
209
- - 401/403:检查账号的 clientId/clientSecret/refreshToken 是否正确,或手动刷新,或确认账号 enabled=1
210
- - 未选到账号:检查 OPENAI_KEYS 映射与账号启用状态;对于通配池 key:* 需保证至少有一个启用账号
211
- - 无响应/超时:检查网络或上游服务可达性
212
 
213
- ## 10. 设计与来源
214
 
215
- - 核心重放与事件流解析来自 v1 的思路,已抽取为 [v2/replicate.py](v2/replicate.py)
216
- - 后端入口:[v2/app.py](v2/app.py)
217
- - 模板请求:[v2/templates/streaming_request.json](v2/templates/streaming_request.json)
218
 
219
- ## 11. 许可证
220
 
221
- 仅供内部集成与测试使用。
 
1
+ # Amazon Q to OpenAI API Bridge
2
 
3
+ Amazon Q Developer 转换为 OpenAI 兼容的 API 服务,支持流式和非流式响应。
 
 
 
 
 
 
4
 
5
+ ## ✨ 核心特性
 
 
 
 
 
 
6
 
7
+ - **OpenAI 兼容接口** - 完全兼容 OpenAI Chat Completions API(`/v1/chat/completions`)
8
+ - **账号管理系统** - 支持多账号管理,启用/禁用控制,自动令牌刷新
9
+ - **设备授权登录** - 通过 URL 快速登录并自动创建账号(5分钟超时)
10
+ - **智能负载均衡** - 从启用的账号中随机选择,实现简单的负载分配
11
+ - **API Key 白名单** - 可选的访问控制,支持开发模式
12
+ - **现代化前端** - 美观的 Web 控制台,支持账号管理和 Chat 测试
13
+ - **自动重试机制** - Token 过期时自动刷新并重试请求
14
 
15
+ ## 🚀 快速开始
16
 
17
+ ### 1. 安装依赖
18
 
19
  ```bash
20
+ # 创建虚拟环境
21
  python -m venv .venv
 
 
22
 
23
+ # Windows
24
+ .venv\Scripts\activate
25
+ pip install -r requirements.txt
26
 
27
+ # Linux/macOS
 
28
  source .venv/bin/activate
29
+ pip install -r requirements.txt
30
  ```
31
 
32
+ ### 2. 配置环境变量
 
 
33
 
34
  ```bash
35
+ # 复制示例配置
36
+ cp .env.example .env
 
 
 
 
37
 
38
+ # 编辑 .env 文件
39
+ # OPENAI_KEYS="key1,key2,key3" # 可选,留空则为开发模式
 
40
  ```
41
 
42
+ **配置说明:**
43
+ - `OPENAI_KEYS` 为空或未设置:开发模式,不校验 Authorization
44
+ - `OPENAI_KEYS` 设置后:仅白名单中的 key 可访问 API
45
+ - API Key 仅用于访问控制,不映射到特定账号
46
 
47
+ ### 3. 启动服务
 
 
 
 
 
 
 
 
48
 
49
  ```bash
50
+ python -m uvicorn app:app --reload --port 8000
51
  ```
52
 
53
  访问:
54
+ - 🏠 Web 控制台:http://localhost:8000/
55
+ - 💚 健康检查:http://localhost:8000/healthz
56
+
57
+ ## 📖 使用指南
58
 
59
+ ### 账号管理
60
 
61
+ #### 方式一:Web 控制台(推荐)
 
62
 
63
+ 访问 http://localhost:8000/ 使用可视化界面管理账号:
64
+ - 查看所有账号及状态
65
+ - 创建/删除/编辑账号
66
+ - 启用/禁用账号
67
+ - 刷新 Token
68
+ - URL 登录(设备授权)
69
 
70
+ #### 方式二:REST API
71
+
72
+ **创建账号**
73
  ```bash
74
+ curl -X POST http://localhost:8000/v2/accounts \
75
+ -H "Content-Type: application/json" \
76
+ -d '{
77
+ "label": "我的账号",
78
+ "clientId": "your-client-id",
79
+ "clientSecret": "your-client-secret",
80
+ "refreshToken": "your-refresh-token",
81
+ "enabled": true
82
+ }'
83
  ```
84
 
85
+ **列出所有账号**
 
86
  ```bash
87
  curl http://localhost:8000/v2/accounts
88
  ```
89
 
90
+ **更新账号(切换启用状态)**
 
91
  ```bash
92
+ curl -X PATCH http://localhost:8000/v2/accounts/{account_id} \
93
+ -H "Content-Type: application/json" \
94
+ -d '{"enabled": false}'
95
  ```
96
 
97
+ **刷新 Token**
 
98
  ```bash
99
  curl -X POST http://localhost:8000/v2/accounts/{account_id}/refresh
100
  ```
101
 
102
+ **删除账号**
 
103
  ```bash
104
  curl -X DELETE http://localhost:8000/v2/accounts/{account_id}
105
  ```
106
 
107
+ ### URL 登录(设备授权)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
+ 快速添加账号的最简单方式:
110
+
111
+ 1. **启动登录流程**
112
+ ```bash
113
+ curl -X POST http://localhost:8000/v2/auth/start \
114
+ -H "Content-Type: application/json" \
115
+ -d '{"label": "新账号", "enabled": true}'
116
+ ```
117
+
118
+ 返回:
119
  ```json
120
  {
121
+ "authId": "xxx",
122
+ "verificationUriComplete": "https://...",
123
+ "userCode": "ABCD-1234",
124
+ "expiresIn": 600,
125
+ "interval": 1
 
126
  }
127
  ```
128
 
129
+ 2. **在浏览器中打开 `verificationUriComplete` 完成登录**
130
+
131
+ 3. **等待并创建账号**(最多5分钟)
132
+ ```bash
133
+ curl -X POST http://localhost:8000/v2/auth/claim/{authId}
134
+ ```
135
+
136
+ 成功后自动创建并启用账号。
137
+
138
+ ### OpenAI 兼容 API
139
 
140
+ #### 非流式请求
141
 
142
  ```bash
143
+ curl -X POST http://localhost:8000/v1/chat/completions \
144
+ -H "Content-Type: application/json" \
145
+ -H "Authorization: Bearer your-api-key" \
146
+ -d '{
147
+ "model": "claude-sonnet-4",
148
+ "stream": false,
149
+ "messages": [
150
+ {"role": "system", "content": "你是一个乐于助人的助手"},
151
+ {"role": "user", "content": "你好,请讲一个简短的故事"}
152
+ ]
153
+ }'
154
  ```
155
 
156
+ #### 流式请求(SSE
157
 
158
  ```bash
159
+ curl -N -X POST http://localhost:8000/v1/chat/completions \
160
+ -H "Content-Type: application/json" \
161
+ -H "Authorization: Bearer your-api-key" \
162
+ -d '{
163
+ "model": "claude-sonnet-4",
164
+ "stream": true,
165
+ "messages": [
166
+ {"role": "user", "content": "讲一个笑话"}
167
+ ]
168
+ }'
169
+ ```
170
+
171
+ #### Python 示例
172
+
173
+ ```python
174
+ import openai
175
+
176
+ client = openai.OpenAI(
177
+ base_url="http://localhost:8000/v1",
178
+ api_key="your-api-key" # 如果配置了 OPENAI_KEYS
179
+ )
180
+
181
+ response = client.chat.completions.create(
182
+ model="claude-sonnet-4",
183
+ messages=[
184
+ {"role": "user", "content": "你好"}
185
+ ]
186
+ )
187
+
188
+ print(response.choices[0].message.content)
189
+ ```
190
+
191
+ ## 🔐 授权与账号选择
192
+
193
+ ### 授权机制
194
+ - **开发模式**(`OPENAI_KEYS` 未设置):不校验 Authorization
195
+ - **生产模式**(`OPENAI_KEYS` 已设置):必须提供白名单中的 key
196
+
197
+ ### 账号选择策略
198
+ - 从所有 `enabled=1` 的账号中**随机选择**
199
+ - API Key 不映射到特定账号
200
+ - 无可用账号时返回 401
201
+
202
+ ### Token 刷新
203
+ - 请求时若账号缺少 accessToken,自动刷新
204
+ - 上游返回 401/403 时,自动刷新并重试一次
205
+ - 可手动调用刷新接口
206
+
207
+ ## 📁 项目结构
208
+
209
+ ```
210
+ .
211
+ ├── app.py # FastAPI 主应用
212
+ ├── auth_flow.py # 设备授权登录
213
+ ├── replicate.py # Amazon Q 请求复刻
214
+ ├── requirements.txt # Python 依赖
215
+ ├── .env.example # 环境变量示例
216
+ ├── .gitignore # Git 忽略规则
217
+ ├── data.sqlite3 # SQLite 数据库(自动创建)
218
+ ├── frontend/
219
+ │ └── index.html # Web 控制台
220
+ └── templates/
221
+ └── streaming_request.json # 请求模板
222
+ ```
223
+
224
+ ## 🛠️ 技术栈
225
+
226
+ - **后端**: FastAPI + Python 3.8+
227
+ - **数据库**: SQLite3
228
+ - **前端**: 纯 HTML/CSS/JavaScript
229
+ - **认证**: AWS OIDC 设备授权流程
230
+
231
+ ## 🔧 高级配置
232
+
233
+ ### 环境变量
234
+
235
+ | 变量 | 说明 | 默认值 |
236
+ |------|------|--------|
237
+ | `OPENAI_KEYS` | API Key 白名单(逗号分隔) | 空(开发模式) |
238
+
239
+ ### 数据库结构
240
+
241
+ ```sql
242
+ CREATE TABLE accounts (
243
+ id TEXT PRIMARY KEY,
244
+ label TEXT,
245
+ clientId TEXT,
246
+ clientSecret TEXT,
247
+ refreshToken TEXT,
248
+ accessToken TEXT,
249
+ other TEXT, -- JSON 格式的额外信息
250
+ last_refresh_time TEXT,
251
+ last_refresh_status TEXT,
252
+ created_at TEXT,
253
+ updated_at TEXT,
254
+ enabled INTEGER DEFAULT 1 -- 1=启用, 0=禁用
255
+ );
256
  ```
257
 
258
+ ## 🐛 故障排查
 
 
259
 
260
+ ### 401 Unauthorized
261
+ - 检查 `OPENAI_KEYS` 配置
262
+ - 确认至少有一个 `enabled=1` 的账号
263
+ - 验证账号的 clientId/clientSecret/refreshToken 正确
264
 
265
+ ### Token 刷新失败
266
+ - 检查网络连接
267
+ - 验证 refreshToken 是否过期
268
+ - 查看账号的 `last_refresh_status` 字段
269
 
270
+ ### 无响应/超时
271
+ - 检查 Amazon Q 服务可达性
272
+ - 查看服务日志排查错误
273
 
274
+ ## 📝 API 端点
 
275
 
276
+ ### 账号管理
277
+ - `POST /v2/accounts` - 创建账号
278
+ - `GET /v2/accounts` - 列出所有账号
279
+ - `GET /v2/accounts/{id}` - 获取账号详情
280
+ - `PATCH /v2/accounts/{id}` - 更新账号
281
+ - `DELETE /v2/accounts/{id}` - 删除账号
282
+ - `POST /v2/accounts/{id}/refresh` - 刷新 Token
283
 
284
+ ### 设备授权
285
+ - `POST /v2/auth/start` - 启动登录流程
286
+ - `GET /v2/auth/status/{authId}` - 查询登录状态
287
+ - `POST /v2/auth/claim/{authId}` - 等待并创建账号
288
 
289
+ ### OpenAI 兼容
290
+ - `POST /v1/chat/completions` - Chat Completions API
291
 
292
+ ### 其他
293
+ - `GET /` - Web 控制台
294
+ - `GET /healthz` - 健康检查
 
295
 
296
+ ## 📄 许可证
297
 
298
+ 本项目仅供学习和测试使用。
 
 
299
 
300
+ ## 🤝 贡献
301
 
302
+ 欢迎提交 Issue 和 Pull Request!