agagsder commited on
Commit
10cd7fe
·
verified ·
1 Parent(s): 0facd40

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +12 -0
  2. app.py +89 -0
  3. requirements.txt +3 -0
Dockerfile ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+ RUN pip install --no-cache-dir -r requirements.txt
7
+
8
+ COPY app.py .
9
+
10
+ EXPOSE 7860
11
+
12
+ CMD ["gunicorn", "-b", "0.0.0.0:7860", "app:app"]
app.py ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Hugging Face Space - Cloudflare Worker 代理
4
+ 部署到 Hugging Face Spaces,用于国内访问 Cloudflare Worker API
5
+ """
6
+
7
+ from flask import Flask, request, Response
8
+ import requests
9
+ import os
10
+
11
+ app = Flask(__name__)
12
+
13
+ # Cloudflare Worker 地址
14
+ WORKER_URL = "https://license-api.yunzun8.workers.dev"
15
+
16
+ # 代理访问密钥(防止滥用)
17
+ PROXY_KEY = os.environ.get("PROXY_KEY", "your_proxy_key_here")
18
+
19
+ @app.route("/", methods=["GET"])
20
+ def index():
21
+ return {"status": "ok", "message": "License API Proxy"}
22
+
23
+ @app.route("/<path:path>", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"])
24
+ def proxy(path):
25
+ """代理所有请求到 Cloudflare Worker"""
26
+
27
+ # 验证代理密钥(从 header 或 query 获取)
28
+ proxy_key = request.headers.get("X-Proxy-Key") or request.args.get("proxy_key")
29
+ if proxy_key != PROXY_KEY:
30
+ return {"success": False, "error": "unauthorized", "message": "Invalid proxy key"}, 401
31
+
32
+ # 构建目标 URL
33
+ target_url = f"{WORKER_URL}/{path}"
34
+
35
+ # 获取查询参数(排除 proxy_key)
36
+ query_params = {k: v for k, v in request.args.items() if k != "proxy_key"}
37
+ if query_params:
38
+ query_string = "&".join(f"{k}={v}" for k, v in query_params.items())
39
+ target_url += f"?{query_string}"
40
+
41
+ # 准备请求头
42
+ headers = {
43
+ "Content-Type": request.content_type or "application/json",
44
+ }
45
+
46
+ try:
47
+ # 转发请求
48
+ if request.method == "GET":
49
+ resp = requests.get(target_url, headers=headers, timeout=30)
50
+ elif request.method == "POST":
51
+ resp = requests.post(target_url, headers=headers, data=request.get_data(), timeout=30)
52
+ elif request.method == "PUT":
53
+ resp = requests.put(target_url, headers=headers, data=request.get_data(), timeout=30)
54
+ elif request.method == "DELETE":
55
+ resp = requests.delete(target_url, headers=headers, timeout=30)
56
+ elif request.method == "OPTIONS":
57
+ # CORS 预检请求
58
+ return Response(
59
+ "",
60
+ status=200,
61
+ headers={
62
+ "Access-Control-Allow-Origin": "*",
63
+ "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
64
+ "Access-Control-Allow-Headers": "Content-Type",
65
+ }
66
+ )
67
+ else:
68
+ return {"error": "Method not allowed"}, 405
69
+
70
+ # 返回响应
71
+ return Response(
72
+ resp.content,
73
+ status=resp.status_code,
74
+ headers={
75
+ "Content-Type": resp.headers.get("Content-Type", "application/json"),
76
+ "Access-Control-Allow-Origin": "*",
77
+ }
78
+ )
79
+
80
+ except requests.Timeout:
81
+ return {"success": False, "error": "timeout", "message": "请求超时"}, 504
82
+ except requests.RequestException as e:
83
+ return {"success": False, "error": "proxy_error", "message": str(e)}, 502
84
+ except Exception as e:
85
+ return {"success": False, "error": "server_error", "message": str(e)}, 500
86
+
87
+
88
+ if __name__ == "__main__":
89
+ app.run(host="0.0.0.0", port=7860)
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ flask
2
+ requests
3
+ gunicorn