viven-b3 / app.py
diwash-barla1's picture
Update app.py
e79ed03 verified
Raw
History Blame Contribute Delete
3.23 kB
from fastapi import FastAPI, Request, HTTPException, Security, BackgroundTasks
from fastapi.middleware.cors import CORSMiddleware
from fastapi.security import APIKeyHeader
from fastapi.responses import StreamingResponse
from pydantic import BaseModel
import comfy_engine
import httpx
import os
app = FastAPI(title="Sparkling Vision Pro API - Backend Engine")
# 🌐 CORS सेटअप: यह बहुत ज़रूरी है ताकि दूसरा स्पेस इसे कॉल कर सके!
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # प्रोडक्शन में इसे अपने फ्रंटएंड URL से रिप्लेस कर देना
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 🛡️ सीक्रेट पासवर्ड
API_KEY = os.getenv("VIVEN_API_KEY", "your_default_password")
header_scheme = APIKeyHeader(name="X-API-Key")
async def verify_key(key: str = Security(header_scheme)):
if key != API_KEY:
raise HTTPException(status_code=403, detail="Access Denied! Invalid API Key.")
return key
class VideoRequest(BaseModel):
prompt: str
aspect_ratio: str = "16:9"
quality: str = "480p"
frames: int = 81
fps: int = 16
# ==========================================
# 🚀 FIRE-AND-FORGET API ENDPOINT
# ==========================================
@app.post("/api/generate")
async def generate(req: VideoRequest, bg_tasks: BackgroundTasks, auth: str = Security(verify_key)):
try:
task_id, client_id, token, total_nodes = await comfy_engine.queue_prompt(req.dict())
comfy_engine.init_task(task_id, req.prompt)
bg_tasks.add_task(comfy_engine.background_watcher, task_id, client_id, token, total_nodes)
return {"status": "queued", "task_id": task_id, "message": "Task is running in the background."}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# ==========================================
# 🗂️ STATUS & HISTORY ENDPOINTS
# ==========================================
@app.get("/api/history")
async def get_history():
return comfy_engine.load_history()
@app.get("/api/video")
async def proxy_video(request: Request):
q = request.query_params
target = f"http://{comfy_engine.COMFY_HOST}/view?{q}"
async def stream():
async with httpx.AsyncClient() as client:
async with client.stream("GET", target, timeout=60.0) as r:
async for chunk in r.aiter_bytes():
yield chunk
return StreamingResponse(stream(), media_type="video/mp4")
@app.delete("/api/history/{task_id}")
async def delete_history_item(task_id: str):
import json, os
if os.path.exists("history.json"):
with open("history.json", "r", encoding="utf-8") as f:
data = json.load(f)
data = [item for item in data if item["id"] != task_id]
with open("history.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=4)
return {"status": "deleted"}
return {"status": "not found"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)