Download app/sql/executor.py from nvikou/corrective-rag-data-assistant: direct link, hf CLI and curl.
- Browser
- Download file 1.98 kB
-
https://huggingface.co/spaces/nvikou/corrective-rag-data-assistant/resolve/main/app/sql/executor.py
- Command line
-
hf download hf://spaces/nvikou/corrective-rag-data-assistant/app/sql/executor.py
-
curl -L -o executor.py https://huggingface.co/spaces/nvikou/corrective-rag-data-assistant/resolve/main/app/sql/executor.py
1.98 kB
| """Exécuteur SQL lecture seule sur SQLite (company.db).""" | |
| from __future__ import annotations | |
| import logging | |
| import sqlite3 | |
| import time | |
| from pathlib import Path | |
| from app.core.config import get_settings | |
| from app.sql.seed import ensure_company_db | |
| from app.sql.sql_validator import MAX_ROWS, is_safe_sql | |
| logger = logging.getLogger(__name__) | |
| def get_db_path() -> Path: | |
| settings = get_settings() | |
| return Path(settings.sqlite_db_path) | |
| def _connect() -> sqlite3.Connection: | |
| db_path = ensure_company_db(get_db_path()) | |
| conn = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True, timeout=5.0) | |
| conn.row_factory = sqlite3.Row | |
| return conn | |
| def execute_readonly(query: str, params: tuple | list | None = None) -> dict: | |
| """Exécute un SELECT validé, avec limite de lignes et journal d'audit.""" | |
| params = tuple(params or ()) | |
| started = time.perf_counter() | |
| if not is_safe_sql(query): | |
| return { | |
| "error": "Requête SQL refusée par le validateur.", | |
| "query": query, | |
| "duration_ms": 0, | |
| } | |
| limited = query.strip().rstrip(";") | |
| if "LIMIT" not in limited.upper(): | |
| limited = f"{limited} LIMIT {MAX_ROWS}" | |
| try: | |
| with _connect() as conn: | |
| cur = conn.execute(limited, params) | |
| rows = [dict(r) for r in cur.fetchall()] | |
| except sqlite3.Error as exc: | |
| logger.warning("Échec SQL: %s", exc) | |
| return { | |
| "error": str(exc), | |
| "query": limited, | |
| "params": list(params), | |
| "duration_ms": int((time.perf_counter() - started) * 1000), | |
| } | |
| duration_ms = int((time.perf_counter() - started) * 1000) | |
| logger.info( | |
| "SQL audit query=%r params=%s rows=%d duration_ms=%d", | |
| limited, params, len(rows), duration_ms, | |
| ) | |
| return { | |
| "query": limited, | |
| "params": list(params), | |
| "rows": rows, | |
| "row_count": len(rows), | |
| "duration_ms": duration_ms, | |
| } | |