MaktubCN commited on
Commit
43e3029
1 Parent(s): c28b8a5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +197 -30
app.py CHANGED
@@ -1,8 +1,8 @@
1
  import os
2
  os.environ['no_proxy'] = '*' # 避免代理网络产生意外污染
3
 
4
- help_menu_description = """
5
- Github源代码开源和更新[地址🚀](https://github.com/binary-husky/gpt_academic),
6
  感谢热情的[开发者们❤️](https://github.com/binary-husky/gpt_academic/graphs/contributors).
7
  </br></br>常见问题请查阅[项目Wiki](https://github.com/binary-husky/gpt_academic/wiki),
8
  如遇到Bug请前往[Bug反馈](https://github.com/binary-husky/gpt_academic/issues).
@@ -19,7 +19,7 @@ def main():
19
  import logging, uuid, traceback
20
 
21
  try:
22
- # 安装 Gradio
23
  subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'https://public.agent-matrix.com/publish/gradio-3.32.8-py3-none-any.whl'])
24
  import gradio as gr
25
  print(f"Gradio version: {gr.__version__}")
@@ -89,9 +89,13 @@ def main():
89
  predefined_btns = {}
90
  with gr.Blocks(title="GPT 学术优化", theme=set_theme, analytics_enabled=False, css=advanced_css) as demo:
91
  gr.HTML(title_html)
92
- gr.HTML('''<center><a href="https://huggingface.co/spaces/qingxu98/gpt-academic?duplicate=true"><img src="https://bit.ly/3gLdBN6" alt="Duplicate Space"></a>请您打开此页面后务必点击上方的“复制空间”(Duplicate Space)按钮!<font color="#FF00FF">使用时,先在输入框填入API-KEY然后回车。</font><br/>切忌在“复制空间”(Duplicate Space)之前填入API_KEY或进行提问,否则您的API_KEY将极可能被空间所有者攫取!<br/>支持任意数量的OpenAI的密钥和API2D的密钥共存,例如输入"OpenAI密钥1,API2D密钥2",然后提交,即可同时使用两种模型接口。</center>''')
93
  secret_css, dark_mode, py_pickle_cookie = gr.Textbox(visible=False), gr.Textbox(DARK_MODE, visible=False), gr.Textbox(visible=False)
94
  cookies = gr.State(load_chat_cookies())
 
 
 
 
95
  with gr_L1():
96
  with gr_L2(scale=2, elem_id="gpt-chat"):
97
  chatbot = gr.Chatbot(label=f"当前模型:{LLM_MODEL}", elem_id="gpt-chatbot")
@@ -115,34 +119,204 @@ def main():
115
  with gr.Row():
116
  status = gr.Markdown(f"Tip: 按Enter提交, 按Shift+Enter换行。当前模型: {LLM_MODEL} \n {proxy_info}", elem_id="state-panel")
117
 
118
- # 其他 UI 组件省略...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
- # 定义从 URL 参数中提取 base_url api_key 的函数
121
- def extract_api_credentials(request: gr.Request, cookies):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  try:
123
- # 提取 URL 参数
124
- params = request.query_params
125
- base_url = params.get('base_url', None)
126
- api_key = params.get('api_key', None)
127
-
128
  print(f"Extracted base_url: {base_url}")
129
  print(f"Extracted api_key: {api_key}")
130
-
131
  # 更新 cookies 或应用程序状态
132
  if base_url:
133
  cookies['base_url'] = base_url
134
  if api_key:
135
  cookies['api_key'] = api_key # 警告:通过 URL 传递 API 密钥是不安全的
136
-
137
  return cookies
138
  except Exception as e:
139
  print(f"Error in extract_api_credentials: {e}")
140
  return cookies
141
 
142
- # 在应用加载时调用该函数,确保传递 gr.Request 对象
143
  demo.load(
144
  fn=extract_api_credentials,
145
- inputs=[gr.Request(), cookies],
146
  outputs=[cookies]
147
  )
148
 
@@ -201,11 +375,11 @@ def main():
201
  md_dropdown.select(on_md_dropdown_changed, [md_dropdown], [chatbot] )
202
 
203
  def on_theme_dropdown_changed(theme, secret_css):
204
- adjust_theme, css_part1, _, adjust_dynamic_theme = load_dynamic_theme(theme)
205
  if adjust_dynamic_theme:
206
  css_part2 = adjust_dynamic_theme._get_theme_css()
207
  else:
208
- css_part2 = adjust_theme()._get_theme_css()
209
  return css_part2 + css_part1
210
 
211
  theme_handle = theme_dropdown.select(on_theme_dropdown_changed, [theme_dropdown, secret_css], [secret_css])
@@ -216,9 +390,9 @@ def main():
216
  _js=js_code_for_css_changing
217
  )
218
  # 随变按钮的回调函数注册
219
- def route(request: gr.Request, k, *args, **kwargs):
220
  if k in [r"打开插件列表", r"请先从插件列表中选择"]: return
221
- yield from ArgsGeneralWrapper(plugins[k]["Function"])(request, *args, **kwargs)
222
  click_handle = switchy_bt.click(route,[switchy_bt, *input_combo], output_combo)
223
  click_handle.then(on_report_generated, [cookies, file_upload, chatbot], [cookies, file_upload, chatbot])
224
  cancel_handles.append(click_handle)
@@ -245,9 +419,7 @@ def main():
245
  rad.feed(cookies['uuid'].hex, audio)
246
  audio_mic.stream(deal_audio, inputs=[audio_mic, cookies])
247
 
248
- # 定义从 URL 参数中提取 base_url 和 api_key 的函数(已定义上面)
249
-
250
- # 应用加载时调用该函数(已修改传递 gr.Request)
251
  # 已在上面调用
252
 
253
  # 启动 Gradio 的延迟任务
@@ -285,10 +457,5 @@ def main():
285
  # demo.launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png",
286
  # blocked_paths=["config.py","config_private.py","docker-compose.yml","Dockerfile",f"{PATH_LOGGING}/admin"])
287
 
288
- except Exception as e:
289
- print("Unhandled exception during application startup:")
290
- traceback.print_exc()
291
- sys.exit(1)
292
-
293
- if __name__ == "__main__":
294
- main()
 
1
  import os
2
  os.environ['no_proxy'] = '*' # 避免代理网络产生意外污染
3
 
4
+ help_menu_description = \
5
+ """Github源代码开源和更新[地址🚀](https://github.com/binary-husky/gpt_academic),
6
  感谢热情的[开发者们❤️](https://github.com/binary-husky/gpt_academic/graphs/contributors).
7
  </br></br>常见问题请查阅[项目Wiki](https://github.com/binary-husky/gpt_academic/wiki),
8
  如遇到Bug请前往[Bug反馈](https://github.com/binary-husky/gpt_academic/issues).
 
19
  import logging, uuid, traceback
20
 
21
  try:
22
+ # 安装指定版本的 Gradio
23
  subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'https://public.agent-matrix.com/publish/gradio-3.32.8-py3-none-any.whl'])
24
  import gradio as gr
25
  print(f"Gradio version: {gr.__version__}")
 
89
  predefined_btns = {}
90
  with gr.Blocks(title="GPT 学术优化", theme=set_theme, analytics_enabled=False, css=advanced_css) as demo:
91
  gr.HTML(title_html)
92
+ gr.HTML('''<center><a href="https://huggingface.co/spaces/qingxu98/gpt-academic?duplicate=true"><img src="https://bit.ly/3gLdBN6" alt="Duplicate Space"></a>请您打开此页面后务必点击上方的“复制空间”(Duplicate Space)按钮!<font color="#FF00FF">使用时,先在输入框填入API-KEY然后回车键提交。</font><br/>切忌在“复制空间”(Duplicate Space)之前填入API_KEY或进行提问,否则您的API_KEY将极可能被空间所有者攫取!<br/>支持任意数量的OpenAI密钥和API2D密钥共存,例如输入"openai-key1,api2d-key2",然后提交,即可同时使用两种模型接口。</center>''')
93
  secret_css, dark_mode, py_pickle_cookie = gr.Textbox(visible=False), gr.Textbox(DARK_MODE, visible=False), gr.Textbox(visible=False)
94
  cookies = gr.State(load_chat_cookies())
95
+
96
+ # 添加一个隐藏的 Textbox 用于存储 URL 参数
97
+ url_params = gr.Textbox(label="URL Parameters", visible=False)
98
+
99
  with gr_L1():
100
  with gr_L2(scale=2, elem_id="gpt-chat"):
101
  chatbot = gr.Chatbot(label=f"当前模型:{LLM_MODEL}", elem_id="gpt-chatbot")
 
119
  with gr.Row():
120
  status = gr.Markdown(f"Tip: 按Enter提交, 按Shift+Enter换行。当前模型: {LLM_MODEL} \n {proxy_info}", elem_id="state-panel")
121
 
122
+ with gr.Accordion("基础功能区", open=True, elem_id="basic-panel") as area_basic_fn:
123
+ with gr.Row():
124
+ for k in range(NUM_CUSTOM_BASIC_BTN):
125
+ customize_btn = gr.Button("自定义按钮" + str(k+1), visible=False, variant="secondary", info_str=f'基础功能区: 自定义按钮')
126
+ customize_btn.style(size="sm")
127
+ customize_btns.update({"自定义按钮" + str(k+1): customize_btn})
128
+ for k in functional:
129
+ if ("Visible" in functional[k]) and (not functional[k]["Visible"]): continue
130
+ variant = functional[k]["Color"] if "Color" in functional[k] else "secondary"
131
+ functional[k]["Button"] = gr.Button(k, variant=variant, info_str=f'基础功能区: {k}')
132
+ functional[k]["Button"].style(size="sm")
133
+ predefined_btns.update({k: functional[k]["Button"]})
134
+ with gr.Accordion("函数插件区", open=True, elem_id="plugin-panel") as area_crazy_fn:
135
+ with gr.Row():
136
+ gr.Markdown("插件可读取“输入区”文本/路径作为参数(上传文件自动修正路径)")
137
+ with gr.Row(elem_id="input-plugin-group"):
138
+ plugin_group_sel = gr.Dropdown(choices=all_plugin_groups, label='', show_label=False, value=DEFAULT_FN_GROUPS,
139
+ multiselect=True, interactive=True, elem_classes='normal_mut_select').style(container=False)
140
+ with gr.Row():
141
+ for k, plugin in plugins.items():
142
+ if not plugin.get("AsButton", True): continue
143
+ visible = True if match_group(plugin['Group'], DEFAULT_FN_GROUPS) else False
144
+ variant = plugins[k]["Color"] if "Color" in plugin else "secondary"
145
+ info = plugins[k].get("Info", k)
146
+ plugin['Button'] = plugins[k]['Button'] = gr.Button(k, variant=variant,
147
+ visible=visible, info_str=f'函数插件区: {info}').style(size="sm")
148
+ with gr.Row():
149
+ with gr.Accordion("更多函数插件", open=True):
150
+ dropdown_fn_list = []
151
+ for k, plugin in plugins.items():
152
+ if not match_group(plugin['Group'], DEFAULT_FN_GROUPS): continue
153
+ if not plugin.get("AsButton", True): dropdown_fn_list.append(k) # 排除已经是按钮的插件
154
+ elif plugin.get('AdvancedArgs', False): dropdown_fn_list.append(k) # 对于需要高级参数的插件,亦在下拉菜单中显示
155
+ with gr.Row():
156
+ dropdown = gr.Dropdown(dropdown_fn_list, value=r"打开插件列表", label="", show_label=False).style(container=False)
157
+ with gr.Row():
158
+ plugin_advanced_arg = gr.Textbox(show_label=True, label="高级参数输入区", visible=False,
159
+ placeholder="这里是特殊函数插件的高级参数输入区").style(container=False)
160
+ with gr.Row():
161
+ switchy_bt = gr.Button(r"请先从插件列表中选择", variant="secondary").style(size="sm")
162
+ with gr.Row():
163
+ with gr.Accordion("点击展开“文件下载区”。", open=False) as area_file_up:
164
+ file_upload = gr.Files(label="任何文件, 推荐上传压缩文件(zip, tar)", file_count="multiple", elem_id="elem_upload")
165
+
166
+ with gr.Floating(init_x="0%", init_y="0%", visible=True, width=None, drag="forbidden", elem_id="tooltip"):
167
+ with gr.Row():
168
+ with gr.Tab("上传文件", elem_id="interact-panel"):
169
+ gr.Markdown("请上传本地文件/压缩包供“函数插件区”功能调用。请注意: 上传文件后会自动把输入区修改为相应路径。")
170
+ file_upload_2 = gr.Files(label="任何文件, 推荐上传压缩文件(zip, tar)", file_count="multiple", elem_id="elem_upload_float")
171
+
172
+ with gr.Tab("更换模型", elem_id="interact-panel"):
173
+ md_dropdown = gr.Dropdown(AVAIL_LLM_MODELS, value=LLM_MODEL, label="更换LLM模型/请求源").style(container=False)
174
+ top_p = gr.Slider(minimum=0, maximum=1.0, value=1.0, step=0.01,interactive=True, label="Top-p (nucleus sampling)",)
175
+ temperature = gr.Slider(minimum=0, maximum=2.0, value=1.0, step=0.01, interactive=True, label="Temperature",)
176
+ max_length_sl = gr.Slider(minimum=256, maximum=1024*32, value=4096, step=128, interactive=True, label="Local LLM MaxLength",)
177
+ system_prompt = gr.Textbox(show_label=True, lines=2, placeholder=f"System Prompt", label="System prompt", value=INIT_SYS_PROMPT)
178
+
179
+ with gr.Tab("界面外观", elem_id="interact-panel"):
180
+ theme_dropdown = gr.Dropdown(AVAIL_THEMES, value=THEME, label="更换UI主题").style(container=False)
181
+ checkboxes = gr.CheckboxGroup(["基础功能区", "函数插件区", "浮动输入区", "输入清除键", "插件参数区"], value=["基础功能区", "函数插件区"], label="显示/隐藏功能区", elem_id='cbs').style(container=False)
182
+ opt = ["自定义菜单"]
183
+ value=[]
184
+ if ADD_WAIFU: opt += ["添加Live2D形象"]; value += ["添加Live2D形象"]
185
+ checkboxes_2 = gr.CheckboxGroup(opt, value=value, label="显示/隐藏自定义菜单", elem_id='cbsc').style(container=False)
186
+ dark_mode_btn = gr.Button("切换界面明暗 ☀", variant="secondary").style(size="sm")
187
+ dark_mode_btn.click(None, None, None, _js=js_code_for_toggle_darkmode)
188
+ with gr.Tab("帮助", elem_id="interact-panel"):
189
+ gr.Markdown(help_menu_description)
190
+
191
+ with gr.Floating(init_x="20%", init_y="50%", visible=False, width="40%", drag="top") as area_input_secondary:
192
+ with gr.Accordion("浮动输入区", open=True, elem_id="input-panel2"):
193
+ with gr.Row() as row:
194
+ row.style(equal_height=True)
195
+ with gr.Column(scale=10):
196
+ txt2 = gr.Textbox(show_label=False, placeholder="Input question here.",
197
+ elem_id='user_input_float', lines=8, label="输入区2").style(container=False)
198
+ with gr.Column(scale=1, min_width=40):
199
+ submitBtn2 = gr.Button("提交", variant="primary"); submitBtn2.style(size="sm")
200
+ resetBtn2 = gr.Button("重置", variant="secondary"); resetBtn2.style(size="sm")
201
+ stopBtn2 = gr.Button("停止", variant="secondary"); stopBtn2.style(size="sm")
202
+ clearBtn2 = gr.Button("清除", elem_id="elem_clear2", variant="secondary", visible=False); clearBtn2.style(size="sm")
203
+
204
+ with gr.Floating(init_x="20%", init_y="50%", visible=False, width="40%", drag="top") as area_customize:
205
+ with gr.Accordion("自定义菜单", open=True, elem_id="edit-panel"):
206
+ with gr.Row() as row:
207
+ with gr.Column(scale=10):
208
+ AVAIL_BTN = [btn for btn in customize_btns.keys()] + [k for k in functional]
209
+ basic_btn_dropdown = gr.Dropdown(AVAIL_BTN, value="自定义按钮1", label="选择一个需要自定义基础功能区按钮").style(container=False)
210
+ basic_fn_title = gr.Textbox(show_label=False, placeholder="输入新按钮名称", lines=1).style(container=False)
211
+ basic_fn_prefix = gr.Textbox(show_label=False, placeholder="输入新提示前缀", lines=4).style(container=False)
212
+ basic_fn_suffix = gr.Textbox(show_label=False, placeholder="输入新提示后缀", lines=4).style(container=False)
213
+ with gr.Column(scale=1, min_width=70):
214
+ basic_fn_confirm = gr.Button("确认并保存", variant="primary"); basic_fn_confirm.style(size="sm")
215
+ basic_fn_clean = gr.Button("恢复默认", variant="primary"); basic_fn_clean.style(size="sm")
216
 
217
+ def assign_btn(persistent_cookie_, cookies_, basic_btn_dropdown_, basic_fn_title, basic_fn_prefix, basic_fn_suffix, clean_up=False):
218
+ ret = {}
219
+ # 读取之前的自定义按钮
220
+ customize_fn_overwrite_ = cookies_['customize_fn_overwrite']
221
+ # 更新新的自定义按钮
222
+ customize_fn_overwrite_.update({
223
+ basic_btn_dropdown_:
224
+ {
225
+ "Title":basic_fn_title,
226
+ "Prefix":basic_fn_prefix,
227
+ "Suffix":basic_fn_suffix,
228
+ }
229
+ }
230
+ )
231
+ if clean_up:
232
+ customize_fn_overwrite_ = {}
233
+ cookies_.update(customize_fn_overwrite_) # 更新cookie
234
+ visible = (not clean_up) and (basic_fn_title != "")
235
+ if basic_btn_dropdown_ in customize_btns:
236
+ # 是自定义按钮,不是预定义按钮
237
+ ret.update({customize_btns[basic_btn_dropdown_]: gr.update(visible=visible, value=basic_fn_title)})
238
+ else:
239
+ # 是预定义按钮
240
+ ret.update({predefined_btns[basic_btn_dropdown_]: gr.update(visible=visible, value=basic_fn_title)})
241
+ ret.update({cookies: cookies_})
242
+ try: persistent_cookie_ = from_cookie_str(persistent_cookie_) # persistent cookie to dict
243
+ except: persistent_cookie_ = {}
244
+ persistent_cookie_["custom_bnt"] = customize_fn_overwrite_ # dict update new value
245
+ persistent_cookie_ = to_cookie_str(persistent_cookie_) # persistent cookie to dict
246
+ ret.update({py_pickle_cookie: persistent_cookie_}) # write persistent cookie
247
+ return ret
248
+
249
+ # update btn
250
+ h = basic_fn_confirm.click(assign_btn, [py_pickle_cookie, cookies, basic_btn_dropdown, basic_fn_title, basic_fn_prefix, basic_fn_suffix],
251
+ [py_pickle_cookie, cookies, *customize_btns.values(), *predefined_btns.values()])
252
+ h.then(None, [py_pickle_cookie], None, _js="""(py_pickle_cookie)=>{setCookie("py_pickle_cookie", py_pickle_cookie, 365);}""")
253
+ # clean up btn
254
+ h2 = basic_fn_clean.click(assign_btn, [py_pickle_cookie, cookies, basic_btn_dropdown, basic_fn_title, basic_fn_prefix, basic_fn_suffix, gr.State(True)],
255
+ [py_pickle_cookie, cookies, *customize_btns.values(), *predefined_btns.values()])
256
+ h2.then(None, [py_pickle_cookie], None, _js="""(py_pickle_cookie)=>{setCookie("py_pickle_cookie", py_pickle_cookie, 365);}""")
257
+
258
+ def persistent_cookie_reload(persistent_cookie_, cookies_):
259
+ ret = {}
260
+ for k in customize_btns:
261
+ ret.update({customize_btns[k]: gr.update(visible=False, value="")})
262
+
263
+ try: persistent_cookie_ = from_cookie_str(persistent_cookie_) # persistent cookie to dict
264
+ except: return ret
265
+
266
+ customize_fn_overwrite_ = persistent_cookie_.get("custom_bnt", {})
267
+ cookies_['customize_fn_overwrite'] = customize_fn_overwrite_
268
+ ret.update({cookies: cookies_})
269
+
270
+ for k,v in persistent_cookie_["custom_bnt"].items():
271
+ if v['Title'] == "": continue
272
+ if k in customize_btns: ret.update({customize_btns[k]: gr.update(visible=True, value=v['Title'])})
273
+ else: ret.update({predefined_btns[k]: gr.update(visible=True, value=v['Title'])})
274
+ return ret
275
+
276
+ # 添加 JavaScript 来解析 URL 参数并设置到隐藏的 Textbox
277
+ url_param_js = """
278
+ <script>
279
+ window.onload = function() {
280
+ const params = new URLSearchParams(window.location.search);
281
+ let base_url = params.get('base_url') || '';
282
+ let api_key = params.get('api_key') || '';
283
+ let combined = `base_url=${encodeURIComponent(base_url)}&api_key=${encodeURIComponent(api_key)}`;
284
+ // 将解析后的参数设置到隐藏的 Textbox
285
+ const urlParamsTextbox = document.querySelector('input[aria-label="URL Parameters"]');
286
+ if (urlParamsTextbox) {
287
+ urlParamsTextbox.value = combined;
288
+ }
289
+ }
290
+ </script>
291
+ """
292
+ gr.HTML(url_param_js)
293
+
294
+ # 定义从隐藏的 Textbox 中提取 base_url 和 api_key 的函数
295
+ def extract_api_credentials(url_params, cookies):
296
  try:
297
+ # 解析 URL 参数
298
+ parsed = dict(param.split('=') for param in url_params.split('&') if '=' in param)
299
+ base_url = parsed.get('base_url', None)
300
+ api_key = parsed.get('api_key', None)
301
+
302
  print(f"Extracted base_url: {base_url}")
303
  print(f"Extracted api_key: {api_key}")
304
+
305
  # 更新 cookies 或应用程序状态
306
  if base_url:
307
  cookies['base_url'] = base_url
308
  if api_key:
309
  cookies['api_key'] = api_key # 警告:通过 URL 传递 API 密钥是不安全的
310
+
311
  return cookies
312
  except Exception as e:
313
  print(f"Error in extract_api_credentials: {e}")
314
  return cookies
315
 
316
+ # 在应用加载时调用该函数,通过隐藏的 Textbox 获取 URL 参数
317
  demo.load(
318
  fn=extract_api_credentials,
319
+ inputs=[url_params, cookies],
320
  outputs=[cookies]
321
  )
322
 
 
375
  md_dropdown.select(on_md_dropdown_changed, [md_dropdown], [chatbot] )
376
 
377
  def on_theme_dropdown_changed(theme, secret_css):
378
+ adjust_theme_func, css_part1, _, adjust_dynamic_theme = load_dynamic_theme(theme)
379
  if adjust_dynamic_theme:
380
  css_part2 = adjust_dynamic_theme._get_theme_css()
381
  else:
382
+ css_part2 = adjust_theme_func()._get_theme_css()
383
  return css_part2 + css_part1
384
 
385
  theme_handle = theme_dropdown.select(on_theme_dropdown_changed, [theme_dropdown, secret_css], [secret_css])
 
390
  _js=js_code_for_css_changing
391
  )
392
  # 随变按钮的回调函数注册
393
+ def route(k, *args, **kwargs):
394
  if k in [r"打开插件列表", r"请先从插件列表中选择"]: return
395
+ return ArgsGeneralWrapper(plugins[k]["Function"])(*args, **kwargs)
396
  click_handle = switchy_bt.click(route,[switchy_bt, *input_combo], output_combo)
397
  click_handle.then(on_report_generated, [cookies, file_upload, chatbot], [cookies, file_upload, chatbot])
398
  cancel_handles.append(click_handle)
 
419
  rad.feed(cookies['uuid'].hex, audio)
420
  audio_mic.stream(deal_audio, inputs=[audio_mic, cookies])
421
 
422
+ # 定义从隐藏的 Textbox 中提取 base_url 和 api_key 的函数(已定义上面)
 
 
423
  # 已在上面调用
424
 
425
  # 启动 Gradio 的延迟任务
 
457
  # demo.launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png",
458
  # blocked_paths=["config.py","config_private.py","docker-compose.yml","Dockerfile",f"{PATH_LOGGING}/admin"])
459
 
460
+ if __name__ == "__main__":
461
+ main()