# ============================================================ # config.py — Configuration & connexion SQL Server # Data Sentinel | COYAUD Anthony | 2026 # ============================================================ import os import pyodbc from contextlib import contextmanager def _build_connection_string() -> str: """ Construit la chaîne de connexion ODBC à partir des variables d'environnement. Deux modes d'authentification : • authentification SQL (déploiement) — dès que DB_USER est défini ; • authentification Windows (poste de dev) — sinon, ou en forçant DB_TRUSTED_CONNECTION=yes. Le serveur par défaut reste modifiable par DB_SERVER : coder en dur le nom d'un poste rendait l'API inutilisable sur toute autre machine. """ server = os.getenv("DB_SERVER", "localhost") port = os.getenv("DB_PORT", "") base = os.getenv("DB_NAME", "DataSentinel") driver = os.getenv("DB_DRIVER", "ODBC Driver 18 for SQL Server") user = os.getenv("DB_USER") # Une instance nommée (MonPoste\SQLEXPRESS) se joint sans port explicite. adresse = f"{server},{port}" if port else server trusted = os.getenv("DB_TRUSTED_CONNECTION", "").lower() in ("1", "yes", "true") if user and not trusted: identification = f"UID={user};PWD={os.getenv('DB_PASSWORD', '')};" else: identification = "Trusted_Connection=yes;" return ( f"Driver={{{driver}}};" f"Server={adresse};" f"Database={base};" f"{identification}" "Encrypt=yes;TrustServerCertificate=yes;" ) class Config: # Chaîne de connexion SQL Server (env en prod, Windows en local) DB_CONNECTION_STRING = _build_connection_string() # Paramètres API API_TITLE = "Data Sentinel API" API_VERSION = "1.0.0" API_DESCRIPTION = "API de monitoring de la qualité des données — XEFI" # Sécurité JWT SECRET_KEY = os.getenv("JWT_SECRET", "data-sentinel-secret-change-in-prod") ALGORITHM = os.getenv("JWT_ALGORITHM", "HS256") TOKEN_EXPIRE_MINUTES = int(os.getenv("JWT_EXPIRE_MINUTES", "60")) # ---------------------------------------------------------------- # Connexion — retourne un curseur pyodbc via context manager # ---------------------------------------------------------------- def get_connection() -> pyodbc.Connection: """Ouvre une connexion SQL Server et la retourne.""" return pyodbc.connect(Config.DB_CONNECTION_STRING) @contextmanager def get_cursor(): """ Context manager : ouvre connexion + curseur, commit ou rollback, ferme proprement. Usage : with get_cursor() as cursor: cursor.execute("SELECT ...") rows = cursor.fetchall() """ conn = get_connection() cursor = conn.cursor() try: yield cursor conn.commit() except Exception: conn.rollback() raise finally: cursor.close() conn.close()