Files
baby-monitor/src/baby_monitor/main.py
T

156 lines
4.9 KiB
Python

"""Baby Monitor Main Application"""
import os
from pathlib import Path
from typing import Annotated
from contextlib import asynccontextmanager
from collections.abc import AsyncIterator
from fastapi import FastAPI, Depends
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from baby_monitor.routers.auth import router as auth_router
from baby_monitor.routers.auth import verify_token
from baby_monitor.routers.admin import router as admin_router
from baby_monitor.routers.child import router as child_router
from baby_monitor.routers.feeding import router as feeding_router
from baby_monitor.routers.diaper_change import router as diaper_change_router
from baby_monitor.routers.sleep import router as sleep_router
from baby_monitor.routers.health import router as health_router
from baby_monitor.repositories.dependencies.get_database import init_db
# Disable docs in production
ENVIRONMENT = os.getenv("ENVIRONMENT", "production")
docs_url = "/docs" if ENVIRONMENT == "development" else None
redoc_url = "/redoc" if ENVIRONMENT == "development" else None
openapi_url = "/openapi.json" if ENVIRONMENT == "development" else None
@asynccontextmanager
async def lifespan(app_instance: FastAPI) -> AsyncIterator[None]:
"""Lifespan event handler for startup and shutdown."""
# Startup: Initialize database tables
init_db()
yield
# Shutdown: Add cleanup code here if needed
# Instantiate app
app = FastAPI(
docs_url=docs_url,
redoc_url=redoc_url,
openapi_url=openapi_url,
lifespan=lifespan,
)
# Mount static files
static_path = Path(__file__).parent / "static"
app.mount("/static", StaticFiles(directory=str(static_path)), name="static")
# Include routers
app.include_router(auth_router)
app.include_router(admin_router)
app.include_router(child_router)
app.include_router(feeding_router)
app.include_router(diaper_change_router)
app.include_router(sleep_router)
app.include_router(health_router)
# Serve HTML pages at root level
@app.get("/", include_in_schema=False)
def serve_home() -> FileResponse:
"""Serve the home page (handles auth check client-side)."""
return FileResponse(static_path / "index.html")
@app.get("/login.html", include_in_schema=False)
def serve_login() -> FileResponse:
"""Serve the login page."""
return FileResponse(static_path / "login.html")
@app.get("/register.html", include_in_schema=False)
def serve_register() -> FileResponse:
"""Serve the registration page."""
return FileResponse(static_path / "register.html")
@app.get("/admin.html", include_in_schema=False)
def serve_admin() -> FileResponse:
"""Serve the admin page."""
return FileResponse(static_path / "admin.html")
@app.get("/add-child.html", include_in_schema=False)
def serve_add_child() -> FileResponse:
"""Serve the add child page."""
return FileResponse(static_path / "add-child.html")
@app.get("/log-feeding.html", include_in_schema=False)
def serve_log_feeding() -> FileResponse:
"""Serve the log feeding page."""
return FileResponse(static_path / "log-feeding.html")
@app.get("/feedings.html", include_in_schema=False)
def serve_feedings() -> FileResponse:
"""Serve the feedings overview page."""
return FileResponse(static_path / "feedings.html")
@app.get("/diapers.html", include_in_schema=False)
def serve_diapers() -> FileResponse:
"""Serve the diaper changes overview page."""
return FileResponse(static_path / "diapers.html")
@app.get("/log-diaper.html", include_in_schema=False)
def serve_log_diaper() -> FileResponse:
"""Serve the log diaper change page."""
return FileResponse(static_path / "log-diaper.html")
@app.get("/sleep.html", include_in_schema=False)
def serve_sleep() -> FileResponse:
"""Serve the sleep overview page."""
return FileResponse(static_path / "sleep.html")
@app.get("/log-sleep.html", include_in_schema=False)
def serve_log_sleep() -> FileResponse:
"""Serve the log sleep page."""
return FileResponse(static_path / "log-sleep.html")
@app.get("/settings.html", include_in_schema=False)
def serve_settings() -> FileResponse:
"""Serve the settings page."""
return FileResponse(static_path / "settings.html")
@app.get("/menu.css", include_in_schema=False)
def serve_menu_css() -> FileResponse:
"""Serve the shared menu CSS."""
return FileResponse(static_path / "menu.css")
@app.get("/menu.js", include_in_schema=False)
def serve_menu_js() -> FileResponse:
"""Serve the shared menu JavaScript."""
return FileResponse(static_path / "menu.js")
@app.get("/auth-utils.js", include_in_schema=False)
def serve_auth_utils_js() -> FileResponse:
"""Serve the shared auth utilities JavaScript."""
return FileResponse(static_path / "auth-utils.js")
@app.get("/api/")
def read_root(token: Annotated[str, Depends(verify_token)]) -> dict:
"""API root endpoint (requires authentication)."""
return {"message": "Hello World", "authenticated": True}