From c08ad31b8ab1f08e0b8e5c712bf735f2fd213c4e Mon Sep 17 00:00:00 2001 From: Claude Code Date: Wed, 25 Mar 2026 23:53:23 -0700 Subject: [PATCH] =?UTF-8?q?wip(sprite-generation):=20=F0=9F=9A=A7=20Add=20?= =?UTF-8?q?sprite=20generation=20server=20and=20database=20with=20WIP=20ma?= =?UTF-8?q?rker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../sprite-generation/IN_DEVELOPMENT_DONT_USE | 0 tools/sprite-generation/server.py | 29 +++++++++++++++++- tools/sprite-generation/sprites.db | Bin 81920 -> 81920 bytes 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tools/sprite-generation/IN_DEVELOPMENT_DONT_USE diff --git a/tools/sprite-generation/IN_DEVELOPMENT_DONT_USE b/tools/sprite-generation/IN_DEVELOPMENT_DONT_USE new file mode 100644 index 00000000..e69de29b diff --git a/tools/sprite-generation/server.py b/tools/sprite-generation/server.py index 65ab7e18..091b74de 100644 --- a/tools/sprite-generation/server.py +++ b/tools/sprite-generation/server.py @@ -10,13 +10,15 @@ Usage: """ from __future__ import annotations +import asyncio import json +from datetime import datetime, timezone from pathlib import Path from typing import Annotated from fastapi import FastAPI, HTTPException, Query from fastapi.middleware.cors import CORSMiddleware -from fastapi.responses import FileResponse, JSONResponse +from fastapi.responses import FileResponse, JSONResponse, StreamingResponse from fastapi.staticfiles import StaticFiles from pydantic import BaseModel @@ -179,6 +181,31 @@ def create_app( registry.approve_variant(body.variant_id) return {"status": "approved", "variant_id": body.variant_id} + @app.get("/api/variants/recent") + def get_recent_variants( + limit: Annotated[int, Query(ge=1, le=100)] = 30, + ) -> list[dict]: + return registry.get_recent_variants(limit=limit) + + @app.get("/api/stream/variants") + async def stream_variants() -> StreamingResponse: + async def event_generator(): + last_check = datetime.now(timezone.utc).isoformat() + while True: + await asyncio.sleep(3) + new_variants = registry.get_recent_variants(limit=10, since=last_check) + if new_variants: + last_check = new_variants[0]["created_at"] + yield f"data: {json.dumps(new_variants)}\n\n" + else: + yield ": keepalive\n\n" + + return StreamingResponse( + event_generator(), + media_type="text/event-stream", + headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"}, + ) + @app.get("/api/runs") def get_runs() -> list[dict]: return registry.get_runs() diff --git a/tools/sprite-generation/sprites.db b/tools/sprite-generation/sprites.db index 0e9227bace96c2248ac3a5faffad03286a4d27ad..6d677b80667064bd92a83bf69536eb9062f5a5d6 100644 GIT binary patch delta 6810 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 delta 6647 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