Spaces:
Running
Running
Fix the frontend route overlapping with backend ones
Browse files- src-python/src/main.py +47 -48
src-python/src/main.py
CHANGED
|
@@ -158,21 +158,6 @@ async def startup_event():
|
|
| 158 |
logger.info("✅ Server ready for robot connections!")
|
| 159 |
|
| 160 |
|
| 161 |
-
@app.get("/")
|
| 162 |
-
async def serve_frontend():
|
| 163 |
-
"""Serve the main frontend page"""
|
| 164 |
-
static_dir = get_static_dir()
|
| 165 |
-
if not static_dir:
|
| 166 |
-
return {
|
| 167 |
-
"message": "Frontend not built. Run 'bun run build' to build the frontend."
|
| 168 |
-
}
|
| 169 |
-
|
| 170 |
-
index_file = os.path.join(static_dir, "index.html")
|
| 171 |
-
if os.path.exists(index_file):
|
| 172 |
-
return FileResponse(index_file)
|
| 173 |
-
return {"message": "Frontend not built. Run 'bun run build' to build the frontend."}
|
| 174 |
-
|
| 175 |
-
|
| 176 |
@app.get("/status")
|
| 177 |
async def get_status():
|
| 178 |
"""Get server status for health checks"""
|
|
@@ -185,39 +170,6 @@ async def get_status():
|
|
| 185 |
}
|
| 186 |
|
| 187 |
|
| 188 |
-
# Serve static assets from the _app directory
|
| 189 |
-
@app.get("/_app/{path:path}")
|
| 190 |
-
async def serve_app_assets(path: str):
|
| 191 |
-
"""Serve Svelte app assets"""
|
| 192 |
-
static_dir = get_static_dir()
|
| 193 |
-
if not static_dir:
|
| 194 |
-
raise HTTPException(status_code=404, detail="Frontend not found")
|
| 195 |
-
|
| 196 |
-
file_path = os.path.join(static_dir, "_app", path)
|
| 197 |
-
if os.path.exists(file_path) and os.path.isfile(file_path):
|
| 198 |
-
return FileResponse(file_path)
|
| 199 |
-
raise HTTPException(status_code=404, detail="File not found")
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
# Catch-all route for client-side routing (SPA fallback)
|
| 203 |
-
@app.get("/{path:path}")
|
| 204 |
-
async def serve_spa_fallback(path: str):
|
| 205 |
-
"""Serve the frontend for client-side routing"""
|
| 206 |
-
# If it's an API, WebSocket, or static asset path, let it pass through to other handlers
|
| 207 |
-
if path.startswith(("api/", "ws/", "robots/", "_app/", "static/", "favicon")):
|
| 208 |
-
raise HTTPException(status_code=404, detail="Not found")
|
| 209 |
-
|
| 210 |
-
# For all other paths, serve the index.html (SPA)
|
| 211 |
-
static_dir = get_static_dir()
|
| 212 |
-
if not static_dir:
|
| 213 |
-
raise HTTPException(status_code=404, detail="Frontend not found")
|
| 214 |
-
|
| 215 |
-
index_file = os.path.join(static_dir, "index.html")
|
| 216 |
-
if os.path.exists(index_file):
|
| 217 |
-
return FileResponse(index_file)
|
| 218 |
-
raise HTTPException(status_code=404, detail="Frontend not found")
|
| 219 |
-
|
| 220 |
-
|
| 221 |
# ============= ROBOT MANAGEMENT API =============
|
| 222 |
|
| 223 |
|
|
@@ -687,6 +639,53 @@ async def sync_slave_with_current_state(robot_id: str, websocket: WebSocket):
|
|
| 687 |
})
|
| 688 |
|
| 689 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 690 |
if __name__ == "__main__":
|
| 691 |
import uvicorn
|
| 692 |
|
|
|
|
| 158 |
logger.info("✅ Server ready for robot connections!")
|
| 159 |
|
| 160 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
@app.get("/status")
|
| 162 |
async def get_status():
|
| 163 |
"""Get server status for health checks"""
|
|
|
|
| 170 |
}
|
| 171 |
|
| 172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
# ============= ROBOT MANAGEMENT API =============
|
| 174 |
|
| 175 |
|
|
|
|
| 639 |
})
|
| 640 |
|
| 641 |
|
| 642 |
+
# ============= FRONTEND SERVING ROUTES (Must be last) =============
|
| 643 |
+
|
| 644 |
+
|
| 645 |
+
# Serve static assets from the _app directory
|
| 646 |
+
@app.get("/_app/{path:path}")
|
| 647 |
+
async def serve_app_assets(path: str):
|
| 648 |
+
"""Serve Svelte app assets"""
|
| 649 |
+
static_dir = get_static_dir()
|
| 650 |
+
if not static_dir:
|
| 651 |
+
raise HTTPException(status_code=404, detail="Frontend not found")
|
| 652 |
+
|
| 653 |
+
file_path = os.path.join(static_dir, "_app", path)
|
| 654 |
+
if os.path.exists(file_path) and os.path.isfile(file_path):
|
| 655 |
+
return FileResponse(file_path)
|
| 656 |
+
raise HTTPException(status_code=404, detail="File not found")
|
| 657 |
+
|
| 658 |
+
|
| 659 |
+
@app.get("/")
|
| 660 |
+
async def serve_frontend():
|
| 661 |
+
"""Serve the main frontend page"""
|
| 662 |
+
static_dir = get_static_dir()
|
| 663 |
+
if not static_dir:
|
| 664 |
+
return {
|
| 665 |
+
"message": "Frontend not built. Run 'bun run build' to build the frontend."
|
| 666 |
+
}
|
| 667 |
+
|
| 668 |
+
index_file = os.path.join(static_dir, "index.html")
|
| 669 |
+
if os.path.exists(index_file):
|
| 670 |
+
return FileResponse(index_file)
|
| 671 |
+
return {"message": "Frontend not built. Run 'bun run build' to build the frontend."}
|
| 672 |
+
|
| 673 |
+
|
| 674 |
+
# Catch-all route for client-side routing (SPA fallback) - MUST BE LAST
|
| 675 |
+
@app.get("/{path:path}")
|
| 676 |
+
async def serve_spa_fallback(path: str):
|
| 677 |
+
"""Serve the frontend for client-side routing"""
|
| 678 |
+
# For all paths not handled by other routes, serve the index.html (SPA)
|
| 679 |
+
static_dir = get_static_dir()
|
| 680 |
+
if not static_dir:
|
| 681 |
+
raise HTTPException(status_code=404, detail="Frontend not found")
|
| 682 |
+
|
| 683 |
+
index_file = os.path.join(static_dir, "index.html")
|
| 684 |
+
if os.path.exists(index_file):
|
| 685 |
+
return FileResponse(index_file)
|
| 686 |
+
raise HTTPException(status_code=404, detail="Frontend not found")
|
| 687 |
+
|
| 688 |
+
|
| 689 |
if __name__ == "__main__":
|
| 690 |
import uvicorn
|
| 691 |
|