Spaces:
Running
Running
| """Patches the packaged FiftyOne frontend for a stateless hosted demo.""" | |
| import importlib.util | |
| import json | |
| import logging | |
| from pathlib import Path | |
| import re | |
| ENV_ASSIGNMENT_PATTERN = re.compile( | |
| r"(__vite_import_meta_env__\$\w+=\{)([^}]*)(\})" | |
| ) | |
| HEARTBEAT_INTERVAL_MS = 60_000 | |
| HEARTBEAT_MARKER = "fiftyone-hf-session-heartbeat" | |
| MANIFEST_PATH = Path("/app/datasets.json") | |
| LOG_FORMAT = "%(asctime)s | %(levelname)s | %(name)s | %(message)s" | |
| logging.basicConfig(level=logging.INFO, format=LOG_FORMAT) | |
| logger = logging.getLogger(__name__) | |
| def main(): | |
| """Enables stateless state and browser session heartbeats.""" | |
| static_dir = _get_static_dir() | |
| dataset_names = _get_dataset_names() | |
| _enable_stateless_frontend(static_dir) | |
| _add_session_heartbeat(static_dir, dataset_names) | |
| def _get_static_dir(): | |
| """Returns the static frontend directory in the installed package.""" | |
| spec = importlib.util.find_spec("fiftyone") | |
| if spec is None or spec.origin is None: | |
| raise RuntimeError("Could not locate the installed FiftyOne package") | |
| static_dir = Path(spec.origin).parent / "server" / "static" | |
| if not static_dir.is_dir(): | |
| raise RuntimeError( | |
| f"Could not locate FiftyOne static assets at {static_dir}" | |
| ) | |
| logger.info("Located FiftyOne frontend at %s", static_dir) | |
| return static_dir | |
| def _get_dataset_names(): | |
| """Gets the configured base dataset names from the manifest.""" | |
| with open(MANIFEST_PATH) as file: | |
| manifest = json.load(file) | |
| names = [entry["name"] for entry in manifest["datasets"]] | |
| if not names: | |
| raise ValueError("datasets.json must contain at least one dataset") | |
| return names | |
| def _enable_stateless_frontend(static_dir): | |
| """Enables URL-local state in every compiled Vite environment object.""" | |
| javascript_files = sorted((static_dir / "assets").glob("*.js")) | |
| reference_count = 0 | |
| environment_assignments = 0 | |
| patched_assignments = 0 | |
| def _inject_flag(match): | |
| nonlocal environment_assignments, patched_assignments | |
| environment_assignments += 1 | |
| properties = match.group(2) | |
| if "VITE_NO_STATE:" in properties: | |
| return match.group(0) | |
| patched_assignments += 1 | |
| return ( | |
| match.group(1) | |
| + "VITE_NO_STATE:!0," | |
| + properties | |
| + match.group(3) | |
| ) | |
| for path in javascript_files: | |
| content = path.read_text() | |
| reference_count += content.count(".VITE_NO_STATE") | |
| patched = ENV_ASSIGNMENT_PATTERN.sub(_inject_flag, content) | |
| if patched != content: | |
| path.write_text(patched) | |
| logger.info("Enabled stateless mode in %s", path.name) | |
| if reference_count == 0: | |
| raise RuntimeError( | |
| "The packaged frontend contains no VITE_NO_STATE references" | |
| ) | |
| if environment_assignments == 0: | |
| raise RuntimeError("No compiled Vite environment objects were found") | |
| logger.info( | |
| "Stateless patch complete: references=%d environments=%d patched=%d", | |
| reference_count, | |
| environment_assignments, | |
| patched_assignments, | |
| ) | |
| def _add_session_heartbeat(static_dir, dataset_names): | |
| """Adds a heartbeat that keeps the browser's dataset clone alive.""" | |
| index_path = static_dir / "index.html" | |
| content = index_path.read_text() | |
| if HEARTBEAT_MARKER in content: | |
| logger.info("Browser session heartbeat is already installed") | |
| return | |
| session_script = _get_session_script(dataset_names) | |
| if "</head>" not in content: | |
| raise RuntimeError(f"Could not patch missing </head> in {index_path}") | |
| index_path.write_text( | |
| content.replace("</head>", session_script + "</head>", 1) | |
| ) | |
| logger.info( | |
| "Installed browser heartbeat with interval=%dms", | |
| HEARTBEAT_INTERVAL_MS, | |
| ) | |
| def _get_session_script(dataset_names): | |
| """Returns the inline browser identity and heartbeat script.""" | |
| base_paths = json.dumps( | |
| [f"/datasets/{name}" for name in dataset_names], | |
| separators=(",", ":"), | |
| ) | |
| return ( | |
| f'<script id="{HEARTBEAT_MARKER}">' | |
| f"if({base_paths}." | |
| 'includes(location.pathname))location.replace("/");' | |
| 'const foSessionKey="fiftyone_demo_session";' | |
| 'const foFetch=window.fetch.bind(window);' | |
| 'window.fetch=(input,init={})=>{' | |
| 'const token=localStorage.getItem(foSessionKey);' | |
| 'const target=typeof input==="string"?input:' | |
| 'input instanceof Request?input.url:String(input);' | |
| 'const url=new URL(target,location.href);' | |
| 'if(token&&url.origin===location.origin){' | |
| 'const sourceHeaders=init.headers||' | |
| '(input instanceof Request?input.headers:void 0);' | |
| 'const headers=new Headers(sourceHeaders);' | |
| 'headers.set("X-FiftyOne-Session",token);' | |
| 'init={...init,headers};' | |
| '}return foFetch(input,init);' | |
| '};' | |
| 'setInterval(()=>{' | |
| 'const dataset=location.pathname.split("/").pop();' | |
| 'fetch("/__session/heartbeat?dataset="+encodeURIComponent(dataset),' | |
| '{method:"POST",credentials:"same-origin"}).then(response=>{' | |
| 'if(response.status===401){' | |
| 'localStorage.removeItem(foSessionKey);' | |
| 'location.replace("/");' | |
| '}' | |
| '});' | |
| '},' | |
| f"{HEARTBEAT_INTERVAL_MS});" | |
| "</script>" | |
| ) | |
| if __name__ == "__main__": | |
| main() | |