lightning / app.py
sharktide's picture
Update app.py
a5bd7b0 verified
Raw
History Blame
3.24 kB
import os
import time
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import Response
import httpx
from bs4 import BeautifulSoup
from typing import List, Dict
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["GET"],
allow_headers=["*"],
)
OLLAMA_LIBRARY_URL = "https://ollama.com/library"
# -----------------------------
# RATE LIMITING (25 req/day/IP)
# -----------------------------
RATE_LIMIT = 25
WINDOW_SECONDS = 60 * 60 * 24 # 24 hours
ip_store = {} # { ip: { "count": int, "reset": timestamp } }
def check_rate_limit(ip: str):
now = time.time()
if ip not in ip_store:
ip_store[ip] = {"count": 0, "reset": now + WINDOW_SECONDS}
entry = ip_store[ip]
if now > entry["reset"]:
entry["count"] = 0
entry["reset"] = now + WINDOW_SECONDS
if entry["count"] >= RATE_LIMIT:
raise HTTPException(
status_code=429,
detail="Daily limit reached: 25 images per IP"
)
entry["count"] += 1
# -----------------------------
# IMAGE GENERATION ENDPOINT
# -----------------------------
PKEY = os.getenv("POLLINATIONS_KEY", "") # ensure this is set in your environment
@app.get("/genimg/{prompt}")
async def generate_image(prompt: str, request: Request):
client_ip = request.client.host
check_rate_limit(client_ip)
url = f"https://gen.pollinations.ai/image/{prompt}?model=zimage&key={PKEY}"
async with httpx.AsyncClient() as client:
response = await client.get(url)
if response.status_code != 200:
raise HTTPException(
status_code=500,
detail=f"Pollinations error: {response.status_code}"
)
# Pollinations always returns JPEG
return Response(
content=response.content,
media_type="image/jpeg"
)
# -----------------------------
# EXISTING MODELS SCRAPER
# -----------------------------
@app.get("/models")
async def get_models() -> List[Dict]:
async with httpx.AsyncClient() as client:
response = await client.get(OLLAMA_LIBRARY_URL)
html = response.text
soup = BeautifulSoup(html, "html.parser")
items = soup.select("li[x-test-model]")
models = []
for item in items:
name = item.select_one("[x-test-model-title] span")
description = item.select_one("p.max-w-lg")
sizes = [el.get_text(strip=True) for el in item.select("[x-test-size]")]
pulls = item.select_one("[x-test-pull-count]")
tags = [t.get_text(strip=True) for t in item.select('span[class*="text-blue-600"]')]
updated = item.select_one("[x-test-updated]")
link = item.select_one("a")
models.append({
"name": name.get_text(strip=True) if name else "",
"description": description.get_text(strip=True) if description else "No description",
"sizes": sizes,
"pulls": pulls.get_text(strip=True) if pulls else "Unknown",
"tags": tags,
"updated": updated.get_text(strip=True) if updated else "Unknown",
"link": link.get("href") if link else None,
})
return models