Update app.py
Browse files
app.py
CHANGED
@@ -8,6 +8,9 @@ from urllib.parse import urlparse, urljoin
|
|
8 |
from typing import Dict, Any, Optional, List
|
9 |
from dataclasses import dataclass
|
10 |
from datetime import datetime
|
|
|
|
|
|
|
11 |
|
12 |
# 配置日志
|
13 |
logging.basicConfig(
|
@@ -19,7 +22,7 @@ logging.basicConfig(
|
|
19 |
class ProxyResponse:
|
20 |
"""代理响应数据类"""
|
21 |
status: int
|
22 |
-
content:
|
23 |
headers: Dict[str, str]
|
24 |
redirect_url: Optional[str] = None
|
25 |
error: Optional[str] = None
|
@@ -167,7 +170,7 @@ class GitHubProxy:
|
|
167 |
error="服务器内部错误"
|
168 |
)
|
169 |
|
170 |
-
def proxy_request(self, url: str, request:
|
171 |
"""处理代理请求"""
|
172 |
# 记录请求
|
173 |
logging.info(f"Proxy request from {request.client.host} to {url}")
|
@@ -233,20 +236,27 @@ class GitHubProxy:
|
|
233 |
|
234 |
return result
|
235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
def create_interface():
|
237 |
"""创建Gradio界面"""
|
238 |
proxy = GitHubProxy()
|
239 |
|
240 |
-
|
|
|
241 |
"""处理直接代理请求"""
|
242 |
-
# 从路径中提取GitHub URL
|
243 |
-
path = request.headers.get('x-path', '')
|
244 |
if not path:
|
245 |
-
return
|
246 |
-
|
247 |
-
# 移除开头的斜杠
|
248 |
-
if path.startswith('/'):
|
249 |
-
path = path[1:]
|
250 |
|
251 |
# 检查并处理URL
|
252 |
if not path.startswith(('http://', 'https://')):
|
@@ -257,34 +267,27 @@ def create_interface():
|
|
257 |
response = proxy.proxy_request(path, request)
|
258 |
|
259 |
if 'error' in response:
|
260 |
-
return
|
261 |
|
262 |
if 'redirect_url' in response:
|
263 |
-
return
|
264 |
|
265 |
# 获取文件内容(使用流式传输)
|
266 |
proxy_response = proxy.fetch_github_content(path, stream=True)
|
267 |
if proxy_response.error:
|
268 |
-
return
|
269 |
|
270 |
-
#
|
271 |
-
headers =
|
272 |
-
|
273 |
-
|
274 |
-
}
|
275 |
-
return gr.FileBinaryResponse(
|
276 |
-
proxy_response.content.raw,
|
277 |
headers=headers,
|
278 |
-
|
279 |
)
|
280 |
|
281 |
except Exception as e:
|
282 |
logging.error(f"Proxy error: {str(e)}")
|
283 |
-
return
|
284 |
-
|
285 |
-
# 添加直接代理路由
|
286 |
-
app = gr.App()
|
287 |
-
app.add_route("/.*", proxy_download, method="GET")
|
288 |
|
289 |
with gr.Blocks(title="GitHub Proxy", theme=gr.themes.Soft()) as blocks:
|
290 |
gr.Markdown("""
|
@@ -355,14 +358,12 @@ def create_interface():
|
|
355 |
inputs=url_input
|
356 |
)
|
357 |
|
358 |
-
|
359 |
-
|
|
|
|
|
360 |
|
361 |
if __name__ == "__main__":
|
|
|
362 |
app = create_interface()
|
363 |
-
app.
|
364 |
-
server_name="0.0.0.0",
|
365 |
-
server_port=7860,
|
366 |
-
show_error=True,
|
367 |
-
quiet=False
|
368 |
-
)
|
|
|
8 |
from typing import Dict, Any, Optional, List
|
9 |
from dataclasses import dataclass
|
10 |
from datetime import datetime
|
11 |
+
from fastapi import FastAPI, Request
|
12 |
+
from fastapi.responses import StreamingResponse, RedirectResponse, JSONResponse
|
13 |
+
from fastapi.middleware.cors import CORSMiddleware
|
14 |
|
15 |
# 配置日志
|
16 |
logging.basicConfig(
|
|
|
22 |
class ProxyResponse:
|
23 |
"""代理响应数据类"""
|
24 |
status: int
|
25 |
+
content: Any
|
26 |
headers: Dict[str, str]
|
27 |
redirect_url: Optional[str] = None
|
28 |
error: Optional[str] = None
|
|
|
170 |
error="服务器内部错误"
|
171 |
)
|
172 |
|
173 |
+
def proxy_request(self, url: str, request: Request) -> Dict[str, Any]:
|
174 |
"""处理代理请求"""
|
175 |
# 记录请求
|
176 |
logging.info(f"Proxy request from {request.client.host} to {url}")
|
|
|
236 |
|
237 |
return result
|
238 |
|
239 |
+
# 创建 FastAPI 应用
|
240 |
+
api = FastAPI()
|
241 |
+
|
242 |
+
# 配置 CORS
|
243 |
+
api.add_middleware(
|
244 |
+
CORSMiddleware,
|
245 |
+
allow_origins=["*"],
|
246 |
+
allow_credentials=True,
|
247 |
+
allow_methods=["*"],
|
248 |
+
allow_headers=["*"],
|
249 |
+
)
|
250 |
+
|
251 |
def create_interface():
|
252 |
"""创建Gradio界面"""
|
253 |
proxy = GitHubProxy()
|
254 |
|
255 |
+
@api.get("/{path:path}")
|
256 |
+
async def proxy_download(request: Request, path: str):
|
257 |
"""处理直接代理请求"""
|
|
|
|
|
258 |
if not path:
|
259 |
+
return JSONResponse({"error": "无效的请求路径"}, status_code=400)
|
|
|
|
|
|
|
|
|
260 |
|
261 |
# 检查并处理URL
|
262 |
if not path.startswith(('http://', 'https://')):
|
|
|
267 |
response = proxy.proxy_request(path, request)
|
268 |
|
269 |
if 'error' in response:
|
270 |
+
return JSONResponse({"error": response['error']}, status_code=response['status'])
|
271 |
|
272 |
if 'redirect_url' in response:
|
273 |
+
return RedirectResponse(response['redirect_url'])
|
274 |
|
275 |
# 获取文件内容(使用流式传输)
|
276 |
proxy_response = proxy.fetch_github_content(path, stream=True)
|
277 |
if proxy_response.error:
|
278 |
+
return JSONResponse({"error": proxy_response.error}, status_code=proxy_response.status)
|
279 |
|
280 |
+
# 返回流式响应
|
281 |
+
headers = dict(proxy_response.headers)
|
282 |
+
return StreamingResponse(
|
283 |
+
proxy_response.content.iter_content(chunk_size=8192),
|
|
|
|
|
|
|
284 |
headers=headers,
|
285 |
+
status_code=proxy_response.status
|
286 |
)
|
287 |
|
288 |
except Exception as e:
|
289 |
logging.error(f"Proxy error: {str(e)}")
|
290 |
+
return JSONResponse({"error": f"代理请求失败: {str(e)}"}, status_code=500)
|
|
|
|
|
|
|
|
|
291 |
|
292 |
with gr.Blocks(title="GitHub Proxy", theme=gr.themes.Soft()) as blocks:
|
293 |
gr.Markdown("""
|
|
|
358 |
inputs=url_input
|
359 |
)
|
360 |
|
361 |
+
# 将 Gradio 界面挂载到 FastAPI
|
362 |
+
blocks.queue()
|
363 |
+
api.mount("/ui", blocks)
|
364 |
+
return api
|
365 |
|
366 |
if __name__ == "__main__":
|
367 |
+
import uvicorn
|
368 |
app = create_interface()
|
369 |
+
uvicorn.run(app, host="0.0.0.0", port=7860)
|
|
|
|
|
|
|
|
|
|