"""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("/api/") def read_root(token: Annotated[str, Depends(verify_token)]) -> dict: """API root endpoint (requires authentication).""" return {"message": "Hello World", "authenticated": True}