# main.py import logging from datetime import datetime, timezone from fastapi import Depends, FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.staticfiles import StaticFiles from sqlalchemy import text from sqlalchemy.orm import Session from app.api.main import api_router from app.routes.frontend import router as frontend_router from app.core.config import settings from app.core.database import get_db from app.core.lifespan import lifespan from app.exceptions.handler import setup_exception_handlers from app.exceptions import ServiceUnavailableException from middleware.vendor_context import vendor_context_middleware logger = logging.getLogger(__name__) # FastAPI app with lifespan app = FastAPI( title=settings.project_name, description=settings.description, version=settings.version, lifespan=lifespan, ) # Setup custom exception handlers (unified approach) setup_exception_handlers(app) # Add CORS middleware app.add_middleware( CORSMiddleware, allow_origins=settings.allowed_hosts, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Add vendor context middleware (ADDED - must be after CORS) app.middleware("http")(vendor_context_middleware) # ======================================== # MOUNT STATIC FILES - ADD THIS SECTION # ======================================== app.mount("/static", StaticFiles(directory="static"), name="static") # ======================================== # Include API router app.include_router(api_router, prefix="/api") app.include_router(frontend_router) # Public Routes (no authentication required) @app.get("/", include_in_schema=False) async def root(): """Redirect root to documentation""" return RedirectResponse(url="/documentation") @app.get("/health") def health_check(db: Session = Depends(get_db)): """Health check endpoint""" try: # Test database connection db.execute(text("SELECT 1")) return { "status": "healthy", "timestamp": datetime.now(timezone.utc), "message": f"{settings.project_name} v{settings.version}", "docs": { "swagger": "/docs", "redoc": "/redoc", "openapi": "/openapi.json", "complete": "/documentation", }, "features": [ "Multi-tenant architecture with vendor isolation", "JWT Authentication with role-based access control", "Marketplace product import and curation", "Vendor catalog management", "Product-based inventory tracking", "Stripe Connect payment processing", ], "supported_marketplaces": [ "Letzshop", ], "deployment_modes": [ "Subdomain-based (production): vendor.platform.com", "Path-based (development): /vendor/vendorname/", ], "auth_required": "Most endpoints require Bearer token authentication", } except Exception as e: logger.error(f"Health check failed: {e}") raise ServiceUnavailableException("Service unhealthy") @app.get("/documentation", response_class=HTMLResponse, include_in_schema=False) async def documentation(): """Redirect to documentation""" if settings.debug: return RedirectResponse(url="http://localhost:8001") return RedirectResponse(url=settings.documentation_url) if __name__ == "__main__": import uvicorn uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)