Notiflow / backend /main.py
dipan004's picture
Update backend/main.py
48c328a verified
"""
backend/main.py
---------------
FastAPI application entry point for Notiflow.
Startup:
1. Loads .env file from project root (python-dotenv)
2. Configures logging
3. Mounts the notification API router
4. Exposes health check endpoint
Run:
uvicorn backend.main:app --reload
The server expects to be started from the project root so that
all relative imports (app/, agent/, services/, etc.) resolve correctly.
"""
from __future__ import annotations
import logging
import sys
from pathlib import Path
# ---------------------------------------------------------------------------
# .env loader β€” must happen BEFORE any app.config import
# ---------------------------------------------------------------------------
try:
from dotenv import load_dotenv
_env_path = Path(__file__).parent.parent / ".env"
load_dotenv(dotenv_path=_env_path, override=False)
except ImportError:
pass # python-dotenv not installed; env vars must be set externally
# ---------------------------------------------------------------------------
# Ensure project root is on sys.path when running via uvicorn
# ---------------------------------------------------------------------------
_PROJECT_ROOT = str(Path(__file__).parent.parent)
if _PROJECT_ROOT not in sys.path:
sys.path.insert(0, _PROJECT_ROOT)
# ---------------------------------------------------------------------------
# Logging
# ---------------------------------------------------------------------------
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)-8s %(name)s β€” %(message)s",
datefmt="%H:%M:%S",
)
logger = logging.getLogger(__name__)
# ---------------------------------------------------------------------------
# FastAPI app
# ---------------------------------------------------------------------------
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from api.notification_routes import router as notification_router
app = FastAPI(
title = "Notiflow API",
description = (
"AI operations assistant for small businesses.\n\n"
"Converts informal Hinglish business notifications into "
"structured operations β€” powered by Amazon Nova 2 Lite."
),
version = "1.0.0",
docs_url = "/docs",
redoc_url = "/redoc",
)
# ---------------------------------------------------------------------------
# CORS β€” allow all origins for hackathon demo
# ---------------------------------------------------------------------------
app.add_middleware(
CORSMiddleware,
allow_origins = ["*"],
allow_credentials = True,
allow_methods = ["*"],
allow_headers = ["*"],
)
# ---------------------------------------------------------------------------
# Routers
# ---------------------------------------------------------------------------
app.include_router(notification_router)
# ---------------------------------------------------------------------------
# Health check
# ---------------------------------------------------------------------------
@app.get("/health", tags=["Meta"])
async def health():
"""
Basic health check.
Returns service status and configuration summary.
"""
from app.config import DEMO_MODE, BEDROCK_MODEL_ID, GEMINI_API_KEY, EXCEL_SYNC_FILE
return {
"status": "ok",
"demo_mode": DEMO_MODE,
"bedrock_model": BEDROCK_MODEL_ID,
"gemini_enabled": bool(GEMINI_API_KEY),
"excel_file": str(EXCEL_SYNC_FILE),
}
# ---------------------------------------------------------------------------
# Frontend static files or root redirect
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
# Frontend static files or root redirect
# ---------------------------------------------------------------------------
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
_frontend_dist = Path(_PROJECT_ROOT) / "dashboard" / "dist"
if _frontend_dist.is_dir():
# Serve Vite assets
app.mount(
"/assets",
StaticFiles(directory=str(_frontend_dist / "assets")),
name="assets"
)
# Serve frontend index
@app.get("/", include_in_schema=False)
async def root():
return FileResponse(_frontend_dist / "index.html")
else:
@app.get("/", include_in_schema=False)
async def root():
from fastapi.responses import RedirectResponse
return RedirectResponse(url="/docs")
# ---------------------------------------------------------------------------
# Startup / shutdown events
# ---------------------------------------------------------------------------
@app.on_event("startup")
async def on_startup():
from app.config import DEMO_MODE, GEMINI_API_KEY, EXCEL_SYNC_FILE
logger.info("=" * 55)
logger.info(" Notiflow API starting up")
logger.info(" Demo mode : %s", DEMO_MODE)
logger.info(" Gemini : %s", "enabled" if GEMINI_API_KEY else "disabled (no API key)")
logger.info(" Excel file : %s", EXCEL_SYNC_FILE)
logger.info("=" * 55)
@app.on_event("shutdown")
async def on_shutdown():
logger.info("Notiflow API shutting down.")