Spaces:
Sleeping
Sleeping
Commit ·
69c71e7
1
Parent(s): bf9c8c1
Fix: Parse DATABASE_URL to extract individual connection parameters for asyncpg
Browse files- app/core/config.py +40 -2
app/core/config.py
CHANGED
|
@@ -41,13 +41,51 @@ class Settings(BaseSettings):
|
|
| 41 |
|
| 42 |
@model_validator(mode='after')
|
| 43 |
def assemble_db_connection(self) -> 'Settings':
|
| 44 |
-
from urllib.parse import quote_plus
|
|
|
|
| 45 |
# Prefer DATABASE_URL and DATABASE_URI
|
| 46 |
env_url = (os.getenv("DATABASE_URL") or os.getenv("DATABASE_URI") or "").strip()
|
| 47 |
if env_url:
|
| 48 |
self.POSTGRES_URI = env_url
|
| 49 |
-
print(f"[CONFIG] Using provided DATABASE_URL/URI
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
return self
|
|
|
|
| 51 |
# Build DSN from individual parts
|
| 52 |
if all([self.POSTGRES_USER, self.POSTGRES_PASSWORD, self.POSTGRES_HOST, self.POSTGRES_DB]):
|
| 53 |
protocol = os.getenv("DB_PROTOCOL", "postgresql+asyncpg")
|
|
|
|
| 41 |
|
| 42 |
@model_validator(mode='after')
|
| 43 |
def assemble_db_connection(self) -> 'Settings':
|
| 44 |
+
from urllib.parse import quote_plus, urlparse
|
| 45 |
+
|
| 46 |
# Prefer DATABASE_URL and DATABASE_URI
|
| 47 |
env_url = (os.getenv("DATABASE_URL") or os.getenv("DATABASE_URI") or "").strip()
|
| 48 |
if env_url:
|
| 49 |
self.POSTGRES_URI = env_url
|
| 50 |
+
print(f"[CONFIG] Using provided DATABASE_URL/URI")
|
| 51 |
+
|
| 52 |
+
# Parse the URL to extract individual components for asyncpg
|
| 53 |
+
try:
|
| 54 |
+
# Remove the +asyncpg suffix if present for parsing
|
| 55 |
+
parse_url = env_url.replace("postgresql+asyncpg://", "postgresql://")
|
| 56 |
+
parsed = urlparse(parse_url)
|
| 57 |
+
|
| 58 |
+
# Override individual settings from URL
|
| 59 |
+
if parsed.hostname:
|
| 60 |
+
self.POSTGRES_HOST = parsed.hostname
|
| 61 |
+
if parsed.port:
|
| 62 |
+
self.POSTGRES_PORT = parsed.port
|
| 63 |
+
if parsed.username:
|
| 64 |
+
self.POSTGRES_USER = parsed.username
|
| 65 |
+
if parsed.password:
|
| 66 |
+
self.POSTGRES_PASSWORD = parsed.password
|
| 67 |
+
if parsed.path and len(parsed.path) > 1:
|
| 68 |
+
self.POSTGRES_DB = parsed.path[1:] # Remove leading /
|
| 69 |
+
|
| 70 |
+
# Parse query parameters for SSL mode
|
| 71 |
+
if parsed.query:
|
| 72 |
+
from urllib.parse import parse_qs
|
| 73 |
+
params = parse_qs(parsed.query)
|
| 74 |
+
if 'sslmode' in params:
|
| 75 |
+
self.POSTGRES_SSL_MODE = params['sslmode'][0]
|
| 76 |
+
|
| 77 |
+
print(f"[CONFIG] Parsed DATABASE_URL:")
|
| 78 |
+
print(f"[CONFIG] Host: {self.POSTGRES_HOST}")
|
| 79 |
+
print(f"[CONFIG] Port: {self.POSTGRES_PORT}")
|
| 80 |
+
print(f"[CONFIG] Database: {self.POSTGRES_DB}")
|
| 81 |
+
print(f"[CONFIG] User: {self.POSTGRES_USER}")
|
| 82 |
+
print(f"[CONFIG] SSL Mode: {self.POSTGRES_SSL_MODE}")
|
| 83 |
+
|
| 84 |
+
except Exception as e:
|
| 85 |
+
print(f"[CONFIG] Warning: Failed to parse DATABASE_URL: {e}")
|
| 86 |
+
|
| 87 |
return self
|
| 88 |
+
|
| 89 |
# Build DSN from individual parts
|
| 90 |
if all([self.POSTGRES_USER, self.POSTGRES_PASSWORD, self.POSTGRES_HOST, self.POSTGRES_DB]):
|
| 91 |
protocol = os.getenv("DB_PROTOCOL", "postgresql+asyncpg")
|