Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/nene2/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ class AppSettings(BaseSettings):
cors_origins: list[str] = []
cors_allow_credentials: bool = False
cors_allow_methods: list[str] = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
cors_allow_headers: list[str] = ["*"]
cors_allow_headers: list[str] = [
"Content-Type",
"Authorization",
"X-Api-Key",
"X-Request-Id",
]

bearer_token_enabled: bool = False
bearer_tokens: list[str] = []
Expand Down
9 changes: 7 additions & 2 deletions src/nene2/database/health.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
"""Database health check — verifies DB connectivity for /health endpoint."""

import logging

from nene2.http import HealthStatus

from .interfaces import DatabaseQueryExecutorInterface

logger = logging.getLogger(__name__)


class DatabaseHealthCheck:
"""Check database connectivity by executing a lightweight query."""
Expand All @@ -15,5 +19,6 @@ def check(self) -> HealthStatus:
try:
self._executor.fetch_one("SELECT 1 AS ok")
return HealthStatus(status="ok", checks={"database": "ok"})
except Exception:
return HealthStatus(status="degraded", checks={"database": "error"})
except Exception as exc:
logger.warning("database health check failed: %s", exc)
return HealthStatus(status="error", checks={"database": "error"})
23 changes: 16 additions & 7 deletions src/nene2/database/sqlalchemy_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,26 @@ def __init__(self, conn: Connection) -> None:
self._conn = conn

def fetch_all(self, sql: str, params: dict[str, Any] | None = None) -> list[dict[str, Any]]:
result = self._conn.execute(text(sql), params or {})
return [dict(row._mapping) for row in result]
try:
result = self._conn.execute(text(sql), params or {})
return [dict(row._mapping) for row in result]
except OperationalError as exc:
raise DatabaseConnectionException(str(exc)) from exc

def fetch_one(self, sql: str, params: dict[str, Any] | None = None) -> dict[str, Any] | None:
result = self._conn.execute(text(sql), params or {})
row = result.fetchone()
return dict(row._mapping) if row else None
try:
result = self._conn.execute(text(sql), params or {})
row = result.fetchone()
return dict(row._mapping) if row else None
except OperationalError as exc:
raise DatabaseConnectionException(str(exc)) from exc

def write(self, sql: str, params: dict[str, Any] | None = None) -> int:
result = self._conn.execute(text(sql), params or {})
return result.lastrowid or result.rowcount
try:
result = self._conn.execute(text(sql), params or {})
return result.lastrowid or result.rowcount
except OperationalError as exc:
raise DatabaseConnectionException(str(exc)) from exc


class SqlAlchemyTransactionManager(DatabaseTransactionManagerInterface):
Expand Down
Loading