Amazon Q to API Bridge:一个使用 FastAPI 实现的桥接服务,将 Amazon Q Developer 变成兼容 OpenAI Chat Completions 和 Claude Messages 的 API,支持多账号管理、随机负载均衡和流式响应。
|
|
3 hafta önce | |
|---|---|---|
| account-feeder | 2 ay önce | |
| docs | 2 ay önce | |
| frontend | 1 ay önce | |
| scripts | 2 ay önce | |
| templates | 2 ay önce | |
| .env.example | 2 ay önce | |
| .gitignore | 2 ay önce | |
| Dockerfile | 2 ay önce | |
| README.md | 2 ay önce | |
| app.py | 3 hafta önce | |
| auth_flow.py | 2 ay önce | |
| claude_converter.py | 1 ay önce | |
| claude_parser.py | 2 ay önce | |
| claude_stream.py | 1 ay önce | |
| claude_types.py | 1 ay önce | |
| db.py | 1 ay önce | |
| docker-compose.yml | 2 ay önce | |
| message_processor.py | 1 ay önce | |
| replicate.py | 2 ay önce | |
| requirements.txt | 2 ay önce |
将 Amazon Q Developer 转换为兼容 OpenAI 和 Claude API 的服务,支持多账号管理、流式响应和智能负载均衡。
项目地址:
致谢:
/v1/chat/completions 端点/v1/messages 端点,支持流式和非流式# 1. 复制环境变量配置
cp .env.example .env
# 2. 编辑 .env 文件(可选)
# 配置 OPENAI_KEYS、MAX_ERROR_COUNT 等
# 3. 启动服务
docker-compose up -d
# 4. 查看日志
docker-compose logs -f
# 5. 停止服务
docker-compose down
服务访问地址:
推荐使用 uv 进行环境管理和依赖安装。
# 安装 uv
pip install uv
# 创建虚拟环境并安装依赖
uv venv
uv pip install -r requirements.txt
# 复制示例配置
cp .env.example .env
# 根据需要编辑 .env 文件
.env 配置说明:
# 数据库连接URL(留空使用本地SQLite)
# PostgreSQL: DATABASE_URL="postgres://user:password@host:5432/dbname?sslmode=require"
# MySQL: DATABASE_URL="mysql://user:password@host:3306/dbname"
DATABASE_URL=""
# OpenAI 风格 API Key 白名单(仅用于授权,与账号无关)
# 多个用逗号分隔,例如:OPENAI_KEYS="key1,key2,key3"
# 留空则为开发模式,不校验 Authorization
OPENAI_KEYS=""
# Token 计数倍率(影响 /v1/messages/count_tokens 和 /v1/messages 的输入 token 统计)
# 默认值为 1.0,可根据实际需要调整(如设置为 1.5 表示返回 1.5 倍的 token 数)
TOKEN_COUNT_MULTIPLIER="1.0"
# 出错次数阈值,超过此值自动禁用账号
MAX_ERROR_COUNT=100
# HTTP代理设置(留空不使用代理)
# 例如:HTTP_PROXY="http://127.0.0.1:7890"
HTTP_PROXY=""
# 管理控制台开关(默认启用)
# 设置为 "false" 或 "0" 可禁用管理控制台和相关API端点
ENABLE_CONSOLE="true"
# 管理控制台登录密码(默认 "admin")
# 用于访问管理控制台的密码,会话有效期为30天
ADMIN_PASSWORD="admin"
# 主服务端口(默认 8000)
PORT=8000
配置要点:
OPENAI_KEYS 为空:开发模式,不校验 AuthorizationOPENAI_KEYS 设置后:仅白名单中的 key 可访问 APIENABLE_CONSOLE 设为 false 或 0:禁用 Web 管理控制台和账号管理 APIADMIN_PASSWORD:管理控制台登录密码,默认为 "admin",建议修改为强密码# 启动服务 (带热重载)
uvicorn app:app --host 0.0.0.0 --port 8000 --reload
服务启动后,即可通过 http://localhost:8000 访问。该模式适用于开发,修改代码后服务会自动重启。
首次访问管理控制台需要登录:
admin,可通过 ADMIN_PASSWORD 环境变量配置)安全建议:
ADMIN_PASSWORD 为强密码登录管理控制台后,使用可视化界面:
快速添加账号的推荐方式:
启动登录流程
curl -X POST http://localhost:8000/v2/auth/start \
-H "Content-Type: application/json" \
-d '{"label": "我的账号", "enabled": true}'
在浏览器中打开返回的 verificationUriComplete 完成登录
等待并创建账号(最多5分钟)
curl -X POST http://localhost:8000/v2/auth/claim/{authId}
成功后自动创建并启用账号,立即可用。
注意: 所有管理 API 请求需要携带登录凭证(Authorization Bearer Token)
先登录获取 Token
# 登录并获取 token
TOKEN=$(curl -X POST http://localhost:8000/api/login \
-H "Content-Type: application/json" \
-d '{"password": "admin"}' \
| jq -r '.token')
创建账号
curl -X POST http://localhost:8000/v2/accounts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"label": "手动创建的账号",
"clientId": "your-client-id",
"clientSecret": "your-client-secret",
"refreshToken": "your-refresh-token",
"enabled": true
}'
列出所有账号
curl http://localhost:8000/v2/accounts \
-H "Authorization: Bearer $TOKEN"
更新账号
curl -X PATCH http://localhost:8000/v2/accounts/{account_id} \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"enabled": false}'
刷新 Token
curl -X POST http://localhost:8000/v2/accounts/{account_id}/refresh \
-H "Authorization: Bearer $TOKEN"
删除账号
curl -X DELETE http://localhost:8000/v2/accounts/{account_id} \
-H "Authorization: Bearer $TOKEN"
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": "你好,请讲一个简短的故事"}
]
}'
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": "讲一个笑话"}
]
}'
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)
本项目完整支持 Claude Messages API 格式,包括流式响应、工具调用、多模态内容等。
curl -X POST http://localhost:8000/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: your-api-key" \
-d '{
"model": "claude-sonnet-4.5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "你好"}
]
}'
from anthropic import Anthropic
client = Anthropic(
base_url="http://localhost:8000/v1",
api_key="your-api-key"
)
# 基础对话
message = client.messages.create(
model="claude-sonnet-4.5",
max_tokens=1024,
messages=[
{"role": "user", "content": "你好"}
]
)
print(message.content[0].text)
# 流式响应
with client.messages.stream(
model="claude-sonnet-4.5",
max_tokens=1024,
messages=[
{"role": "user", "content": "写一首诗"}
]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
OPENAI_KEYS 未设置):不校验 AuthorizationOPENAI_KEYS 已设置):必须提供白名单中的 keyenabled=1 的账号中随机选择v2/
├── app.py # FastAPI 主应用
├── db.py # 数据库抽象层 (SQLite/PG/MySQL)
├── replicate.py # Amazon Q 请求复刻
├── auth_flow.py # 设备授权登录
├── claude_types.py # Claude API 类型定义
├── claude_converter.py # Claude 到 Amazon Q 转换
├── claude_parser.py # Event Stream 解析
├── claude_stream.py # Claude SSE 流式处理
├── requirements.txt # Python 依赖
├── .env.example # 环境变量示例
├── .env # 环境变量配置(需自行创建)
├── docker-compose.yml # Docker Compose 配置
├── Dockerfile # Docker 镜像配置
├── data.sqlite3 # SQLite 数据库(自动创建)
├── templates/
│ └── streaming_request.json # Amazon Q 请求模板
├── frontend/
│ └── index.html # Web 控制台
└── scripts/
├── account_stats.py # 账号统计脚本
├── retry_failed_accounts.py # 重试失败账号脚本
└── reset_accounts.py # 重置账号脚本
| 变量 | 说明 | 默认值 | 示例 |
|---|---|---|---|
DATABASE_URL |
数据库连接URL | 空(使用SQLite) | "postgres://user:pass@host:5432/db" |
OPENAI_KEYS |
API Key 白名单(逗号分隔) | 空(开发模式) | "key1,key2" |
TOKEN_COUNT_MULTIPLIER |
Token 计数倍率 | 1.0 |
"1.5" |
MAX_ERROR_COUNT |
错误次数阈值 | 100 | 50 |
HTTP_PROXY |
HTTP代理地址 | 空 | "http://127.0.0.1:7890" |
ENABLE_CONSOLE |
管理控制台开关 | "true" |
"false" |
ADMIN_PASSWORD |
管理控制台登录密码 | "admin" |
"your-secure-password" |
PORT |
服务端口 | 8000 | 8080 |
DEBUG_MESSAGE_CONVERSION |
消息转换调试日志 | "false" |
"true" |
LAZY_ACCOUNT_POOL_ENABLED |
是否启用 Lazy 号池 | "false" |
"true" |
LAZY_ACCOUNT_POOL_SIZE |
Lazy 号池大小(聊天) | 20 |
50 |
LAZY_ACCOUNT_POOL_REFRESH_OFFSET |
Lazy 号池刷新偏移量 | 10 |
20 |
LAZY_ACCOUNT_POOL_ORDER_BY |
Lazy 号池排序字段 | "created_at" |
"success_count" |
LAZY_ACCOUNT_POOL_ORDER_DESC |
Lazy 号池是否降序 | "false" |
"true" |
CREATE TABLE accounts (
id TEXT PRIMARY KEY, -- UUID
label TEXT, -- 账号标签
clientId TEXT, -- OIDC 客户端 ID
clientSecret TEXT, -- OIDC 客户端密钥
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 -- 成功请求次数
);
POST /api/login - 管理员登录,获取会话 tokenGET /login - 登录页面POST /v2/accounts - 创建账号POST /v2/accounts/feed - 批量创建账号GET /v2/accounts - 列出所有账号GET /v2/accounts/{id} - 获取账号详情PATCH /v2/accounts/{id} - 更新账号DELETE /v2/accounts/{id} - 删除账号POST /v2/accounts/{id}/refresh - 刷新 TokenPOST /v2/auth/start - 启动登录流程GET /v2/auth/status/{authId} - 查询登录状态POST /v2/auth/claim/{authId} - 等待并创建账号(最多5分钟)POST /v1/chat/completions - Chat Completions APIPOST /v1/messages - Messages API(支持流式、工具调用、多模态)POST /v1/messages/count_tokens - Token 计数接口(预先统计消息的 token 数量)GET / - Web 控制台首页(需启用 ENABLE_CONSOLE,需登录)GET /healthz - 健康检查GET /docs - API 文档(Swagger UI)现象: AI 重复调用相同的工具(如 git、bash 命令),无法停止
原因: 消息历史被错误合并,导致 AI 无法识别已执行的工具调用
解决方法:
DEBUG_MESSAGE_CONVERSION=true可能原因:
OPENAI_KEYS 白名单中enabled=1)解决方法:
.env 中的 OPENAI_KEYS 配置/v2/accounts 确认至少有一个启用的账号可能原因:
解决方法:
last_refresh_status 字段# 使用多个 worker 提高并发性能
python -m uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# SSE 支持
proxy_buffering off;
proxy_cache off;
}
}
ADMIN_PASSWORD 为强密码OPENAI_KEYSdata.sqlite3,或 PG/MySQL 数据库)本项目仅供学习和测试使用。
欢迎提交 Issue 和 Pull Request!