- DeviceRegistry with load/save/add/remove/instantiate and _DEVICE_CLASSES dict
- ShowStore with save/load/list_ids using aiofiles for async I/O
- FastAPI app with lifespan hook (startup: load registry/store, shutdown: save registry)
- API routes: GET/POST /api/devices/, DELETE /api/devices/{id}, GET/POST /api/shows/, GET /api/shows/{id}
- WebSocket stub at /ws with ConnectionManager and ack echo
- Frontend shell: DAW layout with header, sidebar (DEVICES + ANIMATIONS), TIMELINE, TRANSPORT
- Terminal aesthetic: dark theme, cyan accents, monospace fonts, no drop shadows
- .gitignore for runtime data (devices.json, shows/, __pycache__, .venv)
35 lines
985 B
Python
35 lines
985 B
Python
from fastapi import APIRouter, HTTPException
|
|
from lightsync.models.show import ShowModel
|
|
import lightsync.main as state # access show_store via module-level ref
|
|
|
|
router = APIRouter(tags=["shows"])
|
|
|
|
|
|
@router.get("/")
|
|
async def list_shows():
|
|
"""Return summary list of all shows."""
|
|
summaries = []
|
|
for show_id in state.show_store.list_ids():
|
|
show = await state.show_store.load(show_id)
|
|
if show is not None:
|
|
summaries.append({
|
|
"id": str(show.id),
|
|
"name": show.name,
|
|
"created_at": show.created_at.isoformat(),
|
|
})
|
|
return summaries
|
|
|
|
|
|
@router.post("/", status_code=201)
|
|
async def create_show(show: ShowModel) -> ShowModel:
|
|
await state.show_store.save(show)
|
|
return show
|
|
|
|
|
|
@router.get("/{show_id}")
|
|
async def get_show(show_id: str) -> ShowModel:
|
|
show = await state.show_store.load(show_id)
|
|
if show is None:
|
|
raise HTTPException(404, "Show not found")
|
|
return show
|