MaktubCN commited on
Commit
c28b8a5
1 Parent(s): e27de37

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +279 -136
app.py CHANGED
@@ -1,7 +1,8 @@
1
- import os; os.environ['no_proxy'] = '*' # 避免代理网络产生意外污染
 
2
 
3
- help_menu_description = \
4
- """Github源代码开源和更新[地址🚀](https://github.com/binary-husky/gpt_academic),
5
  感谢热情的[开发者们❤️](https://github.com/binary-husky/gpt_academic/graphs/contributors).
6
  </br></br>常见问题请查阅[项目Wiki](https://github.com/binary-husky/gpt_academic/wiki),
7
  如遇到Bug请前往[Bug反馈](https://github.com/binary-husky/gpt_academic/issues).
@@ -15,137 +16,279 @@ help_menu_description = \
15
 
16
  def main():
17
  import subprocess, sys
18
- subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'https://public.agent-matrix.com/publish/gradio-3.32.8-py3-none-any.whl'])
19
- import gradio as gr
20
- if gr.__version__ not in ['3.32.8']:
21
- raise ModuleNotFoundError("使用项目内置Gradio获取最优体验! 请运行 `pip install -r requirements.txt` 指令安装内置Gradio及其他依赖, 详情信息见requirements.txt.")
22
- from request_llms.bridge_all import predict
23
- from toolbox import format_io, find_free_port, on_file_uploaded, on_report_generated, get_conf, ArgsGeneralWrapper, load_chat_cookies, DummyWith
24
- # 建议您复制一个config_private.py放自己的秘密, 如API和代理网址
25
- proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION = get_conf('proxies', 'WEB_PORT', 'LLM_MODEL', 'CONCURRENT_COUNT', 'AUTHENTICATION')
26
- CHATBOT_HEIGHT, LAYOUT, AVAIL_LLM_MODELS, AUTO_CLEAR_TXT = get_conf('CHATBOT_HEIGHT', 'LAYOUT', 'AVAIL_LLM_MODELS', 'AUTO_CLEAR_TXT')
27
- ENABLE_AUDIO, AUTO_CLEAR_TXT, PATH_LOGGING, AVAIL_THEMES, THEME, ADD_WAIFU = get_conf('ENABLE_AUDIO', 'AUTO_CLEAR_TXT', 'PATH_LOGGING', 'AVAIL_THEMES', 'THEME', 'ADD_WAIFU')
28
- DARK_MODE, NUM_CUSTOM_BASIC_BTN, SSL_KEYFILE, SSL_CERTFILE = get_conf('DARK_MODE', 'NUM_CUSTOM_BASIC_BTN', 'SSL_KEYFILE', 'SSL_CERTFILE')
29
- INIT_SYS_PROMPT = get_conf('INIT_SYS_PROMPT')
30
-
31
- # 如果WEB_PORT是-1, 则随机选取WEB端口
32
- PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT
33
- from check_proxy import get_current_version
34
- from themes.theme import adjust_theme, advanced_css, theme_declaration, js_code_clear, js_code_reset, js_code_show_or_hide, js_code_show_or_hide_group2
35
- from themes.theme import js_code_for_css_changing, js_code_for_toggle_darkmode, js_code_for_persistent_cookie_init
36
- from themes.theme import load_dynamic_theme, to_cookie_str, from_cookie_str, init_cookie
37
- title_html = f"<h1 align=\"center\">GPT 学术优化 {get_current_version()}</h1>{theme_declaration}"
38
-
39
- # 问询记录, python 版本建议3.9+(越新越好)
40
- import logging, uuid
41
- os.makedirs(PATH_LOGGING, exist_ok=True)
42
  try:
43
- logging.basicConfig(filename=f"{PATH_LOGGING}/chat_secrets.log", level=logging.INFO, encoding="utf-8",
44
- format="%(asctime)s %(levelname)-8s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
45
- except:
46
- logging.basicConfig(filename=f"{PATH_LOGGING}/chat_secrets.log", level=logging.INFO,
47
- format="%(asctime)s %(levelname)-8s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
48
- # Disable logging output from the 'httpx' logger
49
- logging.getLogger("httpx").setLevel(logging.WARNING)
50
- print(f"所有问询记录将自动保存在本地目录./{PATH_LOGGING}/chat_secrets.log, 请注意自我隐私保护哦!")
51
-
52
- # 一些普通功能模块
53
- from core_functional import get_core_functions
54
- functional = get_core_functions()
55
-
56
- # 高级函数插件
57
- from crazy_functional import get_crazy_functions
58
- DEFAULT_FN_GROUPS = get_conf('DEFAULT_FN_GROUPS')
59
- plugins = get_crazy_functions()
60
- all_plugin_groups = list(set([g for _, plugin in plugins.items() for g in plugin['Group'].split('|')]))
61
- match_group = lambda tags, groups: any([g in groups for g in tags.split('|')])
62
-
63
- # 处理markdown文本格式的转变
64
- gr.Chatbot.postprocess = format_io
65
-
66
- # 做一些外观色彩上的调整
67
- set_theme = adjust_theme()
68
-
69
- # 代理与自动更新
70
- from check_proxy import check_proxy, auto_update, warm_up_modules
71
- proxy_info = check_proxy(proxies)
72
-
73
- gr_L1 = lambda: gr.Row().style()
74
- gr_L2 = lambda scale, elem_id: gr.Column(scale=scale, elem_id=elem_id, min_width=400)
75
- if LAYOUT == "TOP-DOWN":
76
- gr_L1 = lambda: DummyWith()
77
- gr_L2 = lambda scale, elem_id: gr.Row()
78
- CHATBOT_HEIGHT /= 2
79
-
80
- cancel_handles = []
81
- customize_btns = {}
82
- predefined_btns = {}
83
- with gr.Blocks(title="GPT 学术优化", theme=set_theme, analytics_enabled=False, css=advanced_css) as demo:
84
- gr.HTML(title_html)
85
- 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>''')
86
- secret_css, dark_mode, py_pickle_cookie = gr.Textbox(visible=False), gr.Textbox(DARK_MODE, visible=False), gr.Textbox(visible=False)
87
- cookies = gr.State(load_chat_cookies())
88
- with gr_L1():
89
- with gr_L2(scale=2, elem_id="gpt-chat"):
90
- chatbot = gr.Chatbot(label=f"当前模型:{LLM_MODEL}", elem_id="gpt-chatbot")
91
- if LAYOUT == "TOP-DOWN": chatbot.style(height=CHATBOT_HEIGHT)
92
- history = gr.State([])
93
- with gr_L2(scale=1, elem_id="gpt-panel"):
94
- with gr.Accordion("输入区", open=True, elem_id="input-panel") as area_input_primary:
95
- with gr.Row():
96
- txt = gr.Textbox(show_label=False, lines=2, placeholder="输入问题或API密钥,输入多个密钥时,用英文逗号间隔。支持多个OpenAI密钥共存。").style(container=False)
97
- with gr.Row():
98
- submitBtn = gr.Button("提交", elem_id="elem_submit", variant="primary")
99
- with gr.Row():
100
- resetBtn = gr.Button("重置", elem_id="elem_reset", variant="secondary"); resetBtn.style(size="sm")
101
- stopBtn = gr.Button("停止", elem_id="elem_stop", variant="secondary"); stopBtn.style(size="sm")
102
- clearBtn = gr.Button("清除", elem_id="elem_clear", variant="secondary", visible=False); clearBtn.style(size="sm")
103
- # 如果需要启用音频,可以取消下面的注释
104
- # if ENABLE_AUDIO:
105
- # with gr.Row():
106
- # audio_mic = gr.Audio(source="microphone", type="numpy", elem_id="elem_audio", streaming=True, show_label=False).style(container=False)
107
- with gr.Row():
108
- status = gr.Markdown(f"Tip: 按Enter提交, 按Shift+Enter换行。当前模型: {LLM_MODEL} \n {proxy_info}", elem_id="state-panel")
109
-
110
- # 其他 UI 组件省略...
111
-
112
- # 定义从 URL 参数中提取 base_url 和 api_key 的函数
113
- def extract_api_credentials(request: gr.Request, cookies):
114
- # 提取 URL 参数
115
- params = request.query_params
116
- base_url = params.get('base_url', None)
117
- api_key = params.get('api_key', None)
118
-
119
- # 更新 cookies 或应用程序状态
120
- if base_url:
121
- cookies['base_url'] = base_url
122
- if api_key:
123
- cookies['api_key'] = api_key # 警告:通过 URL 传递 API 密钥是不安全的
124
-
125
- return cookies
126
-
127
- # 在应用加载时调用该函数
128
- demo.load(
129
- fn=extract_api_credentials,
130
- inputs=[cookies],
131
- outputs=[cookies]
132
- )
133
-
134
- # 准备传递给 predict 函数的输入
135
- input_combo = [cookies, max_length_sl, md_dropdown, txt, gr.Textbox(visible=False), top_p, temperature, chatbot, history, system_prompt, gr.Textbox(visible=False)]
136
- output_combo = [cookies, chatbot, history, status]
137
- predict_args = dict(fn=ArgsGeneralWrapper(predict), inputs=[*input_combo, gr.State(True)], outputs=output_combo)
138
-
139
- # 提交按钮和重置按钮
140
- cancel_handles.append(txt.submit(**predict_args))
141
- cancel_handles.append(submitBtn.click(**predict_args))
142
- resetBtn.click(None, None, [chatbot, history, status], _js=js_code_reset)
143
- resetBtn.click(lambda: ([], [], "已重置"), None, [chatbot, history, status])
144
-
145
- # 继续设置 Gradio 应用...
146
-
147
- # 启动 Gradio 应用
148
- demo.queue(concurrency_count=CONCURRENT_COUNT).launch(server_name="0.0.0.0", share=False, favicon_path="docs/logo.png", blocked_paths=["config.py","config_private.py","docker-compose.yml","Dockerfile"])
149
-
150
- if __name__ == "__main__":
151
- 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).
 
16
 
17
  def main():
18
  import subprocess, sys
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__}")
26
+ if gr.__version__ not in ['3.32.8']:
27
+ raise ModuleNotFoundError("使用项目内置Gradio获取最优体验! 请运行 `pip install -r requirements.txt` 指令安装内置Gradio及其他依赖, 详情信息见requirements.txt.")
28
+
29
+ from request_llms.bridge_all import predict
30
+ from toolbox import format_io, find_free_port, on_file_uploaded, on_report_generated, get_conf, ArgsGeneralWrapper, load_chat_cookies, DummyWith
31
+
32
+ # 获取配置
33
+ proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION = get_conf('proxies', 'WEB_PORT', 'LLM_MODEL', 'CONCURRENT_COUNT', 'AUTHENTICATION')
34
+ CHATBOT_HEIGHT, LAYOUT, AVAIL_LLM_MODELS, AUTO_CLEAR_TXT = get_conf('CHATBOT_HEIGHT', 'LAYOUT', 'AVAIL_LLM_MODELS', 'AUTO_CLEAR_TXT')
35
+ ENABLE_AUDIO, AUTO_CLEAR_TXT, PATH_LOGGING, AVAIL_THEMES, THEME, ADD_WAIFU = get_conf('ENABLE_AUDIO', 'AUTO_CLEAR_TXT', 'PATH_LOGGING', 'AVAIL_THEMES', 'THEME', 'ADD_WAIFU')
36
+ DARK_MODE, NUM_CUSTOM_BASIC_BTN, SSL_KEYFILE, SSL_CERTFILE = get_conf('DARK_MODE', 'NUM_CUSTOM_BASIC_BTN', 'SSL_KEYFILE', 'SSL_CERTFILE')
37
+ INIT_SYS_PROMPT = get_conf('INIT_SYS_PROMPT')
38
+
39
+ # 如果WEB_PORT是-1, 则随机选取WEB端口
40
+ PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT
41
+ from check_proxy import get_current_version
42
+ from themes.theme import adjust_theme, advanced_css, theme_declaration, js_code_clear, js_code_reset, js_code_show_or_hide, js_code_show_or_hide_group2
43
+ from themes.theme import js_code_for_css_changing, js_code_for_toggle_darkmode, js_code_for_persistent_cookie_init
44
+ from themes.theme import load_dynamic_theme, to_cookie_str, from_cookie_str, init_cookie
45
+ title_html = f"<h1 align=\"center\">GPT 学术优化 {get_current_version()}</h1>{theme_declaration}"
46
+
47
+ # 问询记录, python 版本建议3.9+(越新越好)
48
+ os.makedirs(PATH_LOGGING, exist_ok=True)
49
+ try:
50
+ logging.basicConfig(filename=f"{PATH_LOGGING}/chat_secrets.log", level=logging.INFO, encoding="utf-8",
51
+ format="%(asctime)s %(levelname)-8s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
52
+ except:
53
+ logging.basicConfig(filename=f"{PATH_LOGGING}/chat_secrets.log", level=logging.INFO,
54
+ format="%(asctime)s %(levelname)-8s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
55
+ # Disable logging output from the 'httpx' logger
56
+ logging.getLogger("httpx").setLevel(logging.WARNING)
57
+ print(f"所有问询记录将自动保存在本地目录./{PATH_LOGGING}/chat_secrets.log, 请注意自我隐私保护哦!")
58
+
59
+ # 一些普通功能模块
60
+ from core_functional import get_core_functions
61
+ functional = get_core_functions()
62
+
63
+ # 高级函数插件
64
+ from crazy_functional import get_crazy_functions
65
+ DEFAULT_FN_GROUPS = get_conf('DEFAULT_FN_GROUPS')
66
+ plugins = get_crazy_functions()
67
+ all_plugin_groups = list(set([g for _, plugin in plugins.items() for g in plugin['Group'].split('|')]))
68
+ match_group = lambda tags, groups: any([g in groups for g in tags.split('|')])
69
+
70
+ # 处理markdown文本格式的转变
71
+ gr.Chatbot.postprocess = format_io
72
+
73
+ # 做一些外观色彩上的调整
74
+ set_theme = adjust_theme()
75
+
76
+ # 代理与自动更新
77
+ from check_proxy import check_proxy, auto_update, warm_up_modules
78
+ proxy_info = check_proxy(proxies)
79
+
80
+ gr_L1 = lambda: gr.Row().style()
81
+ gr_L2 = lambda scale, elem_id: gr.Column(scale=scale, elem_id=elem_id, min_width=400)
82
+ if LAYOUT == "TOP-DOWN":
83
+ gr_L1 = lambda: DummyWith()
84
+ gr_L2 = lambda scale, elem_id: gr.Row()
85
+ CHATBOT_HEIGHT /= 2
86
+
87
+ cancel_handles = []
88
+ customize_btns = {}
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")
98
+ if LAYOUT == "TOP-DOWN":
99
+ chatbot.style(height=CHATBOT_HEIGHT)
100
+ history = gr.State([])
101
+ with gr_L2(scale=1, elem_id="gpt-panel"):
102
+ with gr.Accordion("输入区", open=True, elem_id="input-panel") as area_input_primary:
103
+ with gr.Row():
104
+ txt = gr.Textbox(show_label=False, lines=2, placeholder="输入问题或API密钥,输入多个密钥时,用英文逗号间隔。支持多个OpenAI密钥共存。").style(container=False)
105
+ with gr.Row():
106
+ submitBtn = gr.Button("提交", elem_id="elem_submit", variant="primary")
107
+ with gr.Row():
108
+ resetBtn = gr.Button("重置", elem_id="elem_reset", variant="secondary"); resetBtn.style(size="sm")
109
+ stopBtn = gr.Button("停止", elem_id="elem_stop", variant="secondary"); stopBtn.style(size="sm")
110
+ clearBtn = gr.Button("清除", elem_id="elem_clear", variant="secondary", visible=False); clearBtn.style(size="sm")
111
+ # 如果需要启用音频,可以取消下面的注释
112
+ # if ENABLE_AUDIO:
113
+ # with gr.Row():
114
+ # audio_mic = gr.Audio(source="microphone", type="numpy", elem_id="elem_audio", streaming=True, show_label=False).style(container=False)
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
+
149
+ # 准备传递给 predict 函数的输入
150
+ input_combo = [cookies, max_length_sl, md_dropdown, txt, txt2, top_p, temperature, chatbot, history, system_prompt, plugin_advanced_arg]
151
+ output_combo = [cookies, chatbot, history, status]
152
+ predict_args = dict(fn=ArgsGeneralWrapper(predict), inputs=[*input_combo, gr.State(True)], outputs=output_combo)
153
+
154
+ # 提交按钮和重置按钮
155
+ cancel_handles.append(txt.submit(**predict_args))
156
+ cancel_handles.append(txt2.submit(**predict_args))
157
+ cancel_handles.append(submitBtn.click(**predict_args))
158
+ cancel_handles.append(submitBtn2.click(**predict_args))
159
+ resetBtn.click(None, None, [chatbot, history, status], _js=js_code_reset) # 先在前端快速清除chatbot&status
160
+ resetBtn2.click(None, None, [chatbot, history, status], _js=js_code_reset) # 先在前端快速清除chatbot&status
161
+ resetBtn.click(lambda: ([], [], "已重置"), None, [chatbot, history, status]) # 再在后端清除history
162
+ resetBtn2.click(lambda: ([], [], "已重置"), None, [chatbot, history, status]) # 再在后端清除history
163
+ clearBtn.click(None, None, [txt, txt2], _js=js_code_clear)
164
+ clearBtn2.click(None, None, [txt, txt2], _js=js_code_clear)
165
+ if AUTO_CLEAR_TXT:
166
+ submitBtn.click(None, None, [txt, txt2], _js=js_code_clear)
167
+ submitBtn2.click(None, None, [txt, txt2], _js=js_code_clear)
168
+ txt.submit(None, None, [txt, txt2], _js=js_code_clear)
169
+ txt2.submit(None, None, [txt, txt2], _js=js_code_clear)
170
+ # 基础功能区的回调函数注册
171
+ for k in functional:
172
+ if ("Visible" in functional[k]) and (not functional[k]["Visible"]): continue
173
+ click_handle = functional[k]["Button"].click(fn=ArgsGeneralWrapper(predict), inputs=[*input_combo, gr.State(True), gr.State(k)], outputs=output_combo)
174
+ cancel_handles.append(click_handle)
175
+ for btn in customize_btns.values():
176
+ click_handle = btn.click(fn=ArgsGeneralWrapper(predict), inputs=[*input_combo, gr.State(True), gr.State(btn.value)], outputs=output_combo)
177
+ cancel_handles.append(click_handle)
178
+ # 文件上传区,接收文件后与chatbot的互动
179
+ file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt, txt2, checkboxes, cookies], [chatbot, txt, txt2, cookies]).then(None, None, None, _js=r"()=>{toast_push('上传完毕 ...'); cancel_loading_status();}")
180
+ file_upload_2.upload(on_file_uploaded, [file_upload_2, chatbot, txt, txt2, checkboxes, cookies], [chatbot, txt, txt2, cookies]).then(None, None, None, _js=r"()=>{toast_push('上传完毕 ...'); cancel_loading_status();}")
181
+ # 函数插件-固定按钮区
182
+ for k in plugins:
183
+ if not plugins[k].get("AsButton", True): continue
184
+ click_handle = plugins[k]["Button"].click(ArgsGeneralWrapper(plugins[k]["Function"]), [*input_combo], output_combo)
185
+ click_handle.then(on_report_generated, [cookies, file_upload, chatbot], [cookies, file_upload, chatbot])
186
+ cancel_handles.append(click_handle)
187
+ # 函数插件-下拉菜单与随变按钮的互动
188
+ def on_dropdown_changed(k):
189
+ variant = plugins[k]["Color"] if "Color" in plugins else "secondary"
190
+ info = plugins[k].get("Info", k)
191
+ ret = {switchy_bt: gr.update(value=k, variant=variant, info_str=f'函数插件区: {info}')}
192
+ if plugins[k].get("AdvancedArgs", False): # 是否唤起高级插件参数区
193
+ ret.update({plugin_advanced_arg: gr.update(visible=True, label=f"插件[{k}]的高级参数说明:" + plugins[k].get("ArgsReminder", [f"没有提供高级参数功能说明"]))})
194
+ else:
195
+ ret.update({plugin_advanced_arg: gr.update(visible=False, label=f"插件[{k}]不需要高级参数。")})
196
+ return ret
197
+ dropdown.select(on_dropdown_changed, [dropdown], [switchy_bt, plugin_advanced_arg] )
198
+
199
+ def on_md_dropdown_changed(k):
200
+ return {chatbot: gr.update(label="当前模型:"+k)}
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])
212
+ theme_handle.then(
213
+ None,
214
+ [secret_css],
215
+ None,
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)
225
+ # 终止按钮的回调函数注册
226
+ stopBtn.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
227
+ stopBtn2.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
228
+ plugins_as_btn = {name:plugin for name, plugin in plugins.items() if plugin.get('Button', None)}
229
+ def on_group_change(group_list):
230
+ btn_list = []
231
+ fns_list = []
232
+ if not group_list: # 处理特殊情况:没有选择任何插件组
233
+ return [*[plugin['Button'].update(visible=False) for _, plugin in plugins_as_btn.items()], gr.Dropdown.update(choices=[])]
234
+ for k, plugin in plugins.items():
235
+ if plugin.get("AsButton", True):
236
+ btn_list.append(plugin['Button'].update(visible=match_group(plugin['Group'], group_list))) # 刷新按钮
237
+ if plugin.get('AdvancedArgs', False): fns_list.append(k) # 对于需要高级参数的插件,亦在下拉菜单中显示
238
+ elif match_group(plugin['Group'], group_list): fns_list.append(k) # 刷新下拉列表
239
+ return [*btn_list, gr.Dropdown.update(choices=fns_list)]
240
+ plugin_group_sel.select(fn=on_group_change, inputs=[plugin_group_sel], outputs=[*[plugin['Button'] for name, plugin in plugins_as_btn.items()], dropdown])
241
+ if ENABLE_AUDIO:
242
+ from crazy_functions.live_audio.audio_io import RealtimeAudioDistribution
243
+ rad = RealtimeAudioDistribution()
244
+ def deal_audio(audio, cookies):
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 的延迟任务
254
+ def run_delayed_tasks():
255
+ import threading, webbrowser, time
256
+ print(f"如果浏览器没有自动打开,请复制并转到以下URL:")
257
+ if DARK_MODE:
258
+ print(f"\t「暗色主题已启用(支持动态切换主题)」: http://localhost:{PORT}")
259
+ else:
260
+ print(f"\t「亮色主题已启用(支持动态切换主题)」: http://localhost:{PORT}")
261
+
262
+ def auto_updates():
263
+ time.sleep(0)
264
+ auto_update()
265
+ def open_browser():
266
+ time.sleep(2)
267
+ webbrowser.open_new_tab(f"http://localhost:{PORT}")
268
+ def warm_up_mods():
269
+ time.sleep(6)
270
+ warm_up_modules()
271
+
272
+ threading.Thread(target=auto_updates, name="self-upgrade", daemon=True).start() # 查看自动更新
273
+ threading.Thread(target=open_browser, name="open-browser", daemon=True).start() # 打开浏览器页面
274
+ threading.Thread(target=warm_up_mods, name="warm-up", daemon=True).start() # 预热tiktoken模块
275
+
276
+ run_delayed_tasks()
277
+ demo.queue(concurrency_count=CONCURRENT_COUNT).launch(server_name="0.0.0.0", share=False, favicon_path="docs/logo.png", blocked_paths=["config.py","config_private.py","docker-compose.yml","Dockerfile"])
278
+
279
+ # 如果需要在二级路径下运行
280
+ # CUSTOM_PATH = get_conf('CUSTOM_PATH')
281
+ # if CUSTOM_PATH != "/":
282
+ # from toolbox import run_gradio_in_subpath
283
+ # run_gradio_in_subpath(demo, auth=AUTHENTICATION, port=PORT, custom_path=CUSTOM_PATH)
284
+ # else:
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()