node-py-test / app.py
pngwn
asd
9840eb8
raw
history blame
2.1 kB
import httpx
from fastapi import FastAPI, Request
from fastapi.responses import StreamingResponse, JSONResponse
from fastapi.middleware.cors import CORSMiddleware
import uvicorn
import subprocess
import signal
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
PYTHON_PORT = 7860
NODE_PORT = 4321
NODE_SCRIPT_PATH = "build"
node_process = subprocess.Popen(["node", NODE_SCRIPT_PATH])
def handle_sigterm(signum, frame):
print("Stopping Node.js server...")
node_process.terminate()
node_process.wait()
exit(0)
signal.signal(signal.SIGTERM, handle_sigterm)
@app.on_event("shutdown")
def shutdown_event():
print("Stopping Node.js server...")
node_process.terminate()
node_process.wait()
@app.get("/config")
async def route_with_config():
return JSONResponse(content={"one": "hello", "two": "from", "three": "Python"})
async def proxy_to_node(request: Request):
client = httpx.AsyncClient()
# Preserve the full path including query parameters
full_path = request.url.path
if request.url.query:
full_path += f"?{request.url.query}"
url = f"http://localhost:{NODE_PORT}{full_path}"
headers = {
k: v
for k, v in request.headers.items()
if k.lower() not in ["host", "content-length"]
}
body = await request.body()
async with client:
response = await client.request(
method=request.method, url=url, headers=headers, content=body
)
return StreamingResponse(
response.iter_bytes(),
status_code=response.status_code,
headers=response.headers,
)
@app.api_route(
"/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
)
async def catch_all(request: Request, path: str):
return await proxy_to_node(request)
if __name__ == "__main__":
print(
f"Starting dual server. Python handles specific routes, Node handles the rest."
)
uvicorn.run(app, host="0.0.0.0", port=PYTHON_PORT)