Spaces:
Running
Running
Update app.py
Browse files
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 |
-
#
|
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
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
|
120 |
-
|
121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
try:
|
123 |
-
#
|
124 |
-
|
125 |
-
base_url =
|
126 |
-
api_key =
|
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 |
-
#
|
143 |
demo.load(
|
144 |
fn=extract_api_credentials,
|
145 |
-
inputs=[
|
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 |
-
|
205 |
if adjust_dynamic_theme:
|
206 |
css_part2 = adjust_dynamic_theme._get_theme_css()
|
207 |
else:
|
208 |
-
css_part2 =
|
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(
|
220 |
if k in [r"打开插件列表", r"请先从插件列表中选择"]: return
|
221 |
-
|
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 |
-
#
|
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 |
-
|
289 |
-
|
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()
|
|
|
|
|
|
|
|
|
|