ParthSadaria commited on
Commit
1f4da00
·
verified ·
1 Parent(s): 3b6dbab

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +65 -140
main.py CHANGED
@@ -38,8 +38,8 @@ api_key_header = APIKeyHeader(name="Authorization", auto_error=False)
38
 
39
  from usage_tracker import UsageTracker
40
  usage_tracker = UsageTracker()
41
-
42
- app = FastAPI()
43
 
44
  app.add_middleware(GZipMiddleware, minimum_size=1000)
45
  app.add_middleware(
@@ -311,80 +311,6 @@ async def root():
311
  raise HTTPException(status_code=404, detail="index.html not found")
312
  return HTMLResponse(content=html_content)
313
 
314
- @app.get("/script.js", response_class=HTMLResponse)
315
- async def script():
316
- html_content = read_html_file("script.js")
317
- if html_content is None:
318
- raise HTTPException(status_code=404, detail="script.js not found")
319
- return HTMLResponse(content=html_content)
320
-
321
- @app.get("/style.css", response_class=HTMLResponse)
322
- async def style():
323
- html_content = read_html_file("style.css")
324
- if html_content is None:
325
- raise HTTPException(status_code=404, detail="style.css not found")
326
- return HTMLResponse(content=html_content)
327
-
328
- @app.get("/dynamo", response_class=HTMLResponse)
329
- async def dynamic_ai_page(request: Request):
330
- user_agent = request.headers.get('user-agent', 'Unknown User')
331
- client_ip = request.client.host if request.client else "Unknown IP"
332
- location = f"IP: {client_ip}"
333
-
334
- prompt = f"""
335
- Generate a dynamic HTML page for a user with the following details: with name "LOKI.AI"
336
- - User-Agent: {user_agent}
337
- - Location: {location}
338
- - Style: Cyberpunk, minimalist, or retro
339
-
340
- Make sure the HTML is clean and includes a heading, also have cool animations a motivational message, and a cool background.
341
- Wrap the generated HTML in triple backticks (```).
342
- """
343
-
344
- payload_data = {
345
- "model": "mistral-small-latest",
346
- "messages": [{"role": "user", "content": prompt}],
347
- "stream": False
348
- }
349
-
350
- headers = {
351
- "Authorization": "Bearer playground"
352
- }
353
-
354
- try:
355
- client = get_async_client()
356
- response = await client.post(
357
- f"http://localhost:7860/chat/completions",
358
- json=payload_data,
359
- headers=headers,
360
- timeout=30.0
361
- )
362
- response.raise_for_status()
363
- data = response.json()
364
-
365
- html_content = None
366
- if data and 'choices' in data and len(data['choices']) > 0:
367
- message_content = data['choices'][0].get('message', {}).get('content', '')
368
- match = re.search(r"```(?:html)?(.*?)```", message_content, re.DOTALL)
369
- if match:
370
- html_content = match.group(1).strip()
371
- else:
372
- html_content = message_content.strip()
373
-
374
- if not html_content:
375
- raise HTTPException(status_code=500, detail="Failed to generate HTML content from AI.")
376
-
377
- return HTMLResponse(content=html_content)
378
- except httpx.RequestError as e:
379
- print(f"HTTPX Request Error in /dynamo: {e}")
380
- raise HTTPException(status_code=500, detail=f"Failed to connect to internal AI service: {e}")
381
- except httpx.HTTPStatusError as e:
382
- print(f"HTTPX Status Error in /dynamo: {e.response.status_code} - {e.response.text}")
383
- raise HTTPException(status_code=e.response.status_code, detail=f"Internal AI service responded with error: {e.response.text}")
384
- except Exception as e:
385
- print(f"An unexpected error occurred in /dynamo: {e}")
386
- raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {e}")
387
-
388
 
389
  @app.get("/scraper", response_class=PlainTextResponse)
390
  async def scrape_site(url: str = Query(..., description="URL to scrape")):
@@ -425,70 +351,69 @@ FILES = {
425
  "js": "script.js"
426
  }
427
 
428
- async def get_github_file(filename: str) -> str | None:
429
- url = f"{GITHUB_BASE}/{filename}"
430
- client = get_async_client()
431
- try:
432
- res = await client.get(url, follow_redirects=True)
433
- res.raise_for_status()
434
- return res.text
435
- except httpx.HTTPStatusError as e:
436
- print(f"Error fetching {filename} from GitHub: {e.response.status_code} - {e.response.text}")
437
- return None
438
- except httpx.RequestError as e:
439
- print(f"Request error fetching {filename} from GitHub: {e}")
440
- return None
441
-
442
- @app.get("/vetra", response_class=HTMLResponse)
443
- async def serve_vetra():
444
- html = await get_github_file(FILES["html"])
445
- css = await get_github_file(FILES["css"])
446
- js = await get_github_file(FILES["js"])
447
-
448
- if not html:
449
- raise HTTPException(status_code=404, detail="index.html not found on GitHub")
450
-
451
- final_html = html.replace(
452
- "</head>",
453
- f"<style>{css or '/* CSS not found */'}</style></head>"
454
- ).replace(
455
- "</body>",
456
- f"<script>{js or '// JS not found'}</script></body>"
457
- )
458
-
459
- return HTMLResponse(content=final_html)
460
-
461
- @app.get("/searchgpt")
462
- async def search_gpt(q: str, request: Request, stream: bool = False, systemprompt: str | None = None):
463
- if not q:
464
- raise HTTPException(status_code=400, detail="Query parameter 'q' is required")
465
-
466
- usage_tracker.record_request(request=request, model="searchgpt", endpoint="/searchgpt")
467
-
468
- if stream:
469
- queue = await generate_search_async(q, systemprompt=systemprompt, stream=True)
470
- async def stream_generator():
471
- collected_text = ""
472
- while True:
473
- item = await queue.get()
474
- if item is None:
475
- break
476
-
477
- if "error" in item:
478
- yield f"data: {json.dumps({'error': item['error']})}\n\n"
479
- break
480
-
481
- if "data" in item:
482
- yield item["data"]
483
- collected_text += item.get("text", "")
484
-
485
- return StreamingResponse(
486
- stream_generator(),
487
- media_type="text/event-stream"
488
- )
489
- else:
490
- response_data = await generate_search_async(q, systemprompt=systemprompt, stream=False)
491
- return JSONResponse(content=response_data)
492
 
493
  header_url = os.getenv('HEADER_URL')
494
  @app.post("/chat/completions")
 
38
 
39
  from usage_tracker import UsageTracker
40
  usage_tracker = UsageTracker()
41
+ # Disable the basic docs because we are better than that
42
+ app = FastAPI(docs_url=None, redoc_url=None)
43
 
44
  app.add_middleware(GZipMiddleware, minimum_size=1000)
45
  app.add_middleware(
 
311
  raise HTTPException(status_code=404, detail="index.html not found")
312
  return HTMLResponse(content=html_content)
313
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
 
315
  @app.get("/scraper", response_class=PlainTextResponse)
316
  async def scrape_site(url: str = Query(..., description="URL to scrape")):
 
351
  "js": "script.js"
352
  }
353
 
354
+ @app.get("/docs", include_in_schema=False)
355
+ async def custom_documentation():
356
+ return HTMLResponse("""
357
+ <!DOCTYPE html>
358
+ <html>
359
+ <head>
360
+ <title>Loki API - The Good Stuff</title>
361
+ <meta charset="utf-8" />
362
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
363
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet">
364
+ <style>
365
+ body {
366
+ margin: 0;
367
+ background: #0f0f13; /* Deep dark background */
368
+ }
369
+ /* Custom Scrollbar because default is cringe */
370
+ ::-webkit-scrollbar { width: 8px; height: 8px; }
371
+ ::-webkit-scrollbar-track { background: #0f0f13; }
372
+ ::-webkit-scrollbar-thumb { background: #3b82f6; border-radius: 4px; }
373
+ ::-webkit-scrollbar-thumb:hover { background: #8b5cf6; }
374
+
375
+ /* Overriding Scalar variables for that LOKI aesthetic */
376
+ :root {
377
+ --scalar-color-1: #3b82f6; /* Blue */
378
+ --scalar-color-2: #8b5cf6; /* Purple */
379
+ --scalar-color-3: #10b981; /* Green */
380
+ --scalar-color-accent: #8b5cf6;
381
+
382
+ --scalar-background-1: #0b0b0e;
383
+ --scalar-background-2: #141419;
384
+ --scalar-background-3: #1f1f26;
385
+
386
+ --scalar-border-color: #2d2d3b;
387
+ --scalar-font: 'Inter', sans-serif;
388
+ }
389
+
390
+ /* Smooth fade in for the whole page */
391
+ body {
392
+ animation: fadeIn 0.8s ease-in-out;
393
+ }
394
+
395
+ @keyframes fadeIn {
396
+ from { opacity: 0; transform: translateY(10px); }
397
+ to { opacity: 1; transform: translateY(0); }
398
+ }
399
+
400
+ /* Let's hide the 'Made with Scalar' footer because we're mysterious */
401
+ .scalar-footer { display: none !important; }
402
+ </style>
403
+ </head>
404
+ <body>
405
+ <script
406
+ id="api-reference"
407
+ data-url="/openapi.json"
408
+ data-proxy-url="https://proxy.scalar.com"
409
+ data-layout="modern"
410
+ data-theme="deepSpace"
411
+ data-show-sidebar="true"
412
+ ></script>
413
+ <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
414
+ </body>
415
+ </html>
416
+ """)
 
417
 
418
  header_url = os.getenv('HEADER_URL')
419
  @app.post("/chat/completions")