Kaadan commited on
Commit
e3cd6e2
·
1 Parent(s): 1b562af
Files changed (1) hide show
  1. backend/main.py +53 -27
backend/main.py CHANGED
@@ -1,9 +1,9 @@
1
  import os
2
- from fastapi import FastAPI, APIRouter, Request, Response
 
3
  from fastapi.middleware.cors import CORSMiddleware
4
  from fastapi.staticfiles import StaticFiles
5
  from fastapi.responses import FileResponse
6
- from pathlib import Path
7
  import logging
8
 
9
  from database.database import engine
@@ -15,28 +15,40 @@ from api.assessment_routes import router as assessment_router
15
  from api.application_routes import router as application_router
16
  from config import settings
17
 
18
- # Logging config
 
 
19
  logging.basicConfig(level=settings.log_level)
20
  logger = logging.getLogger(__name__)
21
 
22
- # Env
 
 
23
  PORT = int(os.environ.get("PORT", 7860))
24
  HOST = os.environ.get("HOST", "0.0.0.0")
 
25
 
 
 
 
26
  app = FastAPI(
27
  title=settings.app_name,
28
  description=settings.app_description,
29
  version=settings.app_version
30
  )
31
 
32
- # DB tables
 
 
33
  @app.on_event("startup")
34
  def startup_event():
35
  Base.metadata.create_all(bind=engine)
36
  logger.info(f"Database tables created/verified at {settings.database_url}")
37
 
38
- # CORS
39
- origins = os.getenv("CORS_ORIGINS", "").split(",")
 
 
40
  app.add_middleware(
41
  CORSMiddleware,
42
  allow_origins=[o.strip() for o in origins if o.strip()],
@@ -45,7 +57,9 @@ app.add_middleware(
45
  allow_headers=["*"],
46
  )
47
 
48
- # API routes
 
 
49
  api_router = APIRouter(prefix="/api")
50
  api_router.include_router(root_router)
51
  api_router.include_router(user_router)
@@ -54,36 +68,48 @@ api_router.include_router(assessment_router)
54
  api_router.include_router(application_router)
55
  app.include_router(api_router)
56
 
57
- # Serve static build files (assets + config.js + index.html)
58
- app.mount(
59
- "/",
60
- StaticFiles(directory="static", html=False), # no html=True here
61
- name="static",
62
- )
 
 
 
 
 
63
 
64
- # Custom fallback for SPA routes
 
 
65
  @app.get("/{full_path:path}")
66
  async def serve_spa(full_path: str, request: Request):
67
- # If it's an API route, let FastAPI handle a 404 properly
 
 
68
  if request.url.path.startswith("/api"):
69
  return {"detail": "API route not found."}
70
 
71
- # Try to serve the exact file if it exists
72
- file_path = Path("static") / full_path
73
-
74
- if file_path.is_file():
75
- # Let StaticFiles serve it
76
- return FileResponse(file_path)
77
-
78
- # Fallback: serve index.html (SPA)
79
- index_file = Path("static") / "index.html"
80
  if index_file.exists():
81
  return FileResponse(index_file)
82
-
83
  return {"detail": "SPA not found, build your frontend first."}
84
 
85
  logger.info("Application routes registered")
86
 
 
 
 
87
  if __name__ == "__main__":
88
  import uvicorn
89
- uvicorn.run("main:app", host=HOST, port=PORT, log_level="info", workers=1)
 
 
 
 
 
 
 
 
 
1
  import os
2
+ from pathlib import Path
3
+ from fastapi import FastAPI, APIRouter, Request
4
  from fastapi.middleware.cors import CORSMiddleware
5
  from fastapi.staticfiles import StaticFiles
6
  from fastapi.responses import FileResponse
 
7
  import logging
8
 
9
  from database.database import engine
 
15
  from api.application_routes import router as application_router
16
  from config import settings
17
 
18
+ # ----------------------------
19
+ # Logging configuration
20
+ # ----------------------------
21
  logging.basicConfig(level=settings.log_level)
22
  logger = logging.getLogger(__name__)
23
 
24
+ # ----------------------------
25
+ # Environment variables
26
+ # ----------------------------
27
  PORT = int(os.environ.get("PORT", 7860))
28
  HOST = os.environ.get("HOST", "0.0.0.0")
29
+ DEBUG = os.getenv("DEBUG", str(settings.debug)).lower() == "true"
30
 
31
+ # ----------------------------
32
+ # Initialize FastAPI
33
+ # ----------------------------
34
  app = FastAPI(
35
  title=settings.app_name,
36
  description=settings.app_description,
37
  version=settings.app_version
38
  )
39
 
40
+ # ----------------------------
41
+ # Create database tables on startup
42
+ # ----------------------------
43
  @app.on_event("startup")
44
  def startup_event():
45
  Base.metadata.create_all(bind=engine)
46
  logger.info(f"Database tables created/verified at {settings.database_url}")
47
 
48
+ # ----------------------------
49
+ # Configure CORS
50
+ # ----------------------------
51
+ origins = os.getenv("CORS_ORIGINS", "http://localhost:5173,http://localhost:3000").split(",")
52
  app.add_middleware(
53
  CORSMiddleware,
54
  allow_origins=[o.strip() for o in origins if o.strip()],
 
57
  allow_headers=["*"],
58
  )
59
 
60
+ # ----------------------------
61
+ # API routers under /api
62
+ # ----------------------------
63
  api_router = APIRouter(prefix="/api")
64
  api_router.include_router(root_router)
65
  api_router.include_router(user_router)
 
68
  api_router.include_router(application_router)
69
  app.include_router(api_router)
70
 
71
+ # ----------------------------
72
+ # Mount React static files
73
+ # ----------------------------
74
+ react_build_path = Path("static")
75
+ if react_build_path.exists():
76
+ # Serve actual static files (JS/CSS/images)
77
+ app.mount("/static", StaticFiles(directory=react_build_path / "assets"), name="static_assets")
78
+ # Serve index.html at root
79
+ app.mount("/", StaticFiles(directory=react_build_path, html=True), name="react_root")
80
+ else:
81
+ logger.warning("React build not found in /static. Make sure to build frontend.")
82
 
83
+ # ----------------------------
84
+ # SPA fallback for non-API routes
85
+ # ----------------------------
86
  @app.get("/{full_path:path}")
87
  async def serve_spa(full_path: str, request: Request):
88
+ """
89
+ Serve React SPA for any non-API path that doesn't match a real file.
90
+ """
91
  if request.url.path.startswith("/api"):
92
  return {"detail": "API route not found."}
93
 
94
+ index_file = react_build_path / "index.html"
 
 
 
 
 
 
 
 
95
  if index_file.exists():
96
  return FileResponse(index_file)
97
+
98
  return {"detail": "SPA not found, build your frontend first."}
99
 
100
  logger.info("Application routes registered")
101
 
102
+ # ----------------------------
103
+ # Run server (local/dev)
104
+ # ----------------------------
105
  if __name__ == "__main__":
106
  import uvicorn
107
+ logger.info(f"Starting server on {HOST}:{PORT}")
108
+ uvicorn.run(
109
+ "main:app",
110
+ host=HOST,
111
+ port=PORT,
112
+ log_level="info",
113
+ workers=1,
114
+ loop="asyncio",
115
+ )