CORVO-AI commited on
Commit
f0c48a6
·
verified ·
1 Parent(s): 7c6f376

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -43
app.py CHANGED
@@ -3,67 +3,66 @@ import gradio as gr
3
  import subprocess, os, sys, time
4
  import urllib.request, urllib.error
5
  from fastapi import Request
6
- from fastapi.responses import Response
7
 
8
- SECOND_PORT = 9001
9
- FLASK_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "flask-app")
10
 
11
- # --- Launch YOUR flask-app as a background process on its own port ---
12
- # cwd=FLASK_DIR so its templates/relative paths resolve correctly.
13
- subprocess.Popen(
14
- [sys.executable, "app.py"],
15
- cwd=FLASK_DIR,
16
- stdout=sys.stdout,
17
- stderr=sys.stderr,
18
- )
 
 
 
19
 
20
- # --- Required ZeroGPU function (top level) ---
 
 
21
  @spaces.GPU
22
  def gpu_function():
23
- import torch
24
- return "GPU OK" if torch.cuda.is_available() else "GPU function executed"
25
 
26
- # --- Gradio owns the ONLY public port 7860 ---
27
  with gr.Blocks() as demo:
28
- gr.Markdown("Host running. Your Flask app is on 9001, bridged at /app")
29
- gr.Button("GPU check").click(gpu_function, outputs=gr.Textbox())
30
 
31
  demo.queue()
32
- demo.launch(
33
- server_name="0.0.0.0",
34
- server_port=7860,
35
- ssr_mode=False, # prevents the Node SSR shutdown
36
- prevent_thread_lock=True, # returns control so we can mount the proxy after launch
37
- )
38
 
39
- app = demo.app # Gradio's FastAPI app on 7860
40
 
41
- # --- A session-aware, redirect-aware proxy: /app/... -> 127.0.0.1:9001/app/... ---
42
- class NoRedirect(urllib.request.HTTPRedirectHandler):
43
- def redirect_request(self, *args, **kwargs):
44
- return None # pass 3xx straight to the browser so cookies stick
 
 
45
 
46
- @app.api_route("/app", methods=["GET", "POST"])
47
- @app.api_route("/app/{path:path}", methods=["GET", "POST"])
48
- async def proxy_to_flask(request: Request, path: str = ""):
49
- url = f"http://127.0.0.1:{SECOND_PORT}/app/{path}"
 
50
  if request.url.query:
51
  url += "?" + request.url.query
52
  body = await request.body()
53
- fwd_headers = {k: v for k, v in request.headers.items() if k.lower() != "host"}
54
- req = urllib.request.Request(url, data=body or None, method=request.method, headers=fwd_headers)
55
  try:
56
- opener = urllib.request.build_opener(NoRedirect)
57
- with opener.open(req) as r:
58
- resp_body, status, headers = r.read(), r.status, r.headers
59
  except urllib.error.HTTPError as e:
60
- resp_body, status, headers = e.read(), e.code, e.headers
61
  except urllib.error.URLError:
62
- return Response(content=b"flask-app not up yet on 9001", status_code=502)
63
- out_headers = {k: v for k, v in headers.items()
64
- if k.lower() in ("set-cookie", "location", "content-type")}
65
- return Response(content=resp_body, status_code=status, headers=out_headers)
66
 
67
- # --- Keep the process alive (launch returned control) ---
68
  while True:
69
  time.sleep(3600)
 
3
  import subprocess, os, sys, time
4
  import urllib.request, urllib.error
5
  from fastapi import Request
6
+ from fastapi.responses import Response, HTMLResponse
7
 
8
+ PORT = 9001
9
+ FM_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "file-manager")
10
 
11
+ # --- Launch the file manager as a background child process ---
12
+ proc = {"p": None}
13
+ def start_fm():
14
+ if proc["p"] and proc["p"].poll() is None:
15
+ proc["p"].terminate()
16
+ try:
17
+ proc["p"].wait(timeout=5)
18
+ except Exception:
19
+ proc["p"].kill()
20
+ proc["p"] = subprocess.Popen([sys.executable, "app.py"], cwd=FM_DIR,
21
+ stdout=sys.stdout, stderr=sys.stderr)
22
 
23
+ start_fm()
24
+
25
+ # --- Required ZeroGPU gate (unused, but mandatory to boot) ---
26
  @spaces.GPU
27
  def gpu_function():
28
+ return "ok"
 
29
 
 
30
  with gr.Blocks() as demo:
31
+ gr.Markdown("Self-editing computer. File manager at /fm, hot-reload at /reload")
 
32
 
33
  demo.queue()
34
+ demo.launch(server_name="0.0.0.0", server_port=7860,
35
+ ssr_mode=False, prevent_thread_lock=True)
 
 
 
 
36
 
37
+ app = demo.app
38
 
39
+ # --- Hot-reload: respawn ONLY the file-manager process, no Space rebuild ---
40
+ @app.get("/reload")
41
+ def reload_fm():
42
+ start_fm()
43
+ time.sleep(1)
44
+ return HTMLResponse('Reloaded file-manager process. <a href="/fm/">back to /fm</a>')
45
 
46
+ # --- Proxy: /fm/... -> 127.0.0.1:9001/fm/... (methods + body forwarded) ---
47
+ @app.api_route("/fm", methods=["GET", "POST"])
48
+ @app.api_route("/fm/{path:path}", methods=["GET", "POST"])
49
+ async def proxy(request: Request, path: str = ""):
50
+ url = f"http://127.0.0.1:{PORT}/fm/{path}"
51
  if request.url.query:
52
  url += "?" + request.url.query
53
  body = await request.body()
54
+ fwd = {k: v for k, v in request.headers.items() if k.lower() != "host"}
55
+ req = urllib.request.Request(url, data=body or None, method=request.method, headers=fwd)
56
  try:
57
+ with urllib.request.urlopen(req) as r:
58
+ data, status, headers = r.read(), r.status, r.headers
 
59
  except urllib.error.HTTPError as e:
60
+ data, status, headers = e.read(), e.code, e.headers
61
  except urllib.error.URLError:
62
+ return Response(content=b"file-manager not up yet on 9001", status_code=502)
63
+ out = {k: v for k, v in headers.items()
64
+ if k.lower() in ("set-cookie", "location", "content-type")}
65
+ return Response(content=data, status_code=status, headers=out)
66
 
 
67
  while True:
68
  time.sleep(3600)