basyx commited on
Commit
e58c6b6
·
verified ·
1 Parent(s): e0d43c4

Update auth/database.py

Browse files
Files changed (1) hide show
  1. auth/database.py +72 -84
auth/database.py CHANGED
@@ -1,137 +1,125 @@
1
- """
2
- database.py
3
- Enterprise Database Layer
4
- Basyx Whisper V10.1
5
- """
6
-
7
  import os
8
- from typing import Generator
9
-
10
- from sqlalchemy import create_engine
11
  from sqlalchemy.orm import sessionmaker, declarative_base, Session
 
12
  from sqlalchemy.pool import QueuePool
 
13
 
14
- from utils.logger import logger
15
-
 
16
 
17
- # ==========================================================
18
- # REQUIRED ENVIRONMENT CONFIG
19
- # ==========================================================
20
-
21
- DATABASE_URL = os.environ.get("DATABASE_URL")
22
 
23
  if not DATABASE_URL:
24
- raise RuntimeError("DATABASE_URL environment variable is required")
25
-
 
 
26
 
27
- # ==========================================================
28
- # ENGINE CONFIGURATION
29
- # ==========================================================
30
-
31
- """
32
- Enterprise defaults:
33
-
34
- ✔ connection pooling
35
- ✔ stale connection recovery
36
- ✔ multi-worker safe
37
- ✔ production ready
38
- """
39
 
40
  engine = create_engine(
41
  DATABASE_URL,
42
  poolclass=QueuePool,
 
 
43
  pool_size=10,
44
- max_overflow=20,
45
- pool_pre_ping=True,
46
  pool_recycle=1800,
47
- future=True,
 
 
 
 
 
 
 
48
  echo=False,
 
49
  )
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
- # ==========================================================
53
  # SESSION FACTORY
54
- # ==========================================================
55
 
56
  SessionLocal = sessionmaker(
57
- autocommit=False,
58
- autoflush=False,
59
  bind=engine,
 
 
60
  expire_on_commit=False,
61
  class_=Session,
 
62
  )
63
 
64
-
65
- # ==========================================================
66
- # BASE MODEL CLASS
67
- # ==========================================================
68
 
69
  Base = declarative_base()
70
 
 
 
 
71
 
72
- # ==========================================================
73
- # FASTAPI DEPENDENCY
74
- # ==========================================================
75
-
76
- def get_db() -> Generator[Session, None, None]:
77
  """
78
- FastAPI dependency injection:
79
-
80
- Example:
81
- db: Session = Depends(get_db)
82
  """
83
-
84
  db = SessionLocal()
85
-
86
  try:
87
  yield db
88
- except Exception:
89
- logger.exception("Database session failure")
90
  db.rollback()
91
  raise
92
  finally:
93
  db.close()
94
 
95
 
96
- # ==========================================================
97
- # DATABASE INITIALIZATION
98
- # ==========================================================
99
 
100
- def init_db() -> None:
101
  """
102
- Create tables safely.
103
-
104
- Import models BEFORE create_all
105
- to register metadata.
106
  """
107
-
108
- try:
109
- import auth.models # noqa
110
- import models # optional global models
111
-
112
- Base.metadata.create_all(bind=engine)
113
-
114
- logger.info("Database initialized successfully")
115
-
116
- except Exception:
117
- logger.exception("Database initialization failed")
118
- raise
119
 
120
 
121
- # ==========================================================
122
  # HEALTH CHECK
123
- # ==========================================================
124
 
125
- def db_healthcheck() -> dict:
126
  """
127
- Used by /api/health
 
128
  """
129
-
130
  try:
131
  with engine.connect() as conn:
132
- conn.execute("SELECT 1")
133
- return {"database": "connected"}
134
-
135
  except Exception as e:
136
- logger.exception("Database healthcheck failed")
137
- return {"database": "error", "detail": str(e)}
 
 
 
 
 
 
 
1
  import os
2
+ from sqlalchemy import create_engine, event
 
 
3
  from sqlalchemy.orm import sessionmaker, declarative_base, Session
4
+ from sqlalchemy.engine import Engine
5
  from sqlalchemy.pool import QueuePool
6
+ import logging
7
 
8
+ # ==============================
9
+ # CONFIGURATION (STRICT)
10
+ # ==============================
11
 
12
+ DATABASE_URL = os.getenv("DATABASE_URL")
 
 
 
 
13
 
14
  if not DATABASE_URL:
15
+ raise RuntimeError(
16
+ "DATABASE_URL is not set. "
17
+ "Provide a valid PostgreSQL connection string (Supabase or other)."
18
+ )
19
 
20
+ # ==============================
21
+ # ENGINE CONFIG (PRODUCTION TUNED)
22
+ # ==============================
 
 
 
 
 
 
 
 
 
23
 
24
  engine = create_engine(
25
  DATABASE_URL,
26
  poolclass=QueuePool,
27
+
28
+ # Connection pool tuning for video + AI workloads
29
  pool_size=10,
30
+ max_overflow=25,
31
+ pool_timeout=30,
32
  pool_recycle=1800,
33
+ pool_pre_ping=True,
34
+
35
+ # Required for Supabase/Postgres stability
36
+ connect_args={
37
+ "connect_timeout": 10,
38
+ "application_name": "basyx-whisper-v10",
39
+ },
40
+
41
  echo=False,
42
+ future=True,
43
  )
44
 
45
+ # ==============================
46
+ # SAFETY: PREVENT STALE CONNECTION FAILURES
47
+ # ==============================
48
+
49
+ @event.listens_for(Engine, "engine_connect")
50
+ def validate_connection(connection, branch):
51
+ if branch:
52
+ return
53
+ try:
54
+ connection.scalar("SELECT 1")
55
+ except Exception:
56
+ raise RuntimeError("Database connection validation failed")
57
+
58
 
59
+ # ==============================
60
  # SESSION FACTORY
61
+ # ==============================
62
 
63
  SessionLocal = sessionmaker(
 
 
64
  bind=engine,
65
+ autoflush=False,
66
+ autocommit=False,
67
  expire_on_commit=False,
68
  class_=Session,
69
+ future=True,
70
  )
71
 
72
+ # ==============================
73
+ # BASE MODEL
74
+ # ==============================
 
75
 
76
  Base = declarative_base()
77
 
78
+ # ==============================
79
+ # DEPENDENCY (FASTAPI SAFE)
80
+ # ==============================
81
 
82
+ def get_db():
 
 
 
 
83
  """
84
+ FastAPI dependency:
85
+ Ensures safe transactional session lifecycle per request.
 
 
86
  """
 
87
  db = SessionLocal()
 
88
  try:
89
  yield db
90
+ db.commit()
91
+ except Exception as e:
92
  db.rollback()
93
  raise
94
  finally:
95
  db.close()
96
 
97
 
98
+ # ==============================
99
+ # MANUAL SESSION (WORKER SAFE)
100
+ # ==============================
101
 
102
+ def get_db_session() -> Session:
103
  """
104
+ For background workers, queues, and async threads.
105
+ Must be manually closed.
 
 
106
  """
107
+ return SessionLocal()
 
 
 
 
 
 
 
 
 
 
 
108
 
109
 
110
+ # ==============================
111
  # HEALTH CHECK
112
+ # ==============================
113
 
114
+ def check_db_connection() -> bool:
115
  """
116
+ Lightweight DB connectivity check.
117
+ Safe for startup validation and health endpoints.
118
  """
 
119
  try:
120
  with engine.connect() as conn:
121
+ conn.exec_driver_sql("SELECT 1")
122
+ return True
 
123
  except Exception as e:
124
+ logging.error(f"DB health check failed: {e}")
125
+ return False