Spaces:
Build error
Build error
Download js_execution.py from Hypecat/ChessCommanderFlet: direct link, hf CLI and curl.
- Browser
- Download file 6.67 kB
-
https://huggingface.co/spaces/Hypecat/ChessCommanderFlet/resolve/main/js_execution.py
- Command line
-
hf download hf://spaces/Hypecat/ChessCommanderFlet/js_execution.py
-
curl -L -o js_execution.py https://huggingface.co/spaces/Hypecat/ChessCommanderFlet/resolve/main/js_execution.py
6.67 kB
| import asyncio | |
| import logging | |
| import contextlib | |
| from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect | |
| from fastapi.responses import HTMLResponse | |
| import uuid | |
| import html | |
| logger = logging.getLogger(__name__) | |
| class JSExecutionContext: | |
| def __init__(self, endpoint: str, result_future: asyncio.Future): | |
| self.endpoint = endpoint | |
| self.result_future = result_future | |
| self.hidden_iframe_name = "hidden-iframe" | |
| class JSExecutionRouter: | |
| def __init__(self): | |
| self.app = None | |
| self.active_routes = set() | |
| def init_app(self, app: FastAPI): | |
| self.app = app | |
| def get_eval_js_html(self, js_code: str, result_id: str): | |
| # escaped_js = html.escape(js_code) | |
| logger.info(f"Generating HTML for JavaScript execution. Result ID: {result_id}") | |
| return f""" | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Execute JavaScript</title> | |
| </head> | |
| <body> | |
| <script> | |
| console.log("JavaScript execution page loaded"); | |
| async function executeAndReturn() {{ | |
| console.log("executeAndReturn function called"); | |
| try {{ | |
| const result = await (async () => {{ {js_code} }})(); | |
| console.log("JavaScript execution result:", result); | |
| await fetch('/js-result/{result_id}', {{ | |
| method: 'POST', | |
| headers: {{ 'Content-Type': 'application/json' }}, | |
| body: JSON.stringify({{ result }}) | |
| }}); | |
| }} catch (error) {{ | |
| console.error('Error:', error); | |
| await fetch('/js-result/{result_id}', {{ | |
| method: 'POST', | |
| headers: {{ 'Content-Type': 'application/json' }}, | |
| body: JSON.stringify({{ error: error.toString() }}) | |
| }}); | |
| }} | |
| }} | |
| executeAndReturn(); | |
| </script> | |
| </body> | |
| </html> | |
| """ | |
| async def create_dynamic_endpoint(self, js_code: str): | |
| if not self.app: | |
| raise RuntimeError("DynamicRouter not initialized with FastAPI app") | |
| result_id = str(uuid.uuid4()) | |
| result_future = asyncio.Future() | |
| async def serve_eval_js_page(): | |
| logger.info(f"Serving eval-js page for result ID: {result_id}") | |
| return HTMLResponse(content=self.get_eval_js_html(js_code, result_id)) | |
| async def receive_js_result(data: dict): | |
| logger.info(f"Received result for ID: {result_id}") | |
| if 'error' in data: | |
| result_future.set_exception(Exception(data['error'])) | |
| else: | |
| result_future.set_result(data['result']) | |
| return {"status": "received"} | |
| self.active_routes.add(result_id) | |
| try: | |
| yield JSExecutionContext(f"/eval-js/{result_id}", result_future) | |
| finally: | |
| self.cleanup_route(result_id) | |
| def cleanup_route(self, result_id: str): | |
| if result_id in self.active_routes: | |
| self.app.router.routes = [route for route in self.app.router.routes if route.path not in [f"/eval-js/{result_id}", f"/js-result/{result_id}"]] | |
| self.active_routes.remove(result_id) | |
| js_execution_router = JSExecutionRouter() | |
| def add_js_execution_routes(app: FastAPI): | |
| js_execution_router.init_app(app) | |
| async def websocket_endpoint(websocket: WebSocket): | |
| await websocket.accept() | |
| try: | |
| while True: | |
| data = await websocket.receive_text() | |
| await broadcast_camera_frame(data) | |
| except WebSocketDisconnect: | |
| pass | |
| except Exception as e: | |
| logger.error(f"WebSocket error: {str(e)}") | |
| # Add this new function to handle broadcasting | |
| async def broadcast_camera_frame(frame_data: str): | |
| # This function will be called from the Flet app to set the callback | |
| if hasattr(broadcast_camera_frame, 'callback'): | |
| await broadcast_camera_frame.callback(frame_data) | |
| # Function to set the callback from the Flet app | |
| def set_camera_frame_callback(callback): | |
| broadcast_camera_frame.callback = callback | |
| def mount_flet_app(app: FastAPI, route: str, flet_app): | |
| # Mount the Flet app | |
| app.mount("/flet-app-internal", flet_app) | |
| app.flet_app = flet_app # Store reference to the Flet app | |
| async def serve_main_page(request: Request): | |
| html_content = f""" | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Camera Stream App</title> | |
| <style> | |
| body, html {{ | |
| margin: 0; | |
| padding: 0; | |
| height: 100%; | |
| overflow: hidden; | |
| }} | |
| #flet-app-frame {{ | |
| width: 100%; | |
| height: 100%; | |
| border: none; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| }} | |
| </style> | |
| </head> | |
| <body> | |
| <iframe id="flet-app-frame"></iframe> | |
| <iframe name="hidden-iframe" style="display:none;"></iframe> | |
| <script> | |
| window.onload = function() {{ | |
| var iframe = document.getElementById('flet-app-frame'); | |
| var currentProtocol = window.location.protocol; | |
| var currentHost = window.location.host; | |
| var src = currentProtocol + '//' + currentHost + '/flet-app-internal/'; | |
| iframe.src = src; | |
| // Set Content-Security-Policy based on the current protocol | |
| var meta = document.createElement('meta'); | |
| meta.httpEquiv = "Content-Security-Policy"; | |
| meta.content = currentProtocol === 'https:' ? "upgrade-insecure-requests" : ""; | |
| document.head.appendChild(meta); | |
| }}; | |
| </script> | |
| </body> | |
| </html> | |
| """ | |
| return HTMLResponse(content=html_content) | |
| # Add the JS execution routes | |
| add_js_execution_routes(app) |