Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -368,13 +368,71 @@ async def oauth_logout(request: Request):
|
|
| 368 |
|
| 369 |
@fapp.get("/health")
|
| 370 |
async def health():
|
| 371 |
-
# Check SGLang
|
| 372 |
try:
|
| 373 |
r = requests.get(f"{SGLANG_BASE}/v1/models", timeout=5, verify=False)
|
| 374 |
return {"status":"ok","sglang":"connected"}
|
| 375 |
except:
|
| 376 |
return {"status":"ok","sglang":"disconnected"}
|
| 377 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 378 |
app = gr.mount_gradio_app(fapp, gradio_demo, path="/gradio")
|
| 379 |
|
| 380 |
if __name__ == "__main__":
|
|
|
|
| 368 |
|
| 369 |
@fapp.get("/health")
|
| 370 |
async def health():
|
|
|
|
| 371 |
try:
|
| 372 |
r = requests.get(f"{SGLANG_BASE}/v1/models", timeout=5, verify=False)
|
| 373 |
return {"status":"ok","sglang":"connected"}
|
| 374 |
except:
|
| 375 |
return {"status":"ok","sglang":"disconnected"}
|
| 376 |
|
| 377 |
+
# ββ Web Search API (Brave) ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 378 |
+
BRAVE_API_KEY = os.getenv("BRAVE_API_KEY", "")
|
| 379 |
+
|
| 380 |
+
@fapp.post("/api/search")
|
| 381 |
+
async def api_search(request: Request):
|
| 382 |
+
body = await request.json()
|
| 383 |
+
query = body.get("query", "").strip()
|
| 384 |
+
if not query:
|
| 385 |
+
return JSONResponse({"error": "empty query"}, status_code=400)
|
| 386 |
+
key = BRAVE_API_KEY
|
| 387 |
+
if not key:
|
| 388 |
+
return JSONResponse({"error": "BRAVE_API_KEY not set"}, status_code=500)
|
| 389 |
+
try:
|
| 390 |
+
r = requests.get(
|
| 391 |
+
"https://api.search.brave.com/res/v1/web/search",
|
| 392 |
+
headers={"X-Subscription-Token": key, "Accept": "application/json"},
|
| 393 |
+
params={"q": query, "count": 5}, timeout=10,
|
| 394 |
+
)
|
| 395 |
+
r.raise_for_status()
|
| 396 |
+
results = r.json().get("web", {}).get("results", [])
|
| 397 |
+
items = []
|
| 398 |
+
for item in results[:5]:
|
| 399 |
+
items.append({
|
| 400 |
+
"title": item.get("title", ""),
|
| 401 |
+
"desc": item.get("description", ""),
|
| 402 |
+
"url": item.get("url", ""),
|
| 403 |
+
})
|
| 404 |
+
return JSONResponse({"results": items})
|
| 405 |
+
except Exception as e:
|
| 406 |
+
return JSONResponse({"error": str(e)}, status_code=500)
|
| 407 |
+
|
| 408 |
+
# ββ PDF Text Extraction βββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 409 |
+
@fapp.post("/api/extract-pdf")
|
| 410 |
+
async def api_extract_pdf(request: Request):
|
| 411 |
+
"""Base64 PDF β text extraction"""
|
| 412 |
+
try:
|
| 413 |
+
body = await request.json()
|
| 414 |
+
b64 = body.get("data", "")
|
| 415 |
+
if "," in b64:
|
| 416 |
+
b64 = b64.split(",", 1)[1]
|
| 417 |
+
import io
|
| 418 |
+
pdf_bytes = base64.b64decode(b64)
|
| 419 |
+
text = ""
|
| 420 |
+
try:
|
| 421 |
+
import fitz # PyMuPDF
|
| 422 |
+
doc = fitz.open(stream=pdf_bytes, filetype="pdf")
|
| 423 |
+
for page in doc:
|
| 424 |
+
text += page.get_text() + "\n"
|
| 425 |
+
except ImportError:
|
| 426 |
+
# Fallback: simple text extraction
|
| 427 |
+
content = pdf_bytes.decode("utf-8", errors="ignore")
|
| 428 |
+
# Very basic: find text between stream/endstream
|
| 429 |
+
text = re.sub(r'[^\x20-\x7E\n\r\uAC00-\uD7A3\u3040-\u309F\u30A0-\u30FF]', '', content)
|
| 430 |
+
|
| 431 |
+
text = text.strip()[:8000] # Max 8000 chars
|
| 432 |
+
return JSONResponse({"text": text, "chars": len(text)})
|
| 433 |
+
except Exception as e:
|
| 434 |
+
return JSONResponse({"error": str(e)}, status_code=500)
|
| 435 |
+
|
| 436 |
app = gr.mount_gradio_app(fapp, gradio_demo, path="/gradio")
|
| 437 |
|
| 438 |
if __name__ == "__main__":
|