Spaces:
Runtime error
Runtime error
Refactor VideoTemplateEditor component: remove AI editing features and related state management, streamline template loading, and update styles for improved layout. Enhance CSS for responsive design and visual consistency across various components, including dropdowns, sync stats, and quiz elements. Remove deprecated premium badge styles and adjust layout for chat components.
66de9c8 Download backend/app/services/renderer.py from firebird-technologies/NoteStack-Test: direct link, hf CLI and curl.
- Browser
- Download file 2.5 kB
-
https://huggingface.co/spaces/firebird-technologies/NoteStack-Test/resolve/main/backend/app/services/renderer.py
- Command line
-
hf download hf://spaces/firebird-technologies/NoteStack-Test/backend/app/services/renderer.py
-
curl -L -o renderer.py https://huggingface.co/spaces/firebird-technologies/NoteStack-Test/resolve/main/backend/app/services/renderer.py
2.5 kB
| """Hands a render to the Remotion service with presigned upload URLs (it never holds storage keys).""" | |
| import httpx | |
| from app.config import settings | |
| from app.models import Artifact, Job | |
| from app.services.storage import keys, storage | |
| COMPOSITIONS = { | |
| "AudiogramSquare": "mp4", | |
| "QuoteCard": "png", | |
| "CarouselSlide": "png", | |
| } | |
| class PermanentJobError(RuntimeError): | |
| """Fail the job now; retrying will not help.""" | |
| def available() -> bool: | |
| """Whether the render service answers right now (a quick health check, not a promise for later).""" | |
| try: | |
| return httpx.get(f"{settings.renderer_url}/health", timeout=2).status_code == 200 | |
| except httpx.HTTPError: | |
| return False | |
| def request_render(job: Job, artifact: Artifact, composition: str, props: dict | None = None, | |
| stills: list[dict] | None = None) -> None: | |
| """Start a render. `stills` renders one PNG per props dict (carousels) instead of a single output.""" | |
| fmt = COMPOSITIONS[composition] | |
| content_type = "image/png" if fmt == "png" else "video/mp4" | |
| body: dict = { | |
| "jobId": str(job.id), | |
| "compositionId": composition, | |
| "props": props or {}, | |
| "format": fmt, | |
| "uploadContentType": content_type, | |
| "callbackUrl": f"{settings.api_url}/api/internal/jobs/{job.id}/progress", | |
| } | |
| if stills: | |
| outputs = [] | |
| for i, still_props in enumerate(stills, start=1): | |
| key = keys.artifact(artifact.workspace_id, artifact.id, f"slide-{i:02d}", fmt) | |
| outputs.append({"props": still_props, "uploadUrl": storage.presign_put(key, content_type, ttl=6 * 3600), | |
| "storageKey": key}) | |
| body.update(stills=outputs, props=stills[0], uploadUrl=outputs[0]["uploadUrl"], | |
| storageKey=outputs[0]["storageKey"]) | |
| else: | |
| key = keys.artifact(artifact.workspace_id, artifact.id, composition.lower(), fmt) | |
| body.update(uploadUrl=storage.presign_put(key, content_type, ttl=6 * 3600), storageKey=key) | |
| try: | |
| resp = httpx.post(f"{settings.renderer_url}/render", headers={"x-internal-token": settings.internal_token}, | |
| json=body, timeout=30) | |
| except httpx.ConnectError as exc: | |
| raise PermanentJobError("Renderer is not running. Start it with: cd renderer && npm start") from exc | |
| if resp.status_code == 400: | |
| raise PermanentJobError(f"Renderer rejected the props: {resp.text[:400]}") | |
| resp.raise_for_status() | |