Files
mini-erp/mini-backend/main.py
T

114 lines
4.1 KiB
Python
Raw Normal View History

import os
import uuid
import uvicorn
import urllib3
import logging
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from contextlib import asynccontextmanager
from dotenv import load_dotenv
from logger_config import setup_logging
from context import set_request_id, get_request_id, set_current_user
from core.session import validate_and_refresh_session, get_employee_name, get_emp_id
from routers.auth import router as auth_router
from routers.business_partners import router as bp_router
from routers.items import router as items_router
from routers.sales import router as sales_router
from routers.purchases import router as purchases_router
from routers.catalogs import router as catalogs_router
from routers.batch import router as batch_router
from routers.permissions import router as permissions_router
from routers.apigateway import router as apigateway_router
from routers.reports import router as reports_router
from routers.series import router as series_router
from routers.user_tables import router as user_tables_router
from routers.inventory_transfer_requests import router as inventory_transfer_requests_router
# ============================================================================
load_dotenv(dotenv_path=".env")
logger = logging.getLogger(__name__)
LOG_ENVIRONMENT = os.getenv("LOG_ENVIRONMENT", "production")
# ============================================================================
@asynccontextmanager
async def lifespan(app: FastAPI):
setup_logging(environment=LOG_ENVIRONMENT)
yield
app = FastAPI(
title="SAP Business One Integration API",
description="API para integrar Socios de negocios con SAP Business One Service Layer.",
version="1.1.0",
lifespan=lifespan
)
app.include_router(auth_router)
app.include_router(bp_router)
app.include_router(items_router)
app.include_router(sales_router)
app.include_router(purchases_router)
app.include_router(catalogs_router)
app.include_router(batch_router)
app.include_router(permissions_router)
app.include_router(apigateway_router)
app.include_router(reports_router)
app.include_router(series_router)
app.include_router(user_tables_router)
app.include_router(inventory_transfer_requests_router)
# ============================================================================
@app.middleware("http")
async def correlation_id_middleware(request: Request, call_next):
req_id = request.headers.get("X-Request-ID", str(uuid.uuid4()))
set_request_id(req_id)
response = await call_next(request)
response.headers["X-Request-ID"] = get_request_id()
return response
# ============================================================================
@app.middleware("http")
async def session_middleware(request: Request, call_next):
if request.url.path == "/api/Login":
return await call_next(request)
if request.url.path.startswith("/api/"):
token = request.headers.get("X-Session-Token")
if not token:
logger.warning(f"Request sin token: {request.method} {request.url.path}")
return JSONResponse(
status_code=401,
content={"detail": "Se requiere autenticación. Inicie sesión primero."}
)
webUser = validate_and_refresh_session(token)
if not webUser:
logger.warning(f"Token inválido o expirado en: {request.method} {request.url.path}")
return JSONResponse(
status_code=401,
content={"detail": "Sesión expirada. Debe iniciar sesión nuevamente."}
)
set_current_user(webUser, get_employee_name(webUser), get_emp_id(webUser))
request.state.webUser = webUser
return await call_next(request)
# ============================================================================
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
urllib3.disable_warnings()
# ============================================================================
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, log_level="debug", access_log=True)