Initial commit: mini-erp (backend FastAPI + frontend React/Vite)
Base para el flujo de ramas por cliente. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
commit
ab3c613165
154 files changed
+16872
No files matched your search
@@ -0,0 +1,130 @@
|
||||
from dotenv import load_dotenv
|
||||
import logging
|
||||
import requests
|
||||
from requests import Session
|
||||
from typing import Optional, Dict, Any
|
||||
import os
|
||||
from fastapi import HTTPException
|
||||
import urllib3
|
||||
|
||||
load_dotenv(dotenv_path=".env")
|
||||
|
||||
APIGATEWAY_URL = os.getenv("APIGATEWAY_URL", "")
|
||||
APIGATEWAY_USER = os.getenv("APIGATEWAY_USER", "")
|
||||
APIGATEWAY_PASSWORD = os.getenv("APIGATEWAY_PASSWORD", "")
|
||||
APIGATEWAY_COMPANYDB = os.getenv("APIGATEWAY_COMPANYDB", "")
|
||||
APIGATEWAY_DBINSTANCE = os.getenv("APIGATEWAY_DBINSTANCE", "")
|
||||
APIGATEWAY_TIMEOUT = float(os.getenv("APIGATEWAY_TIMEOUT", 30.0))
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
api_gateway_session: Optional[Session] = None
|
||||
|
||||
|
||||
def ensure_api_gateway_session(force_refresh: bool = False) -> Session:
|
||||
global api_gateway_session
|
||||
|
||||
if api_gateway_session and not force_refresh:
|
||||
return api_gateway_session
|
||||
|
||||
logger.info("Iniciando sesión en APIGateway...")
|
||||
login_url = f"{APIGATEWAY_URL}/login"
|
||||
payload = {
|
||||
"CompanyDB": APIGATEWAY_COMPANYDB,
|
||||
"UserName": APIGATEWAY_USER,
|
||||
"Password": APIGATEWAY_PASSWORD,
|
||||
"DBInstance": APIGATEWAY_DBINSTANCE,
|
||||
}
|
||||
|
||||
try:
|
||||
session = Session()
|
||||
session.verify = False
|
||||
|
||||
response = session.post(
|
||||
login_url,
|
||||
json=payload,
|
||||
timeout=APIGATEWAY_TIMEOUT,
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
logger.error(f"Error login APIGateway. Status: {response.status_code}")
|
||||
raise HTTPException(
|
||||
status_code=response.status_code,
|
||||
detail="Error de autenticación con APIGateway"
|
||||
)
|
||||
|
||||
api_gateway_session = session
|
||||
logger.info(f"Sesión APIGateway establecida. Cookies: {dict(session.cookies)}")
|
||||
return session
|
||||
|
||||
except requests.RequestException as exc:
|
||||
logger.error(f"Error de conexión con APIGateway: {exc}")
|
||||
api_gateway_session = None
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"No se pudo conectar con APIGateway: {exc}"
|
||||
)
|
||||
|
||||
|
||||
def forward_to_api_gateway(
|
||||
method: str,
|
||||
endpoint: str,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
json_data: Optional[Any] = None,
|
||||
) -> requests.Response:
|
||||
if not method or not endpoint:
|
||||
raise ValueError("method y endpoint son requeridos")
|
||||
|
||||
method = method.upper()
|
||||
session = ensure_api_gateway_session()
|
||||
|
||||
url_destino = f"{APIGATEWAY_URL}/{endpoint}"
|
||||
|
||||
log_extra = {"http_method": method, "endpoint": endpoint}
|
||||
logger.info(f"[APIGateway] [{method}] {endpoint}", extra=log_extra)
|
||||
|
||||
try:
|
||||
response = session.request(
|
||||
method=method,
|
||||
url=url_destino,
|
||||
params=params,
|
||||
json=json_data,
|
||||
timeout=APIGATEWAY_TIMEOUT,
|
||||
)
|
||||
except requests.exceptions.Timeout:
|
||||
logger.error(f"Timeout ({APIGATEWAY_TIMEOUT}s) en APIGateway {endpoint}", extra=log_extra)
|
||||
raise ConnectionError(f"Timeout al conectar con APIGateway: {endpoint}")
|
||||
except requests.RequestException as exc:
|
||||
logger.error(f"Error en solicitud APIGateway: {exc}", extra=log_extra)
|
||||
raise ConnectionError(f"Error en solicitud APIGateway: {exc}")
|
||||
|
||||
if response.status_code == 401:
|
||||
logger.warning("Sesión APIGateway expirada (401). Reautenticando...", extra=log_extra)
|
||||
session = ensure_api_gateway_session(force_refresh=True)
|
||||
try:
|
||||
response = session.request(
|
||||
method=method,
|
||||
url=url_destino,
|
||||
params=params,
|
||||
json=json_data,
|
||||
timeout=APIGATEWAY_TIMEOUT,
|
||||
)
|
||||
except requests.RequestException as exc:
|
||||
raise ConnectionError(f"Error en reintento APIGateway: {exc}")
|
||||
|
||||
if response.status_code >= 400:
|
||||
error_msg = response.text[:500]
|
||||
logger.error(
|
||||
f"[{response.status_code}] APIGateway {endpoint}: {error_msg}",
|
||||
extra={**log_extra, "status_code": response.status_code}
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=response.status_code,
|
||||
detail=f"Error en APIGateway: {error_msg}"
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"[{response.status_code}] APIGateway {endpoint}",
|
||||
extra={**log_extra, "status_code": response.status_code}
|
||||
)
|
||||
return response
|
||||
Reference in new issue
Block a user