Spaces:
Paused
Paused
| import spaces | |
| import gradio as gr | |
| import subprocess, os, sys, time | |
| import urllib.request, urllib.error | |
| from fastapi import Request | |
| from fastapi.responses import Response, HTMLResponse | |
| PORT = 9001 | |
| FM_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "file-manager") | |
| # --- Launch the file manager as a background child process --- | |
| proc = {"p": None} | |
| def start_fm(): | |
| if proc["p"] and proc["p"].poll() is None: | |
| proc["p"].terminate() | |
| try: | |
| proc["p"].wait(timeout=5) | |
| except Exception: | |
| proc["p"].kill() | |
| proc["p"] = subprocess.Popen([sys.executable, "app.py"], cwd=FM_DIR, | |
| stdout=sys.stdout, stderr=sys.stderr) | |
| start_fm() | |
| # --- Required ZeroGPU gate (unused, but mandatory to boot) --- | |
| def gpu_function(): | |
| return "ok" | |
| with gr.Blocks() as demo: | |
| gr.Markdown("Self-editing computer. File manager at /fm, hot-reload at /reload") | |
| demo.queue() | |
| demo.launch(server_name="0.0.0.0", server_port=7860, | |
| ssr_mode=False, prevent_thread_lock=True) | |
| app = demo.app | |
| # --- Hot-reload: respawn ONLY the file-manager process, no Space rebuild --- | |
| def reload_fm(): | |
| start_fm() | |
| time.sleep(1) | |
| return HTMLResponse('Reloaded file-manager process. <a href="/fm/">back to /fm</a>') | |
| # --- Proxy: /fm/... -> 127.0.0.1:9001/fm/... (methods + body forwarded) --- | |
| async def proxy(request: Request, path: str = ""): | |
| url = f"http://127.0.0.1:{PORT}/fm/{path}" | |
| if request.url.query: | |
| url += "?" + request.url.query | |
| body = await request.body() | |
| fwd = {k: v for k, v in request.headers.items() if k.lower() != "host"} | |
| req = urllib.request.Request(url, data=body or None, method=request.method, headers=fwd) | |
| try: | |
| with urllib.request.urlopen(req) as r: | |
| data, status, headers = r.read(), r.status, r.headers | |
| except urllib.error.HTTPError as e: | |
| data, status, headers = e.read(), e.code, e.headers | |
| except urllib.error.URLError: | |
| return Response(content=b"file-manager not up yet on 9001", status_code=502) | |
| out = {k: v for k, v in headers.items() | |
| if k.lower() in ("set-cookie", "location", "content-type")} | |
| return Response(content=data, status_code=status, headers=out) | |
| while True: | |
| time.sleep(3600) |