File size: 2,422 Bytes
6f3d5da
 
 
 
 
f0c48a6
6f3d5da
f0c48a6
 
6f3d5da
f0c48a6
 
 
 
 
 
 
 
 
 
 
6f3d5da
f0c48a6
 
 
6f3d5da
 
f0c48a6
6f3d5da
 
f0c48a6
6f3d5da
 
f0c48a6
 
6f3d5da
f0c48a6
6f3d5da
f0c48a6
 
 
 
 
 
6f3d5da
f0c48a6
 
 
 
 
6f3d5da
 
 
f0c48a6
 
6f3d5da
f0c48a6
 
6f3d5da
f0c48a6
6f3d5da
f0c48a6
 
 
 
6f3d5da
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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) ---
@spaces.GPU
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 ---
@app.get("/reload")
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) ---
@app.api_route("/fm", methods=["GET", "POST"])
@app.api_route("/fm/{path:path}", methods=["GET", "POST"])
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)