app.main

Main Application Module.

This module initializes the FastAPI application, sets up standard API routes like health checks, and configures fallback routing to serve the Svelte SPA from static files.

 1"""
 2Main Application Module.
 3
 4This module initializes the FastAPI application, sets up standard API routes
 5like health checks, and configures fallback routing to serve the Svelte SPA
 6from static files.
 7"""
 8
 9import os
10from contextlib import asynccontextmanager
11
12from fastapi import FastAPI
13from sqlmodel import SQLModel
14from starlette.responses import FileResponse
15
16import app.models  # noqa: F401 - ensures all models are registered with SQLModel metadata
17from app.database import engine
18from app.routes.auth import router as auth_router
19from app.routes.rooms import router as rooms_router
20from app.routes.bookings import router as bookings_router
21from app.routes.notifications import router as notifications_router
22from app.seed import seed_rooms_and_slots
23from app.services.user_manager import register_superuser
24
25
26@asynccontextmanager
27async def lifespan(app: FastAPI):
28    async with engine.begin() as conn:
29        await conn.run_sync(SQLModel.metadata.create_all)
30    await register_superuser()
31    await seed_rooms_and_slots()
32    yield
33
34
35app = FastAPI(lifespan=lifespan)
36
37app.include_router(auth_router)
38app.include_router(rooms_router)
39app.include_router(bookings_router)
40app.include_router(notifications_router)
41
42
43@app.get("/api/health")
44async def health_check():
45    """
46    Checks the health status of the API.
47
48    Returns:
49        dict: A dictionary indicating the API status and a confirmation message.
50    """
51    return {"status": "ok", "message": "FastAPI is running"}
52
53
54# 2. Catch-all for Svelte SPA and static files
55static_dir = os.path.join(os.path.dirname(__file__), "static")
56
57
58@app.get("/{catchall:path}")
59async def serve_spa(catchall: str):
60    """
61    Catch-all route handler for serving static files and the Svelte SPA.
62
63    This function prevents directory traversal attacks and routes unmatched
64    requests either to specific static files or to the `index.html` fallback
65    for client-side routing.
66
67    Args:
68        catchall (str): The requested URL path.
69
70    Returns:
71        FileResponse: The requested static file or `index.html`.
72    """
73    # Prevent directory traversal attacks
74    safe_path = os.path.normpath(os.path.join(static_dir, catchall))
75    if not safe_path.startswith(static_dir):
76        return FileResponse(os.path.join(static_dir, "index.html"))
77
78    if os.path.isfile(safe_path):
79        return FileResponse(safe_path)
80
81    # Fallback to Svelte's router
82    return FileResponse(os.path.join(static_dir, "index.html"))
@asynccontextmanager
async def lifespan(app: fastapi.applications.FastAPI):
27@asynccontextmanager
28async def lifespan(app: FastAPI):
29    async with engine.begin() as conn:
30        await conn.run_sync(SQLModel.metadata.create_all)
31    await register_superuser()
32    await seed_rooms_and_slots()
33    yield
app = <fastapi.applications.FastAPI object>
@app.get('/api/health')
async def health_check():
44@app.get("/api/health")
45async def health_check():
46    """
47    Checks the health status of the API.
48
49    Returns:
50        dict: A dictionary indicating the API status and a confirmation message.
51    """
52    return {"status": "ok", "message": "FastAPI is running"}

Checks the health status of the API.

Returns: dict: A dictionary indicating the API status and a confirmation message.

static_dir = '/home/runner/work/CSE362/CSE362/backend/app/static'
@app.get('/{catchall:path}')
async def serve_spa(catchall: str):
59@app.get("/{catchall:path}")
60async def serve_spa(catchall: str):
61    """
62    Catch-all route handler for serving static files and the Svelte SPA.
63
64    This function prevents directory traversal attacks and routes unmatched
65    requests either to specific static files or to the `index.html` fallback
66    for client-side routing.
67
68    Args:
69        catchall (str): The requested URL path.
70
71    Returns:
72        FileResponse: The requested static file or `index.html`.
73    """
74    # Prevent directory traversal attacks
75    safe_path = os.path.normpath(os.path.join(static_dir, catchall))
76    if not safe_path.startswith(static_dir):
77        return FileResponse(os.path.join(static_dir, "index.html"))
78
79    if os.path.isfile(safe_path):
80        return FileResponse(safe_path)
81
82    # Fallback to Svelte's router
83    return FileResponse(os.path.join(static_dir, "index.html"))

Catch-all route handler for serving static files and the Svelte SPA.

This function prevents directory traversal attacks and routes unmatched requests either to specific static files or to the index.html fallback for client-side routing.

Args: catchall (str): The requested URL path.

Returns: FileResponse: The requested static file or index.html.