sreepathi-ravikumar commited on
Commit
73364a8
·
verified ·
1 Parent(s): 3272a52

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -74
app.py CHANGED
@@ -1,108 +1,68 @@
1
- import os
2
- import json
3
- from flask import Flask, request, jsonify, Response, stream_with_context
4
  from flask_cors import CORS
5
- import httpx
6
-
7
 
8
  app = Flask(__name__)
9
- CORS(app)
10
 
11
  OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_NEW")
12
 
13
- @app.route("/health", methods=["GET"])
14
  def health():
15
  return jsonify({"status": "ready"}), 200
16
 
17
- def openrouter_headers():
18
  return {
19
  "Authorization": f"Bearer {OPENROUTER_API_KEY}",
20
  "Content-Type": "application/json",
21
- "HTTP-Referer": "https://sreepathi-ravikumar-sample1.hf.space",
22
- "X-Title": "Educational AI Assistant",
23
  }
24
 
25
- def build_payload(question: str) -> dict:
26
  return {
27
  "model": "deepseek/deepseek-chat-v3-0324:free",
28
  "stream": True,
29
- "messages": [{
30
- "role": "user",
31
- "content": "condition every topics or heading only must startswith # and endswith :\n\n" + question,
32
- }],
33
- "temperature": 0.3,
34
- "max_tokens": 599,
35
  }
36
 
37
- def stream_openrouter(question: str):
 
 
38
  with httpx.Client(timeout=None) as client:
39
- with client.stream(
40
- "POST",
41
- "https://openrouter.ai/api/v1/chat/completions",
42
- headers=openrouter_headers(),
43
- json=build_payload(question),
44
- ) as r:
45
  r.raise_for_status()
46
- # Optional start signal
47
- yield "event: start\ndata: stream\n\n"
48
  for raw in r.iter_lines():
49
- if not raw:
50
  continue
51
- # OpenRouter uses SSE-like "data:" lines
52
- if raw.startswith(b"data:"):
53
- data = raw[5:].strip()
54
- else:
55
- data = raw.strip()
56
-
57
  if data == b"[DONE]":
58
- yield "event: done\ndata: [DONE]\n\n"
59
  break
60
-
61
  try:
62
  obj = json.loads(data.decode("utf-8"))
63
  delta = obj.get("choices", [{}])[0].get("delta", {}).get("content")
64
  if delta:
65
- # Wrap each token in JSON so the frontend can parse safely
66
- yield f"data: {json.dumps({'text': delta})}\n\n"
67
  except Exception:
68
- # Fallback: forward as plain text
69
- try:
70
- txt = data.decode("utf-8")
71
- except Exception:
72
- txt = ""
73
- if txt:
74
- yield f"data: {json.dumps({'text': txt})}\n\n"
75
 
76
- @app.route("/ask", methods=["POST"])
77
  def ask():
78
- try:
79
- if not OPENROUTER_API_KEY:
80
- return jsonify({"error": "OPENROUTER_API_NEW is not set"}), 500
81
-
82
- data = request.get_json(silent=True) or {}
83
- # Accept both keys for compatibility
84
- question = (data.get("question") or data.get("userPrompt") or "").strip()
85
- if not question:
86
- return jsonify({"error": "Question is required"}), 400
87
-
88
- # Stream back as SSE
89
- resp = Response(
90
- stream_with_context(stream_openrouter(question)),
91
- mimetype="text/event-stream",
92
- )
93
- # Important headers to avoid buffering by proxies/CDNs
94
- resp.headers["Cache-Control"] = "no-cache"
95
- resp.headers["X-Accel-Buffering"] = "no"
96
- resp.headers["Connection"] = "keep-alive"
97
- # CORS for SSE: allow the local frontend origins
98
- origin = request.headers.get("Origin")
99
- if origin in ALLOWED_ORIGINS:
100
- resp.headers["Access-Control-Allow-Origin"] = origin
101
- resp.headers["Vary"] = "Origin"
102
- return resp
103
- except Exception as e:
104
- return jsonify({"error": str(e)}), 500
105
 
106
  if __name__ == "__main__":
107
- # In Spaces, use the default port; locally, 7860 is fine.
108
- app.run(host="0.0.0.0", port=7860, debug=True, threaded=True)
 
1
+ # app.py (minimal SSE + CORS)
2
+ from flask import Flask, request, Response, jsonify, stream_with_context
 
3
  from flask_cors import CORS
4
+ import os, json, httpx
 
5
 
6
  app = Flask(__name__)
7
+ CORS(app) # simple: allow all origins for testing
8
 
9
  OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_NEW")
10
 
11
+ @app.get("/health")
12
  def health():
13
  return jsonify({"status": "ready"}), 200
14
 
15
+ def _headers():
16
  return {
17
  "Authorization": f"Bearer {OPENROUTER_API_KEY}",
18
  "Content-Type": "application/json",
19
+ "HTTP-Referer": "https://YOURSPACE.hf.space",
20
+ "X-Title": "Minimal Streaming Test",
21
  }
22
 
23
+ def _payload(q: str):
24
  return {
25
  "model": "deepseek/deepseek-chat-v3-0324:free",
26
  "stream": True,
27
+ "messages": [{"role": "user", "content": q}],
28
+ "temperature": 0.2,
29
+ "max_tokens": 200,
 
 
 
30
  }
31
 
32
+ def stream_openrouter(q: str):
33
+ if not OPENROUTER_API_KEY:
34
+ yield "data: Missing OPENROUTER_API_NEW\n\n"; return
35
  with httpx.Client(timeout=None) as client:
36
+ with client.stream("POST", "https://openrouter.ai/api/v1/chat/completions",
37
+ headers=_headers(), json=_payload(q)) as r:
 
 
 
 
38
  r.raise_for_status()
 
 
39
  for raw in r.iter_lines():
40
+ if not raw:
41
  continue
42
+ data = raw[5:].strip() if raw.startswith(b"data:") else raw.strip()
 
 
 
 
 
43
  if data == b"[DONE]":
44
+ yield "data: [DONE]\n\n"
45
  break
 
46
  try:
47
  obj = json.loads(data.decode("utf-8"))
48
  delta = obj.get("choices", [{}])[0].get("delta", {}).get("content")
49
  if delta:
50
+ # Send plain text chunks (still framed as SSE data)
51
+ yield f"data: {json.dumps(delta)}\n\n"
52
  except Exception:
53
+ pass
 
 
 
 
 
 
54
 
55
+ @app.post("/ask")
56
  def ask():
57
+ payload = request.get_json(silent=True) or {}
58
+ q = (payload.get("question") or payload.get("userPrompt") or "").strip()
59
+ if not q:
60
+ q = "Say hello in one short sentence."
61
+ resp = Response(stream_with_context(stream_openrouter(q)), mimetype="text/event-stream")
62
+ resp.headers["Cache-Control"] = "no-cache"
63
+ resp.headers["X-Accel-Buffering"] = "no"
64
+ resp.headers["Connection"] = "keep-alive"
65
+ return resp
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
  if __name__ == "__main__":
68
+ app.run(host="0.0.0.0", port=7860, debug=False, threaded=True)