DeFactOfficial commited on
Commit
403671f
·
verified ·
1 Parent(s): fceaf4c

Gradio app with node launcher and reverse proxy

Browse files
Files changed (1) hide show
  1. app.py +114 -0
app.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import subprocess
3
+ import requests
4
+ from fastapi import FastAPI, Request
5
+ from fastapi.responses import StreamingResponse
6
+ import uvicorn
7
+ import asyncio
8
+ import signal
9
+ import sys
10
+ import os
11
+
12
+ # Create FastAPI app
13
+ app = FastAPI()
14
+
15
+ # Create Gradio interface
16
+ with gr.Blocks() as demo:
17
+ gr.Markdown("# Welcome to the Proxy App")
18
+ # Add your Gradio components here
19
+
20
+ # Start Node.js process
21
+ node_process = None
22
+
23
+ def start_node():
24
+ global node_process
25
+ try:
26
+ # Start Node.js process
27
+ node_process = subprocess.Popen(
28
+ ["node", "api.js"],
29
+ stdout=subprocess.PIPE,
30
+ stderr=subprocess.PIPE,
31
+ preexec_fn=os.setsid # This makes the process a session leader
32
+ )
33
+ print("Node.js process started")
34
+ except Exception as e:
35
+ print(f"Failed to start Node.js process: {e}")
36
+ sys.exit(1)
37
+
38
+ def cleanup():
39
+ if node_process:
40
+ # Kill the entire process group
41
+ os.killpg(os.getpgid(node_process.pid), signal.SIGTERM)
42
+ print("Node.js process terminated")
43
+
44
+ # Register cleanup handler
45
+ import atexit
46
+ atexit.register(cleanup)
47
+
48
+ @app.middleware("http")
49
+ async def proxy_middleware(request: Request, call_next):
50
+ # Get the path
51
+ path = request.url.path
52
+
53
+ # If path starts with /api, proxy to Node.js server
54
+ if path.startswith("/api"):
55
+ try:
56
+ # Build the target URL
57
+ target_url = f"http://localhost:6666{path}"
58
+
59
+ # Get the request body
60
+ body = await request.body()
61
+
62
+ # Get headers (excluding host)
63
+ headers = dict(request.headers)
64
+ headers.pop("host", None)
65
+
66
+ # Make the request to the Node.js server
67
+ response = requests.request(
68
+ method=request.method,
69
+ url=target_url,
70
+ data=body,
71
+ headers=headers,
72
+ params=dict(request.query_params),
73
+ stream=True
74
+ )
75
+
76
+ # Create a generator for streaming the response
77
+ async def stream_response():
78
+ for chunk in response.iter_content(chunk_size=8192):
79
+ yield chunk
80
+
81
+ # Return a streaming response with the same status code and headers
82
+ return StreamingResponse(
83
+ stream_response(),
84
+ status_code=response.status_code,
85
+ headers=dict(response.headers)
86
+ )
87
+
88
+ except Exception as e:
89
+ print(f"Proxy error: {e}")
90
+ return {"error": "Proxy error occurred"}
91
+
92
+ # If not an API route, continue normal processing
93
+ return await call_next(request)
94
+
95
+ # Mount Gradio app under FastAPI
96
+ app = gr.mount_gradio_app(app, demo, path="/")
97
+
98
+ if __name__ == "__main__":
99
+ # Start Node.js process
100
+ start_node()
101
+
102
+ # Start uvicorn server
103
+ config = uvicorn.Config(
104
+ app=app,
105
+ host="0.0.0.0",
106
+ port=7860,
107
+ log_level="info"
108
+ )
109
+ server = uvicorn.Server(config)
110
+
111
+ try:
112
+ server.run()
113
+ finally:
114
+ cleanup()