bmc_hub/main.py
Christian 23f8a3d2ae Fix watchfiles spam and port conflicts
- Disabled auto-reload by default (ENABLE_RELOAD=false)
- Changed default ports: PostgreSQL 5433, API 8001
- Updated psycopg2-binary to 2.9.10 (Python 3.13 compat)
- Updated Pydantic to 2.10.3 (Python 3.13 compat)
- Added reload_excludes to prevent .git watching
- Updated .env.example with new defaults
2025-12-05 14:42:18 +01:00

124 lines
3.0 KiB
Python

"""
BMC Hub - FastAPI Application
Main application entry point
"""
import logging
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import RedirectResponse
from contextlib import asynccontextmanager
from app.core.config import settings
from app.core.database import init_db
from app.routers import (
customers,
hardware,
billing,
system,
)
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler('logs/app.log')
]
)
logger = logging.getLogger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Lifecycle management - startup and shutdown"""
# Startup
logger.info("🚀 Starting BMC Hub...")
logger.info(f"Database: {settings.DATABASE_URL}")
init_db()
logger.info("✅ System initialized successfully")
yield
# Shutdown
logger.info("👋 Shutting down...")
# Create FastAPI app
app = FastAPI(
title="BMC Hub API",
description="""
Central management system for BMC Networks.
**Key Features:**
- Customer management
- Hardware tracking
- Service management
- Billing integration
""",
version="1.0.0",
lifespan=lifespan,
docs_url="/api/docs",
redoc_url="/api/redoc",
openapi_url="/api/openapi.json"
)
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=settings.ALLOWED_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Include routers
app.include_router(customers.router, prefix="/api/v1", tags=["Customers"])
app.include_router(hardware.router, prefix="/api/v1", tags=["Hardware"])
app.include_router(billing.router, prefix="/api/v1", tags=["Billing"])
app.include_router(system.router, prefix="/api/v1", tags=["System"])
# Serve static files (UI)
app.mount("/static", StaticFiles(directory="static", html=True), name="static")
@app.get("/")
async def root():
"""Redirect to dashboard"""
return RedirectResponse(url="/static/index.html")
@app.get("/health")
async def health_check():
"""Health check endpoint"""
return {
"status": "healthy",
"service": "BMC Hub",
"version": "1.0.0"
}
if __name__ == "__main__":
import uvicorn
import os
# Only enable reload in local development (not in Docker)
enable_reload = os.getenv("ENABLE_RELOAD", "false").lower() == "true"
if enable_reload:
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8000,
reload=True,
reload_includes=["*.py"],
reload_dirs=["app"],
reload_excludes=[".git/*", "*.pyc", "__pycache__/*", "logs/*", "uploads/*", "data/*"],
log_level="info"
)
else:
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8000,
reload=False
)