Aura Gen commited on
Commit
f97b9c9
·
verified ·
1 Parent(s): 350f6b9

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -0
app.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import logging
3
+ import requests
4
+ from flask import Flask, request, jsonify, Response, stream_with_context, send_file
5
+ from flask_cors import CORS
6
+
7
+ logging.basicConfig(
8
+ level=logging.INFO,
9
+ format='%(asctime)s - %(levelname)s - [Vedika Space] - %(message)s'
10
+ )
11
+ logger = logging.getLogger(__name__)
12
+
13
+ app = Flask(__name__)
14
+ CORS(app, resources={r"/*": {"origins": "*"}})
15
+
16
+ # Secrets
17
+ API_KEY = os.getenv("API_KEY")
18
+ MODEL_ID = os.getenv("MODEL_ID")
19
+ GAS_BACKEND_URL = os.getenv("GAS_BACKEND_URL")
20
+ NVIDIA_API_URL = "https://integrate.api.nvidia.com/v1/chat/completions"
21
+
22
+ def validate_token_with_gas(token):
23
+ if not token:
24
+ return False
25
+ try:
26
+ response = requests.post(GAS_BACKEND_URL, json={"action": "validate", "token": token}, timeout=5)
27
+ if response.status_code == 200:
28
+ return response.json().get("valid") == True
29
+ return False
30
+ except requests.exceptions.RequestException as e:
31
+ logger.error(f"GAS validation error: {e}")
32
+ return False
33
+
34
+ # ---------------------------------------------------------
35
+ # फ्रंटएंड सर्व करना (index.html)
36
+ # ---------------------------------------------------------
37
+ @app.route('/')
38
+ def index():
39
+ # यह सीधे उसी फोल्डर से index.html यूज़र को दिखाएगा
40
+ return send_file('index.html')
41
+
42
+ # ---------------------------------------------------------
43
+ # बैकएंड API
44
+ # ---------------------------------------------------------
45
+ @app.route('/chat', methods=['POST', 'OPTIONS'])
46
+ def chat_endpoint():
47
+ if request.method == 'OPTIONS':
48
+ return Response(status=204)
49
+
50
+ auth_header = request.headers.get("Authorization")
51
+ if not auth_header or not auth_header.startswith("Bearer "):
52
+ return jsonify({"error": "Unauthorized: Missing Token"}), 401
53
+
54
+ token = auth_header.split("Bearer ")[1].strip()
55
+
56
+ if not validate_token_with_gas(token):
57
+ return jsonify({"error": "Forbidden: Invalid Token"}), 403
58
+
59
+ try:
60
+ data = request.json
61
+ mode = data.get('mode', 'FLASH')
62
+ messages = data.get('messages', [])
63
+ if not messages:
64
+ return jsonify({"error": "Messages empty"}), 400
65
+ except Exception:
66
+ return jsonify({"error": "Invalid JSON"}), 400
67
+
68
+ system_prompt = os.getenv(mode.upper())
69
+ if not system_prompt:
70
+ return jsonify({"error": f"Mode {mode} missing in Secrets."}), 500
71
+
72
+ messages.insert(0, {"role": "system", "content": system_prompt})
73
+
74
+ nvidia_payload = {
75
+ "model": MODEL_ID,
76
+ "messages": messages,
77
+ "temperature": 0.7,
78
+ "max_tokens": 2048,
79
+ "stream": True
80
+ }
81
+
82
+ nvidia_headers = {"Authorization": f"Bearer {API_KEY}", "Accept": "text/event-stream"}
83
+
84
+ def generate_stream():
85
+ try:
86
+ response = requests.post(NVIDIA_API_URL, headers=nvidia_headers, json=nvidia_payload, stream=True)
87
+ if response.status_code != 200:
88
+ yield f"data: {{\"error\": \"API Error {response.status_code}\"}}\n\n"
89
+ return
90
+ for line in response.iter_lines():
91
+ if line:
92
+ yield line.decode('utf-8') + '\n\n'
93
+ except Exception as e:
94
+ yield f"data: {{\"error\": \"Connection lost.\"}}\n\n"
95
+
96
+ return Response(stream_with_context(generate_stream()), mimetype='text/event-stream')
97
+
98
+ if __name__ == '__main__':
99
+ app.run(host='0.0.0.0', port=7860, debug=False)