Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import time | |
| from dataclasses import dataclass | |
| from pathlib import Path | |
| from typing import Any | |
| import httpx | |
| class ModalUploadError(RuntimeError): | |
| """Raised when hosted post-cut inference fails.""" | |
| class ModalUploadClient: | |
| base_url: str | |
| token: str | |
| http_client: httpx.Client | None = None | |
| poll_interval_s: float = 1.0 | |
| timeout_s: float = 900.0 | |
| def submit_video( | |
| self, | |
| video_path: str | Path, | |
| *, | |
| uploader_hf_username: str, | |
| style_key: str = "deadpan", | |
| scene_hint: str = "", | |
| ) -> dict[str, Any]: | |
| close = self.http_client is None | |
| client = self.http_client or httpx.Client(timeout=30.0, follow_redirects=True) | |
| try: | |
| job_id = self._submit( | |
| client, | |
| Path(video_path), | |
| uploader_hf_username, | |
| style_key, | |
| scene_hint, | |
| ) | |
| return self._poll(client, job_id) | |
| finally: | |
| if close: | |
| client.close() | |
| def _submit( | |
| self, | |
| client: httpx.Client, | |
| video_path: Path, | |
| uploader_hf_username: str, | |
| style_key: str, | |
| scene_hint: str, | |
| ) -> str: | |
| with video_path.open("rb") as handle: | |
| response = client.post( | |
| f"{self.base_url.rstrip('/')}/v1/cuts", | |
| headers={"Authorization": f"Bearer {self.token}"}, | |
| data={ | |
| "style_key": style_key, | |
| "scene_hint": scene_hint, | |
| "uploader_hf_username": uploader_hf_username, | |
| }, | |
| files={"video": (video_path.name, handle, "video/mp4")}, | |
| ) | |
| response.raise_for_status() | |
| job_id = response.json().get("job_id") | |
| if not isinstance(job_id, str) or not job_id: | |
| raise ModalUploadError("Modal did not return a job_id") | |
| return job_id | |
| def _poll(self, client: httpx.Client, job_id: str) -> dict[str, Any]: | |
| deadline = time.monotonic() + self.timeout_s | |
| while time.monotonic() < deadline: | |
| response = client.get( | |
| f"{self.base_url.rstrip('/')}/v1/cuts/{job_id}", | |
| headers={"Authorization": f"Bearer {self.token}"}, | |
| ) | |
| if response.status_code == 202: | |
| time.sleep(self.poll_interval_s) | |
| continue | |
| response.raise_for_status() | |
| payload = response.json() | |
| scene = payload.get("scene") | |
| if not isinstance(scene, dict): | |
| raise ModalUploadError("Modal completed without a scene payload") | |
| return scene | |
| raise ModalUploadError("Modal upload timed out") | |