Spaces:
Sleeping
Sleeping
Commit ·
7551720
1
Parent(s): e026dc9
Fix: Root route now serves frontend, smart API routing by method
Browse files
main.py
CHANGED
|
@@ -296,9 +296,9 @@ class TestingMatrixResponse(BaseModel):
|
|
| 296 |
|
| 297 |
|
| 298 |
# Endpoints
|
| 299 |
-
@app.get("/")
|
| 300 |
-
async def
|
| 301 |
-
"""
|
| 302 |
return {
|
| 303 |
"name": "Ad Generator Lite",
|
| 304 |
"version": "2.0.0",
|
|
@@ -327,6 +327,26 @@ async def root():
|
|
| 327 |
}
|
| 328 |
|
| 329 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 330 |
@app.get("/health")
|
| 331 |
async def health():
|
| 332 |
"""Health check endpoint."""
|
|
@@ -1124,20 +1144,46 @@ async def delete_stored_ad(ad_id: str, username: str = Depends(get_current_user)
|
|
| 1124 |
async def frontend_proxy(path: str, request: StarletteRequest):
|
| 1125 |
"""
|
| 1126 |
Proxy frontend requests to Next.js server.
|
| 1127 |
-
|
| 1128 |
"""
|
| 1129 |
-
# API routes
|
| 1130 |
-
|
| 1131 |
-
"
|
| 1132 |
-
"
|
| 1133 |
]
|
| 1134 |
|
| 1135 |
-
#
|
| 1136 |
-
|
| 1137 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1138 |
raise HTTPException(status_code=404, detail="API endpoint not found")
|
| 1139 |
|
| 1140 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1141 |
try:
|
| 1142 |
async with httpx.AsyncClient(timeout=30.0) as client:
|
| 1143 |
# Forward the request to Next.js
|
|
|
|
| 296 |
|
| 297 |
|
| 298 |
# Endpoints
|
| 299 |
+
@app.get("/api/info")
|
| 300 |
+
async def api_info():
|
| 301 |
+
"""API info endpoint."""
|
| 302 |
return {
|
| 303 |
"name": "Ad Generator Lite",
|
| 304 |
"version": "2.0.0",
|
|
|
|
| 327 |
}
|
| 328 |
|
| 329 |
|
| 330 |
+
# Root route - proxy to Next.js frontend
|
| 331 |
+
@app.get("/")
|
| 332 |
+
async def root():
|
| 333 |
+
"""Proxy root to Next.js frontend."""
|
| 334 |
+
try:
|
| 335 |
+
async with httpx.AsyncClient(timeout=30.0) as client:
|
| 336 |
+
response = await client.get("http://localhost:3000/")
|
| 337 |
+
return StreamingResponse(
|
| 338 |
+
response.iter_bytes(),
|
| 339 |
+
status_code=response.status_code,
|
| 340 |
+
headers=dict(response.headers),
|
| 341 |
+
media_type=response.headers.get("content-type"),
|
| 342 |
+
)
|
| 343 |
+
except httpx.RequestError:
|
| 344 |
+
raise HTTPException(
|
| 345 |
+
status_code=503,
|
| 346 |
+
detail="Frontend server is not available."
|
| 347 |
+
)
|
| 348 |
+
|
| 349 |
+
|
| 350 |
@app.get("/health")
|
| 351 |
async def health():
|
| 352 |
"""Health check endpoint."""
|
|
|
|
| 1144 |
async def frontend_proxy(path: str, request: StarletteRequest):
|
| 1145 |
"""
|
| 1146 |
Proxy frontend requests to Next.js server.
|
| 1147 |
+
Smart routing based on path AND HTTP method.
|
| 1148 |
"""
|
| 1149 |
+
# Exact API-only routes (never frontend)
|
| 1150 |
+
api_only_routes = [
|
| 1151 |
+
"health", "auth/login", "api/correct", "db/stats", "db/ads",
|
| 1152 |
+
"strategies", "extensive/generate"
|
| 1153 |
]
|
| 1154 |
|
| 1155 |
+
# Routes that are API for POST but frontend for GET
|
| 1156 |
+
# GET /generate -> frontend page, POST /generate -> API
|
| 1157 |
+
api_post_routes = [
|
| 1158 |
+
"generate", "generate/batch", "matrix/generate", "matrix/testing"
|
| 1159 |
+
]
|
| 1160 |
+
|
| 1161 |
+
# Routes that are API for GET (data endpoints)
|
| 1162 |
+
api_get_routes = [
|
| 1163 |
+
"matrix/angles", "matrix/concepts", "matrix/angle", "matrix/concept",
|
| 1164 |
+
"matrix/compatible", "db/ad"
|
| 1165 |
+
]
|
| 1166 |
+
|
| 1167 |
+
# Check if this is an API-only route
|
| 1168 |
+
if any(path == route or path.startswith(f"{route}/") for route in api_only_routes):
|
| 1169 |
+
raise HTTPException(status_code=404, detail="API endpoint not found")
|
| 1170 |
+
|
| 1171 |
+
# Check if this is a POST to an API endpoint
|
| 1172 |
+
if request.method == "POST" and any(path == route or path.startswith(f"{route}/") for route in api_post_routes):
|
| 1173 |
raise HTTPException(status_code=404, detail="API endpoint not found")
|
| 1174 |
|
| 1175 |
+
# Check if path starts with image serving routes
|
| 1176 |
+
if path.startswith("image/") or path.startswith("images/"):
|
| 1177 |
+
raise HTTPException(status_code=404, detail="API endpoint not found")
|
| 1178 |
+
|
| 1179 |
+
# Check if this is a GET for data endpoints (with specific patterns)
|
| 1180 |
+
if request.method == "GET":
|
| 1181 |
+
for route in api_get_routes:
|
| 1182 |
+
# Exact match or with path parameter (e.g., matrix/angle/fear)
|
| 1183 |
+
if path == route or (path.startswith(f"{route}/") and "/" in path[len(route)+1:] == False):
|
| 1184 |
+
raise HTTPException(status_code=404, detail="API endpoint not found")
|
| 1185 |
+
|
| 1186 |
+
# Everything else goes to Next.js frontend
|
| 1187 |
try:
|
| 1188 |
async with httpx.AsyncClient(timeout=30.0) as client:
|
| 1189 |
# Forward the request to Next.js
|