exable324 commited on
Commit
ba47fa8
·
verified ·
1 Parent(s): 0243fa2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -45
app.py CHANGED
@@ -9,16 +9,15 @@ from fastapi import FastAPI, Request, HTTPException, Depends, status
9
  from fastapi.responses import StreamingResponse
10
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
11
 
 
12
  app = FastAPI()
13
  security = HTTPBearer()
14
 
15
- # --- 配置与模型列表 ---
16
  ACCESS_TOKEN = os.getenv("ACCESS_TOKEN", "sk-admin-123456")
17
  API_KEY = "AIzaSyAZaD22Mzi9HkTcW3ErNxRA_sNEFolLBCA"
18
- # 原 Go 代码注释中提到的模型列表
19
  SUPPORTED_MODELS = ["auto", "gpt-5-mini", "gemini-3-flash", "pro"]
20
 
21
- # --- 验证逻辑 ---
22
  async def verify_token(auth: HTTPAuthorizationCredentials = Depends(security)):
23
  if auth.credentials != ACCESS_TOKEN:
24
  raise HTTPException(
@@ -28,7 +27,7 @@ async def verify_token(auth: HTTPAuthorizationCredentials = Depends(security)):
28
  )
29
  return auth.credentials
30
 
31
- # --- 核心逻辑函数 ---
32
  def get_jwt():
33
  url = f"https://identitytoolkit.googleapis.com/v1/accounts:signUp?key={API_KEY}"
34
  try:
@@ -40,40 +39,29 @@ def get_jwt():
40
  def generate_id():
41
  return ''.join(random.choice('0123456789abcdef') for _ in range(32))
42
 
43
- # --- OpenAI 兼容接口 ---
44
 
45
- # 1. 获取模型列表接口
46
  @app.get("/v1/models")
47
  async def list_models(token: str = Depends(verify_token)):
48
- models_list = []
49
- for m in SUPPORTED_MODELS:
50
- models_list.append({
51
- "id": m,
52
- "object": "model",
53
- "created": int(time.time()),
54
- "owned_by": "aidocmaker"
55
- })
56
- return {"object": "list", "data": models_list}
57
-
58
- # 2. 对话接口
59
  @app.post("/v1/chat/completions")
60
  async def chat_completions(request: Request, token: str = Depends(verify_token)):
61
  body = await request.json()
62
  messages = body.get("messages", [])
63
- # 使用请求中指定的模型,如果没传则默认 auto
64
- requested_model = body.get("model", "auto")
65
  stream = body.get("stream", False)
66
-
67
  content = messages[-1]["content"] if messages else ""
 
68
  jwt = get_jwt()
69
- if not jwt:
70
- raise HTTPException(status_code=500, detail="Failed to get JWT")
71
 
72
  url = "https://level2labs-prod--adm-agent-send-chat-message.modal.run/"
73
  headers = {"Authorization": f"Bearer {jwt}"}
74
  form_data = {
75
  "content": (None, content),
76
- "model": (None, requested_model),
77
  "conversation_id": (None, generate_id()),
78
  "message_id": (None, generate_id()),
79
  "max_mode": (None, "true")
@@ -83,44 +71,87 @@ async def chat_completions(request: Request, token: str = Depends(verify_token))
83
 
84
  def generate():
85
  chat_id = f"chatcmpl-{uuid.uuid4()}"
86
- created_time = int(time.time())
87
  for line in target_resp.iter_lines():
88
  if line:
89
  try:
90
  raw_data = json.loads(line.decode("utf-8"))
91
- delta_content = raw_data.get("data", "")
92
  chunk = {
93
- "id": chat_id,
94
- "object": "chat.completion.chunk",
95
- "created": created_time,
96
- "model": requested_model,
97
- "choices": [{"index": 0, "delta": {"content": delta_content}, "finish_reason": None}]
98
  }
99
  yield f"data: {json.dumps(chunk)}\n\n"
100
- except:
101
- continue
102
  yield "data: [DONE]\n\n"
103
 
104
  if stream:
105
  return StreamingResponse(generate(), media_type="text/event-stream")
106
  else:
107
- full_text = ""
108
- for line in target_resp.iter_lines():
109
- if line:
110
- try:
111
- full_text += json.loads(line.decode("utf-8")).get("data", "")
112
- except: continue
113
  return {
114
- "id": f"chatcmpl-{uuid.uuid4()}",
115
- "object": "chat.completion",
116
- "created": int(time.time()),
117
- "model": requested_model,
118
- "choices": [{"index": 0, "message": {"role": "assistant", "content": full_text}, "finish_reason": "stop"}]
119
  }
120
 
121
- # --- Gradio UI 逻辑 (略,保持之前的实现即可) ---
122
- # ... 这里放入之前提供的 demo 代码 ...
 
 
 
 
 
 
 
 
123
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  app = gr.mount_gradio_app(app, demo, path="/")
125
 
126
  if __name__ == "__main__":
 
9
  from fastapi.responses import StreamingResponse
10
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
11
 
12
+ # --- 1. 初始化 FastAPI 与 安全验证 ---
13
  app = FastAPI()
14
  security = HTTPBearer()
15
 
16
+ # 建议在 HF Secret 中设置 ACCESS_TOKEN
17
  ACCESS_TOKEN = os.getenv("ACCESS_TOKEN", "sk-admin-123456")
18
  API_KEY = "AIzaSyAZaD22Mzi9HkTcW3ErNxRA_sNEFolLBCA"
 
19
  SUPPORTED_MODELS = ["auto", "gpt-5-mini", "gemini-3-flash", "pro"]
20
 
 
21
  async def verify_token(auth: HTTPAuthorizationCredentials = Depends(security)):
22
  if auth.credentials != ACCESS_TOKEN:
23
  raise HTTPException(
 
27
  )
28
  return auth.credentials
29
 
30
+ # --- 2. 核心后端逻辑 ---
31
  def get_jwt():
32
  url = f"https://identitytoolkit.googleapis.com/v1/accounts:signUp?key={API_KEY}"
33
  try:
 
39
  def generate_id():
40
  return ''.join(random.choice('0123456789abcdef') for _ in range(32))
41
 
42
+ # --- 3. OpenAI 兼容接口 (/v1/...) ---
43
 
 
44
  @app.get("/v1/models")
45
  async def list_models(token: str = Depends(verify_token)):
46
+ models_data = [{"id": m, "object": "model", "created": int(time.time()), "owned_by": "aidocmaker"} for m in SUPPORTED_MODELS]
47
+ return {"object": "list", "data": models_data}
48
+
 
 
 
 
 
 
 
 
49
  @app.post("/v1/chat/completions")
50
  async def chat_completions(request: Request, token: str = Depends(verify_token)):
51
  body = await request.json()
52
  messages = body.get("messages", [])
53
+ model = body.get("model", "auto")
 
54
  stream = body.get("stream", False)
 
55
  content = messages[-1]["content"] if messages else ""
56
+
57
  jwt = get_jwt()
58
+ if not jwt: raise HTTPException(status_code=500, detail="Failed to get JWT")
 
59
 
60
  url = "https://level2labs-prod--adm-agent-send-chat-message.modal.run/"
61
  headers = {"Authorization": f"Bearer {jwt}"}
62
  form_data = {
63
  "content": (None, content),
64
+ "model": (None, model),
65
  "conversation_id": (None, generate_id()),
66
  "message_id": (None, generate_id()),
67
  "max_mode": (None, "true")
 
71
 
72
  def generate():
73
  chat_id = f"chatcmpl-{uuid.uuid4()}"
 
74
  for line in target_resp.iter_lines():
75
  if line:
76
  try:
77
  raw_data = json.loads(line.decode("utf-8"))
 
78
  chunk = {
79
+ "id": chat_id, "object": "chat.completion.chunk", "created": int(time.time()),
80
+ "model": model, "choices": [{"index": 0, "delta": {"content": raw_data.get("data", "")}, "finish_reason": None}]
 
 
 
81
  }
82
  yield f"data: {json.dumps(chunk)}\n\n"
83
+ except: continue
 
84
  yield "data: [DONE]\n\n"
85
 
86
  if stream:
87
  return StreamingResponse(generate(), media_type="text/event-stream")
88
  else:
89
+ full_text = "".join([json.loads(l.decode("utf-8")).get("data", "") for l in target_resp.iter_lines() if l])
 
 
 
 
 
90
  return {
91
+ "id": f"chatcmpl-{uuid.uuid4()}", "object": "chat.completion", "created": int(time.time()),
92
+ "model": model, "choices": [{"index": 0, "message": {"role": "assistant", "content": full_text}, "finish_reason": "stop"}]
 
 
 
93
  }
94
 
95
+ # --- 4. Gradio 管理界面逻辑 ---
96
+
97
+ def ui_check_balance(token):
98
+ if not token: return "请先获取 Token"
99
+ url = "https://level2labs-prod--adm-agent-helper-user-get-credits.modal.run/"
100
+ headers = {"Authorization": f"Bearer {token}"}
101
+ try:
102
+ data = requests.post(url, headers=headers).json()
103
+ return f"当前账号余额: {data.get('premium_quota', 0)}"
104
+ except: return "查询失败"
105
 
106
+ def ui_chat(token, content):
107
+ if not token: yield "请先获取 Token", ""; return
108
+ url = "https://level2labs-prod--adm-agent-send-chat-message.modal.run/"
109
+ headers = {"Authorization": f"Bearer {token}"}
110
+ data = {"content": (None, content), "model": (None, "gemini-3-flash"), "conversation_id": (None, generate_id()), "message_id": (None, generate_id()), "max_mode": (None, "true")}
111
+ full_text = ""
112
+ try:
113
+ resp = requests.post(url, files=data, headers=headers, stream=True)
114
+ for line in resp.iter_lines():
115
+ if line:
116
+ raw = json.loads(line.decode("utf-8"))
117
+ full_text += raw.get("data", "")
118
+ yield full_text, json.dumps(raw, ensure_ascii=False)
119
+ except Exception as e: yield f"错误: {e}", ""
120
+
121
+ def ui_tts(token, prompt):
122
+ if not token: return "请先获取 Token", None
123
+ url = "https://level2labs-prod--adm-agent-audio-create-audio-with-assistant.modal.run/"
124
+ headers = {"Authorization": f"Bearer {token}"}
125
+ try:
126
+ resp = requests.post(url, files={"prompt": (None, prompt), "voice_id": (None, "clear"), "speed": (None, "1")}, headers=headers).json()
127
+ audio_url = requests.get(f"https://level2labs-prod--adm-agent-audio-get-audio-playback-url.modal.run/?name={resp.get('name')}", headers=headers).json().get("url")
128
+ return json.dumps(resp, indent=2), audio_url
129
+ except: return "生成失败", None
130
+
131
+ # --- 5. 构建与挂载 Gradio ---
132
+
133
+ with gr.Blocks(title="AI Doc Maker 管理面板") as demo:
134
+ gr.Markdown("# 🚀 AI Doc Maker 管理面板")
135
+ with gr.Group():
136
+ btn_reg = gr.Button("第一步:创建/刷新 Token", variant="primary")
137
+ token_display = gr.Textbox(label="当前 IdToken", interactive=True)
138
+ with gr.Group():
139
+ btn_balance = gr.Button("查询余额")
140
+ balance_display = gr.Textbox(label="余额详情", interactive=False)
141
+ with gr.Group():
142
+ msg_input = gr.Textbox(label="输入消息", placeholder="a joke")
143
+ with gr.Row():
144
+ btn_msg = gr.Button("发送消息", variant="primary")
145
+ btn_tts = gr.Button("生成语音")
146
+ reply_out = gr.Textbox(label="AI 回复")
147
+ audio_out = gr.Audio(label="语音播放")
148
+
149
+ btn_reg.click(get_jwt, outputs=token_display)
150
+ btn_balance.click(ui_check_balance, inputs=token_display, outputs=balance_display)
151
+ btn_msg.click(ui_chat, inputs=[token_display, msg_input], outputs=[reply_out, gr.State()])
152
+ btn_tts.click(ui_tts, inputs=[token_display, msg_input], outputs=[gr.State(), audio_out])
153
+
154
+ # 挂载到根路径,这样你打开 Space 首页就能看到面板
155
  app = gr.mount_gradio_app(app, demo, path="/")
156
 
157
  if __name__ == "__main__":