import os import threading from fastapi import FastAPI, Request from fastapi.responses import FileResponse, JSONResponse, PlainTextResponse from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles import uvicorn app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"] ) # In-memory, process-lifetime only _CONFIG = {} _LOCK = threading.Lock() # Serve static frontend app.mount("/static", StaticFiles(directory="static"), name="static") @app.get("/", response_class=FileResponse) def root(): return FileResponse("static/index.html") @app.get("/api/ping", response_class=PlainTextResponse) def ping(): return "pong" @app.get("/api/config") def get_config(): with _LOCK: return JSONResponse(_CONFIG or {"background": None, "items": []}) @app.post("/api/config") async def set_config(req: Request): data = await req.json() # Basic shape guard if not isinstance(data, dict): return JSONResponse({"error": "Invalid payload"}, status_code=400) with _LOCK: # store exactly what client sent (ephemeral) _CONFIG.clear() _CONFIG.update(data) return JSONResponse({"ok": True}) if __name__ == "__main__": port = int(os.environ.get("PORT", "7860")) uvicorn.run("app:app", host="0.0.0.0", port=port, reload=False)