Spaces:
Running
Running
File size: 8,673 Bytes
874f0e4 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b a5bfe39 2bce35b a5bfe39 2bce35b a5bfe39 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b a5bfe39 e2ab8a3 2bce35b a5bfe39 e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b a5bfe39 2bce35b a5bfe39 2bce35b e2ab8a3 a5bfe39 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b e2ab8a3 2bce35b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
---
title: Amazon Q to OpenAI API
emoji: 🚀
colorFrom: blue
colorTo: purple
sdk: docker
pinned: false
license: mit
---
# Amazon Q to OpenAI API Bridge
将 Amazon Q Developer 转换为 OpenAI 兼容的 API 服务,支持流式和非流式响应。
## ✨ 核心特性
- **OpenAI 兼容接口** - 完全兼容 OpenAI Chat Completions API(`/v1/chat/completions`)
- **账号管理系统** - 支持多账号管理,启用/禁用控制,自动令牌刷新
- **智能统计监控** - 自动统计成功/失败次数,错误超阈值自动禁用账号
- **设备授权登录** - 通过 URL 快速登录并自动创建账号(5分钟超时)
- **智能负载均衡** - 从启用的账号中随机选择,实现简单的负载分配
- **HTTP 代理支持** - 可配置代理服务器,支持所有 HTTP 请求
- **API Key 白名单** - 可选的访问控制,支持开发模式
- **现代化前端** - 美观的 Web 控制台,标签页布局,支持账号管理和 Chat 测试
- **自动重试机制** - Token 过期时自动刷新并重试请求
## 🚀 快速开始
### 1. 安装依赖
```bash
# 创建虚拟环境
python -m venv .venv
# Windows
.venv\Scripts\activate
pip install -r requirements.txt
# Linux/macOS
source .venv/bin/activate
pip install -r requirements.txt
```
### 2. 配置环境变量
```bash
# 复制示例配置
cp .env.example .env
# 编辑 .env 文件
# OPENAI_KEYS="key1,key2,key3" # 可选,留空则为开发模式
# MAX_ERROR_COUNT=100 # 错误次数阈值
# HTTP_PROXY="http://127.0.0.1:7890" # HTTP代理(可选)
```
**配置说明:**
- `OPENAI_KEYS` 为空或未设置:开发模式,不校验 Authorization
- `OPENAI_KEYS` 设置后:仅白名单中的 key 可访问 API
- API Key 仅用于访问控制,不映射到特定账号
- `MAX_ERROR_COUNT`:账号连续失败次数超过此值将自动禁用(默认100)
- `HTTP_PROXY`:HTTP代理地址,留空则不使用代理
### 3. 启动服务
```bash
python -m uvicorn app:app --reload --port 8000
```
访问:
- 🏠 Web 控制台:http://localhost:8000/
- 💚 健康检查:http://localhost:8000/healthz
## 📖 使用指南
### 账号管理
#### 方式一:Web 控制台(推荐)
访问 http://localhost:8000/ 使用可视化界面管理账号:
- 查看所有账号及状态
- 创建/删除/编辑账号
- 启用/禁用账号
- 刷新 Token
- URL 登录(设备授权)
#### 方式二:REST API
**创建账号**
```bash
curl -X POST http://localhost:8000/v2/accounts \
-H "Content-Type: application/json" \
-d '{
"label": "我的账号",
"clientId": "your-client-id",
"clientSecret": "your-client-secret",
"refreshToken": "your-refresh-token",
"enabled": true
}'
```
**列出所有账号**
```bash
curl http://localhost:8000/v2/accounts
```
**更新账号(切换启用状态)**
```bash
curl -X PATCH http://localhost:8000/v2/accounts/{account_id} \
-H "Content-Type: application/json" \
-d '{"enabled": false}'
```
**刷新 Token**
```bash
curl -X POST http://localhost:8000/v2/accounts/{account_id}/refresh
```
**删除账号**
```bash
curl -X DELETE http://localhost:8000/v2/accounts/{account_id}
```
### URL 登录(设备授权)
快速添加账号的最简单方式:
1. **启动登录流程**
```bash
curl -X POST http://localhost:8000/v2/auth/start \
-H "Content-Type: application/json" \
-d '{"label": "新账号", "enabled": true}'
```
返回:
```json
{
"authId": "xxx",
"verificationUriComplete": "https://...",
"userCode": "ABCD-1234",
"expiresIn": 600,
"interval": 1
}
```
2. **在浏览器中打开 `verificationUriComplete` 完成登录**
3. **等待并创建账号**(最多5分钟)
```bash
curl -X POST http://localhost:8000/v2/auth/claim/{authId}
```
成功后自动创建并启用账号。
### OpenAI 兼容 API
#### 非流式请求
```bash
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"model": "claude-sonnet-4",
"stream": false,
"messages": [
{"role": "system", "content": "你是一个乐于助人的助手"},
{"role": "user", "content": "你好,请讲一个简短的故事"}
]
}'
```
#### 流式请求(SSE)
```bash
curl -N -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"model": "claude-sonnet-4",
"stream": true,
"messages": [
{"role": "user", "content": "讲一个笑话"}
]
}'
```
#### Python 示例
```python
import openai
client = openai.OpenAI(
base_url="http://localhost:8000/v1",
api_key="your-api-key" # 如果配置了 OPENAI_KEYS
)
response = client.chat.completions.create(
model="claude-sonnet-4",
messages=[
{"role": "user", "content": "你好"}
]
)
print(response.choices[0].message.content)
```
## 🔐 授权与账号选择
### 授权机制
- **开发模式**(`OPENAI_KEYS` 未设置):不校验 Authorization
- **生产模式**(`OPENAI_KEYS` 已设置):必须提供白名单中的 key
### 账号选择策略
- 从所有 `enabled=1` 的账号中**随机选择**
- API Key 不映射到特定账号
- 无可用账号时返回 401
### Token 刷新
- 请求时若账号缺少 accessToken,自动刷新
- 上游返回 401/403 时,自动刷新并重试一次
- 可手动调用刷新接口
## 📁 项目结构
```
.
├── app.py # FastAPI 主应用
├── auth_flow.py # 设备授权登录
├── replicate.py # Amazon Q 请求复刻
├── requirements.txt # Python 依赖
├── .env.example # 环境变量示例
├── .gitignore # Git 忽略规则
├── data.sqlite3 # SQLite 数据库(自动创建)
├── frontend/
│ └── index.html # Web 控制台
└── templates/
└── streaming_request.json # 请求模板
```
## 🛠️ 技术栈
- **后端**: FastAPI + Python 3.8+
- **数据库**: SQLite3
- **前端**: 纯 HTML/CSS/JavaScript
- **认证**: AWS OIDC 设备授权流程
## 🔧 高级配置
### 环境变量
| 变量 | 说明 | 默认值 |
|------|------|--------|
| `OPENAI_KEYS` | API Key 白名单(逗号分隔) | 空(开发模式) |
| `MAX_ERROR_COUNT` | 错误次数阈值,超过自动禁用账号 | 100 |
| `HTTP_PROXY` | HTTP代理地址(如 http://127.0.0.1:7890) | 空(不使用代理) |
### 数据库结构
```sql
CREATE TABLE accounts (
id TEXT PRIMARY KEY,
label TEXT,
clientId TEXT,
clientSecret TEXT,
refreshToken TEXT,
accessToken TEXT,
other TEXT, -- JSON 格式的额外信息
last_refresh_time TEXT,
last_refresh_status TEXT,
created_at TEXT,
updated_at TEXT,
enabled INTEGER DEFAULT 1, -- 1=启用, 0=禁用
error_count INTEGER DEFAULT 0, -- 连续错误次数
success_count INTEGER DEFAULT 0 -- 成功请求次数
);
```
### 账号统计与自动禁用
系统会自动统计每个账号的请求结果:
- **成功**:返回至少1个有效字符,`success_count+1`,`error_count`重置为0
- **失败**:未返回有效字符或出错,`error_count+1`
- **自动禁用**:当`error_count >= MAX_ERROR_COUNT`时,账号自动设置为`enabled=0`
这确保了有问题的账号不会持续影响服务质量。
## 🐛 故障排查
### 401 Unauthorized
- 检查 `OPENAI_KEYS` 配置
- 确认至少有一个 `enabled=1` 的账号
- 验证账号的 clientId/clientSecret/refreshToken 正确
### Token 刷新失败
- 检查网络连接
- 验证 refreshToken 是否过期
- 查看账号的 `last_refresh_status` 字段
### 无响应/超时
- 检查 Amazon Q 服务可达性
- 查看服务日志排查错误
## 📝 API 端点
### 账号管理
- `POST /v2/accounts` - 创建账号
- `GET /v2/accounts` - 列出所有账号
- `GET /v2/accounts/{id}` - 获取账号详情
- `PATCH /v2/accounts/{id}` - 更新账号
- `DELETE /v2/accounts/{id}` - 删除账号
- `POST /v2/accounts/{id}/refresh` - 刷新 Token
### 设备授权
- `POST /v2/auth/start` - 启动登录流程
- `GET /v2/auth/status/{authId}` - 查询登录状态
- `POST /v2/auth/claim/{authId}` - 等待并创建账号
### OpenAI 兼容
- `POST /v1/chat/completions` - Chat Completions API
### 其他
- `GET /` - Web 控制台
- `GET /healthz` - 健康检查
## 📄 许可证
本项目仅供学习和测试使用。
## 🤝 贡献
欢迎提交 Issue 和 Pull Request! |