File size: 3,148 Bytes
403671f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import gradio as gr
import subprocess
import requests
from fastapi import FastAPI, Request
from fastapi.responses import StreamingResponse
import uvicorn
import asyncio
import signal
import sys
import os

# Create FastAPI app
app = FastAPI()

# Create Gradio interface
with gr.Blocks() as demo:
    gr.Markdown("# Welcome to the Proxy App")
    # Add your Gradio components here

# Start Node.js process
node_process = None

def start_node():
    global node_process
    try:
        # Start Node.js process
        node_process = subprocess.Popen(
            ["node", "api.js"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            preexec_fn=os.setsid  # This makes the process a session leader
        )
        print("Node.js process started")
    except Exception as e:
        print(f"Failed to start Node.js process: {e}")
        sys.exit(1)

def cleanup():
    if node_process:
        # Kill the entire process group
        os.killpg(os.getpgid(node_process.pid), signal.SIGTERM)
        print("Node.js process terminated")

# Register cleanup handler
import atexit
atexit.register(cleanup)

@app.middleware("http")
async def proxy_middleware(request: Request, call_next):
    # Get the path
    path = request.url.path
    
    # If path starts with /api, proxy to Node.js server
    if path.startswith("/api"):
        try:
            # Build the target URL
            target_url = f"http://localhost:6666{path}"
            
            # Get the request body
            body = await request.body()
            
            # Get headers (excluding host)
            headers = dict(request.headers)
            headers.pop("host", None)
            
            # Make the request to the Node.js server
            response = requests.request(
                method=request.method,
                url=target_url,
                data=body,
                headers=headers,
                params=dict(request.query_params),
                stream=True
            )
            
            # Create a generator for streaming the response
            async def stream_response():
                for chunk in response.iter_content(chunk_size=8192):
                    yield chunk
            
            # Return a streaming response with the same status code and headers
            return StreamingResponse(
                stream_response(),
                status_code=response.status_code,
                headers=dict(response.headers)
            )
            
        except Exception as e:
            print(f"Proxy error: {e}")
            return {"error": "Proxy error occurred"}
    
    # If not an API route, continue normal processing
    return await call_next(request)

# Mount Gradio app under FastAPI
app = gr.mount_gradio_app(app, demo, path="/")

if __name__ == "__main__":
    # Start Node.js process
    start_node()
    
    # Start uvicorn server
    config = uvicorn.Config(
        app=app,
        host="0.0.0.0",
        port=7860,
        log_level="info"
    )
    server = uvicorn.Server(config)
    
    try:
        server.run()
    finally:
        cleanup()