Spaces:
Sleeping
Sleeping
File size: 6,674 Bytes
73364a8 039db5e 967ebf8 b054698 967ebf8 64831ea 967ebf8 7269a81 967ebf8 b054698 179bd1d 30972d9 1bfd55a ad22084 3272a52 73364a8 3272a52 039db5e d80334f 73364a8 3272a52 73364a8 3272a52 7269a81 449efc6 30972d9 967ebf8 01ff30c 88fa970 5aa5a1d 88fa970 449efc6 88fa970 967ebf8 88fa970 967ebf8 86a1646 01ff30c 30972d9 3272a52 967ebf8 30972d9 967ebf8 b07ed9a 3272a52 73364a8 967ebf8 b10bd1b 3ada746 b10bd1b 32be864 b10bd1b 967ebf8 b10bd1b 967ebf8 b10bd1b 967ebf8 b10bd1b 967ebf8 3272a52 73364a8 3272a52 73364a8 b10bd1b 6485772 967ebf8 73364a8 01ff30c 967ebf8 01ff30c 449efc6 01ff30c 7269a81 307e121 aa72d64 449efc6 aa72d64 7269a81 449efc6 7269a81 449efc6 69f273b 7269a81 6e4f42f 7269a81 307e121 d80334f 3272a52 67460be |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
from flask import Flask, request, Response, jsonify, stream_with_context
from flask_cors import CORS
import os, json, httpx
import config
import base64
from io import BytesIO
import io
from PIL import Image
import requests
app = Flask(__name__)
CORS(app)
OPENROUTER_API_KEY = os.getenv("API_KEYS")
@app.get("/health")
def health():
return jsonify({"status": "ready"}), 200
def _headers():
return {
"Authorization": f"Bearer {OPENROUTER_API_KEY}",
"Content-Type": "application/json",
"HTTP-Referer": "https://YOURSPACE.hf.space",
"X-Title": "Minimal Streaming Test",
}
def upload_image_to_imgbb(image_bytes, filename):
"""Upload image to imgbb with 5 minute expiration and return public URL"""
IMGBB_API_KEY = "22f355dd0069ef8742dc94f0c80e4c4d"
try:
# Convert bytes to base64 for imgbb upload
base64_image = base64.b64encode(image_bytes).decode('utf-8')
response = requests.post(
"https://api.imgbb.com/1/upload",
data={
"key": IMGBB_API_KEY,
"image": base64_image,
"name": filename,
"expiration": 300 # 300 seconds = 5 minutes
},
timeout=10
)
if response.status_code == 200:
return response.json()['data']['url']
else:
print(f"ImgBB error: {response.text}")
return None
except Exception as e:
print(f"Upload error: {e}")
return None
# Fixed _payload: For images, use data[1] directly as the public URL (no prefixing with app URL, since it's now hosted on imgbb).
def _payload(q: str):
data=q.split("%")
content=""
system=""
if data[0]=="Text":
content=data[1]
else:
# For images, content must be an array with text + image
content=[
{
"type": "text",
"text": "Analyze image and get question"
},
{
"type": "image_url",
"image_url": {
"url": data[1] # Direct public URL from imgbb
}
}
]
info=config.config
system=info[data[2]][data[3]]
return {
"model": "meta-llama/llama-4-maverick-17b-128e-instruct",
"stream": True,
"messages": [{"role":"system","content":system},{"role": "user", "content": content}],
"temperature": 0.7,
"top_p":0.9,
"max_tokens": 999,
}
def stream_openrouter(q: str):
if not OPENROUTER_API_KEY:
yield "data: Error: Missing API key\n\n"
return
try:
with httpx.Client(timeout=30.0) as client:
with client.stream("POST",
"https://api.groq.com/openai/v1/chat/completions",
headers=_headers(),
json=_payload(q)) as response:
response.raise_for_status()
for line in response.iter_lines():
if line.startswith('data: '):
data = line[6:] # Remove 'data: ' prefix
if data == '[DONE]':
break
try:
json_data = json.loads(data)
if 'choices' in json_data:
content = json_data['choices'][0].get('delta', {}).get('content')
print(content)
if content:
yield f"data: {json.dumps(content)}\n\n"
except json.JSONDecodeError:
continue
yield "data: [DONE]\n\n"
except httpx.HTTPError as e:
yield f"data: Error: {str(e)}\n\n"
except Exception as e:
yield f"data: Unexpected error: {str(e)}\n\n"
@app.post("/ask")
def ask():
payload = request.get_json(silent=True) or {}
q = payload.get("question", "").strip()
lang = payload.get("selectedLanguage", "").strip()
mode = payload.get("selectedMode", "").strip()
prompt=""
q2lang=""
if not q:
q = "Say hello in one short sentence."
prompt="Text"+"%"+q+"%"+mode+"%"+lang
print(prompt)
return Response(
stream_with_context(stream_openrouter(prompt)),
mimetype="text/event-stream",
headers={
"Cache-Control": "no-cache",
"X-Accel-Buffering": "no"
}
)
# Fixed /askimage endpoint:
# - Use upload_image_to_imgbb to get a public URL instead of saving to local disk (which isn't served statically).
# - Removed invalid 'if not image_url:' check (path is always truthy).
# - Removed local file save.
# - Updated prompt construction to use the public URL directly.
@app.post("/askimage")
def askimage():
# Get form data
image_file = request.files.get('image')
lang = request.form.get('selectedLanguage', '').strip()
mode = request.form.get('selectedMode', '').strip()
if not image_file:
return jsonify({"error": "No image provided"}), 400
try:
# Read image bytes
image_bytes = image_file.read()
# Load image from bytes
img = Image.open(io.BytesIO(image_bytes))
# Resize if larger than 1024x1024 to reduce size (adjust as needed)
max_size = 1024
if img.size[0] > max_size or img.size[1] > max_size:
img.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
# Save compressed version (quality 85 for balance of speed/size)
output = io.BytesIO()
img.save(output, format='JPEG', quality=85, optimize=True)
compressed_bytes = output.getvalue()
# Use compressed bytes for upload
image_url = upload_image_to_imgbb(compressed_bytes, image_file.filename)
if not image_url:
return jsonify({"error": "Failed to upload image to host"}), 500
# Build prompt with public URL
prompt = "Image"+"%"+image_url+"%"+mode+"%"+lang
print(f"Image URL: {image_url}")
return Response(
stream_with_context(stream_openrouter(prompt)),
mimetype="text/event-stream",
headers={
"Cache-Control": "no-cache",
"X-Accel-Buffering": "no"
}
)
except Exception as e:
return jsonify({"error": str(e)}), 500
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860, debug=False) |