Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
@@ -28,6 +28,11 @@ _API_BASE_URL = "https://spuckhogycrxcbomznwo.supabase.co"
|
|
28 |
_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36'
|
29 |
_PASTE_API_URL = "https://page.zhoudan.icu/api/paste/b40v96oX"
|
30 |
|
|
|
|
|
|
|
|
|
|
|
31 |
app = Flask(__name__)
|
32 |
logging.basicConfig(level=logging.INFO)
|
33 |
logger = logging.getLogger(__name__)
|
@@ -42,6 +47,25 @@ if not NOTDIAMOND_IP:
|
|
42 |
logger.error("NOTDIAMOND_IP environment variable is not set!")
|
43 |
raise ValueError("NOTDIAMOND_IP must be set")
|
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
refresh_token_cache = TTLCache(maxsize=1000, ttl=3600)
|
46 |
headers_cache = TTLCache(maxsize=1, ttl=3600) # 1小时过期
|
47 |
token_refresh_lock = threading.Lock()
|
@@ -470,12 +494,16 @@ def before_request():
|
|
470 |
multi_auth_manager = None
|
471 |
|
472 |
@app.route('/', methods=['GET'])
|
|
|
473 |
def root():
|
474 |
return jsonify({
|
475 |
"service": "AI Chat Completion Proxy",
|
476 |
"usage": {
|
477 |
"endpoint": "/ai/v1/chat/completions",
|
478 |
"method": "POST",
|
|
|
|
|
|
|
479 |
"body": {
|
480 |
"model": "One of: " + ", ".join(MODEL_INFO.keys()),
|
481 |
"messages": [
|
@@ -487,10 +515,11 @@ def root():
|
|
487 |
}
|
488 |
},
|
489 |
"availableModels": list(MODEL_INFO.keys()),
|
490 |
-
"note": "
|
491 |
})
|
492 |
|
493 |
@app.route('/ai/v1/models', methods=['GET'])
|
|
|
494 |
def proxy_models():
|
495 |
"""返回可用模型列表。"""
|
496 |
models = [
|
@@ -510,6 +539,7 @@ def proxy_models():
|
|
510 |
})
|
511 |
|
512 |
@app.route('/ai/v1/chat/completions', methods=['POST'])
|
|
|
513 |
def handle_request():
|
514 |
global multi_auth_manager
|
515 |
if not multi_auth_manager:
|
|
|
28 |
_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36'
|
29 |
_PASTE_API_URL = "https://page.zhoudan.icu/api/paste/b40v96oX"
|
30 |
|
31 |
+
# 从环境变量获取API密钥
|
32 |
+
API_KEY = os.getenv('API_KEY')
|
33 |
+
if not API_KEY:
|
34 |
+
raise ValueError("API_KEY environment variable must be set")
|
35 |
+
|
36 |
app = Flask(__name__)
|
37 |
logging.basicConfig(level=logging.INFO)
|
38 |
logger = logging.getLogger(__name__)
|
|
|
47 |
logger.error("NOTDIAMOND_IP environment variable is not set!")
|
48 |
raise ValueError("NOTDIAMOND_IP must be set")
|
49 |
|
50 |
+
# API密钥验证装饰器
|
51 |
+
def require_api_key(f):
|
52 |
+
@wraps(f)
|
53 |
+
def decorated_function(*args, **kwargs):
|
54 |
+
auth_header = request.headers.get('Authorization')
|
55 |
+
if not auth_header:
|
56 |
+
return jsonify({'error': 'No API key provided'}), 401
|
57 |
+
|
58 |
+
try:
|
59 |
+
# 从 Bearer token 中提取API密钥
|
60 |
+
provided_key = auth_header.split('Bearer ')[-1].strip()
|
61 |
+
if provided_key != API_KEY:
|
62 |
+
return jsonify({'error': 'Invalid API key'}), 401
|
63 |
+
except Exception:
|
64 |
+
return jsonify({'error': 'Invalid Authorization header format'}), 401
|
65 |
+
|
66 |
+
return f(*args, **kwargs)
|
67 |
+
return decorated_function
|
68 |
+
|
69 |
refresh_token_cache = TTLCache(maxsize=1000, ttl=3600)
|
70 |
headers_cache = TTLCache(maxsize=1, ttl=3600) # 1小时过期
|
71 |
token_refresh_lock = threading.Lock()
|
|
|
494 |
multi_auth_manager = None
|
495 |
|
496 |
@app.route('/', methods=['GET'])
|
497 |
+
@require_api_key
|
498 |
def root():
|
499 |
return jsonify({
|
500 |
"service": "AI Chat Completion Proxy",
|
501 |
"usage": {
|
502 |
"endpoint": "/ai/v1/chat/completions",
|
503 |
"method": "POST",
|
504 |
+
"headers": {
|
505 |
+
"Authorization": "Bearer YOUR_API_KEY"
|
506 |
+
},
|
507 |
"body": {
|
508 |
"model": "One of: " + ", ".join(MODEL_INFO.keys()),
|
509 |
"messages": [
|
|
|
515 |
}
|
516 |
},
|
517 |
"availableModels": list(MODEL_INFO.keys()),
|
518 |
+
"note": "API key authentication is required for all endpoints."
|
519 |
})
|
520 |
|
521 |
@app.route('/ai/v1/models', methods=['GET'])
|
522 |
+
@require_api_key
|
523 |
def proxy_models():
|
524 |
"""返回可用模型列表。"""
|
525 |
models = [
|
|
|
539 |
})
|
540 |
|
541 |
@app.route('/ai/v1/chat/completions', methods=['POST'])
|
542 |
+
@require_api_key
|
543 |
def handle_request():
|
544 |
global multi_auth_manager
|
545 |
if not multi_auth_manager:
|