innoai commited on
Commit
6324099
·
verified ·
1 Parent(s): a6cfdd7

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +127 -0
app.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ 示例:从远程下载一个 .zip 文件(其中含唯一的 .py 脚本),
4
+ 使用唯一文件名和目录名,避免与已有同名文件互相覆盖。
5
+ 下载与解压完成后,动态加载并执行其中的 Python 代码。
6
+
7
+ 使用方法:
8
+ 1. 将 REMOTE_CODE_URL 替换为实际的 ZIP 文件地址;
9
+ 2. 运行本脚本,即可自动下载 ZIP、解压唯一的 .py 文件并执行 build_app()。
10
+
11
+ 注意:
12
+ - ZIP 包内必须包含且只包含 1 个可执行的 .py 文件;
13
+ - 被执行的 .py 文件内需要有一个名为 build_app() 的函数,返回 Gradio 程序实例;
14
+ - 如果需要保留下载的 ZIP 及解压内容,可自行注释掉最后的清理逻辑。
15
+ """
16
+
17
+ import requests
18
+ import zipfile
19
+ import importlib.util
20
+ import os
21
+ import shutil
22
+ from datetime import datetime
23
+
24
+ # 远程 ZIP 文件地址(假设其中只含一个 .py 文件,且该文件内有 build_app() 函数)
25
+ REMOTE_CODE_URL = "https://pycodes.webgpu.click/qrcode/qrcode_en.zip"
26
+
27
+ def download_zip(remote_url, local_zipfile):
28
+ """
29
+ 从远程下载 ZIP 文件并保存到本地 local_zipfile 路径。
30
+ 如果下载成功,则会在当前目录生成名为 local_zipfile 的文件。
31
+ """
32
+ print(f"开始下载 ZIP 文件:{remote_url}")
33
+ response = requests.get(remote_url, stream=True)
34
+ if response.status_code == 200:
35
+ with open(local_zipfile, "wb") as f:
36
+ for chunk in response.iter_content(chunk_size=8192):
37
+ if chunk:
38
+ f.write(chunk)
39
+ print(f"ZIP 文件已下载至:{local_zipfile}")
40
+ else:
41
+ raise Exception(f"无法下载 ZIP 文件,HTTP 状态码:{response.status_code}")
42
+
43
+ def unzip_file(local_zipfile, extract_dir):
44
+ """
45
+ 解压 ZIP 文件到指定目录 extract_dir。
46
+ 该函数会在 extract_dir 下创建对应的文件夹结构。
47
+ """
48
+ print(f"开始解压 ZIP 文件:{local_zipfile}")
49
+ if not os.path.exists(extract_dir):
50
+ os.makedirs(extract_dir, exist_ok=True)
51
+
52
+ with zipfile.ZipFile(local_zipfile, "r") as zip_ref:
53
+ zip_ref.extractall(extract_dir)
54
+
55
+ print(f"ZIP 文件已解压到目录:{extract_dir}")
56
+
57
+ def find_py_file(extract_dir):
58
+ """
59
+ 在解压后目录中查找唯一的 .py 文件,并返回它的完整路径。
60
+ 若未找到或找到多个,将抛出异常。
61
+ """
62
+ py_files = []
63
+ for root, dirs, files in os.walk(extract_dir):
64
+ for file in files:
65
+ if file.lower().endswith(".py"):
66
+ py_files.append(os.path.join(root, file))
67
+
68
+ if len(py_files) == 0:
69
+ raise FileNotFoundError("解压目录内未找到任何 .py 文件!请检查 ZIP 包内容。")
70
+ elif len(py_files) > 1:
71
+ raise RuntimeError("在 ZIP 包中找到多个 .py 文件,无法确定要执行哪一个!")
72
+ else:
73
+ return py_files[0]
74
+
75
+ def execute_py_file(py_file_path):
76
+ """
77
+ 动态加载并执行指定路径下的 .py 文件。
78
+ 要求此文件中必须含有 build_app() 函数,用于启动 Gradio 应用。
79
+ """
80
+ print(f"正在动态加载并执行 Python 文件:{py_file_path}")
81
+ spec = importlib.util.spec_from_file_location("dynamic_module", py_file_path)
82
+ dynamic_module = importlib.util.module_from_spec(spec)
83
+ spec.loader.exec_module(dynamic_module)
84
+
85
+ if not hasattr(dynamic_module, "build_app"):
86
+ raise AttributeError("在下载的脚本中未找到名为 build_app() 的函数!")
87
+
88
+ print("调用 build_app() 启动 Gradio 应用……")
89
+ app = dynamic_module.build_app()
90
+ app.launch()
91
+
92
+ def main():
93
+ """
94
+ 主函数:
95
+ 1. 使用唯一文件名下载 ZIP;
96
+ 2. 使用唯一目录名解压 ZIP;
97
+ 3. 查找唯一的 .py 文件并执行;
98
+ 4. 运行结束后,清理下载的 .zip 与解压目录(可按需求修改)。
99
+ """
100
+ # 为避免同名文件相互覆盖,我们使用当前时间作为后缀
101
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
102
+ local_zipfile = f"downloaded_app_{timestamp}.zip"
103
+ extract_dir = f"extracted_code_{timestamp}"
104
+
105
+ try:
106
+ # 1. 下载 ZIP 文件
107
+ download_zip(REMOTE_CODE_URL, local_zipfile)
108
+
109
+ # 2. 解压 ZIP 文件
110
+ unzip_file(local_zipfile, extract_dir)
111
+
112
+ # 3. 查找唯一的 .py 文件
113
+ py_file_path = find_py_file(extract_dir)
114
+
115
+ # 4. 动态加载并执行 .py 文件
116
+ execute_py_file(py_file_path)
117
+
118
+ finally:
119
+ # 以下为可选清理操作,可根据需求进行保留或删除
120
+ if os.path.exists(local_zipfile):
121
+ os.remove(local_zipfile) # 删除已下载的 ZIP
122
+ if os.path.exists(extract_dir):
123
+ shutil.rmtree(extract_dir) # 删除解压后的文件夹
124
+ print("清理完毕。")
125
+
126
+ if __name__ == "__main__":
127
+ main()