Skip to content

Commit 8b914a3

Browse files
Brain256Brain256
authored andcommitted
add database config to config manager
1 parent e3a8c43 commit 8b914a3

File tree

8 files changed

+97
-48
lines changed

8 files changed

+97
-48
lines changed

gs/backend/api/backend_setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from gs.backend.api.v1.mcc.endpoints.commands import commands_router
1313
from gs.backend.api.v1.mcc.endpoints.main_commands import main_commands_router
1414
from gs.backend.api.v1.mcc.endpoints.telemetry import telemetry_router
15-
from gs.backend.config.config import backend_config
15+
from gs.backend.config.config import settings
1616

1717

1818
def setup_routes(app: FastAPI) -> None:
@@ -38,7 +38,7 @@ def setup_middlewares(app: FastAPI) -> None:
3838
app.add_middleware(AuthMiddleware)
3939
app.add_middleware(
4040
LoggerMiddleware,
41-
excluded_endpoints=backend_config.logger_config.excluded_endpoints,
41+
excluded_endpoints=settings.logger.excluded_endpoints,
4242
)
4343

4444

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from fastapi import FastAPI
22
from fastapi.middleware.cors import CORSMiddleware
33

4-
from gs.backend.config.config import backend_config
4+
from gs.backend.config.config import settings
55

66

77
def add_cors_middleware(app: FastAPI) -> None:
@@ -12,8 +12,8 @@ def add_cors_middleware(app: FastAPI) -> None:
1212
"""
1313
app.add_middleware(
1414
CORSMiddleware,
15-
allow_origins=backend_config.cors_config.allow_origins,
16-
allow_credentials=backend_config.cors_config.allow_credentials,
17-
allow_methods=backend_config.cors_config.allow_methods,
18-
allow_headers=backend_config.cors_config.allow_headers,
15+
allow_origins=settings.cors.allow_origins,
16+
allow_credentials=settings.cors.allow_credentials,
17+
allow_methods=settings.cors.allow_methods,
18+
allow_headers=settings.cors.allow_headers,
1919
)

gs/backend/config/config.py

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,19 @@
11
# TODO:(335) Improve loading the configuration
2-
from os import environ
3-
from typing import Final
4-
5-
from dotenv import load_dotenv
62

73
from .cors_config import CORSConfig
4+
from .database_config import DatabaseConfig
85
from .logger_config import LoggerConfig
96

10-
load_dotenv()
11-
127

138
class BackendConfiguration:
149
"""
1510
Class for storing backend configuration settings
1611
"""
1712

1813
def __init__(self) -> None:
19-
self.cors_config = CORSConfig()
20-
self.logger_config = LoggerConfig()
21-
22-
23-
backend_config = BackendConfiguration()
24-
25-
26-
def getenv(config: str) -> str:
27-
"""
28-
Validates whether or not database env values exist in .env. If not, throws a value error.
29-
30-
:param config: Variable in .env
31-
:type config: str
32-
:return: Value of variable in .env
33-
:rtype: str
34-
"""
35-
value = environ.get(config)
36-
if not value:
37-
raise ValueError(f"{config} is missing from .env.")
38-
return value
39-
14+
self.cors = CORSConfig()
15+
self.logger = LoggerConfig()
16+
self.db = DatabaseConfig()
4017

41-
GS_DATABASE_USER = getenv("GS_DATABASE_USER")
42-
GS_DATABASE_PASSWORD = getenv("GS_DATABASE_PASSWORD")
43-
GS_DATABASE_LOCATION = getenv("GS_DATABASE_LOCATION")
44-
GS_DATABASE_PORT = getenv("GS_DATABASE_PORT")
45-
GS_DATABASE_NAME = getenv("GS_DATABASE_NAME")
4618

47-
DATABASE_CONNECTION_STRING: Final[
48-
str
49-
] = f"postgresql+psycopg2://{GS_DATABASE_USER}:{GS_DATABASE_PASSWORD}@{GS_DATABASE_LOCATION}:{GS_DATABASE_PORT}/{GS_DATABASE_NAME}"
19+
settings = BackendConfiguration()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from pydantic import SecretStr
2+
from pydantic_settings import BaseSettings, SettingsConfigDict
3+
4+
5+
class DatabaseConfig(BaseSettings):
6+
"""
7+
Pydantic class for storing database configuration settings
8+
"""
9+
10+
model_config = SettingsConfigDict(env_prefix="GS_DATABASE_")
11+
12+
user: str
13+
password: SecretStr
14+
location: str
15+
port: int
16+
name: str
17+
18+
def connection_string(self) -> str:
19+
"""
20+
Returns the database connection string
21+
"""
22+
23+
pwd = self.password.get_secret_value()
24+
return f"postgresql://{self.user}:{pwd}@{self.location}:{self.port}/{self.name}"

gs/backend/data/database/engine.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from sqlalchemy import Engine
22
from sqlmodel import Session, create_engine, text
33

4-
from gs.backend.config.config import DATABASE_CONNECTION_STRING
4+
from gs.backend.config.config import settings
55
from gs.backend.data.tables.aro_user_tables import ARO_USER_SCHEMA_NAME
66
from gs.backend.data.tables.main_tables import MAIN_SCHEMA_NAME
77
from gs.backend.data.tables.transactional_tables import TRANSACTIONAL_SCHEMA_NAME
@@ -13,7 +13,7 @@ def get_db_engine() -> Engine:
1313
1414
:return: engine
1515
"""
16-
return create_engine(DATABASE_CONNECTION_STRING)
16+
return create_engine(settings.db.connection_string())
1717

1818

1919
def get_db_session() -> Session:

package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

python_test/conftest.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
import subprocess
33
from datetime import datetime
44

5+
os.environ.setdefault("GS_DATABASE_USER", "testuser")
6+
os.environ.setdefault("GS_DATABASE_PASSWORD", "testpassword")
7+
os.environ.setdefault("GS_DATABASE_LOCATION", "localhost")
8+
os.environ.setdefault("GS_DATABASE_PORT", "5432")
9+
os.environ.setdefault("GS_DATABASE_NAME", "testdb")
10+
511
import pytest
612
from gs.backend.data.database.engine import setup_database
713
from gs.backend.data.tables.transactional_tables import CommsSession

python_test/test_config_manager.py

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import importlib
22

3+
import pytest
34
from gs.backend.config import config
45
from gs.backend.config.cors_config import CORSConfig
6+
from gs.backend.config.database_config import DatabaseConfig
57
from gs.backend.config.logger_config import LoggerConfig
8+
from pydantic import ValidationError
69

710

811
def test_logger_config_default():
912
cfg = LoggerConfig()
13+
1014
assert cfg.excluded_endpoints == []
1115

1216

@@ -21,9 +25,48 @@ def test_cors_config_default():
2125

2226
def test_backend_configuration_from_env(monkeypatch):
2327
monkeypatch.setenv("LOGGER_EXCLUDED_ENDPOINTS", '["/test"]')
24-
monkeypatch.setenv("CORS_ALLOW_ORIGINS", '["http://test.com"]')
28+
monkeypatch.setenv("CORS_ALLOW_ORIGINS", '["http://localhost:5173"]')
29+
monkeypatch.setenv("CORS_ALLOW_CREDENTIALS", "True")
30+
monkeypatch.setenv("CORS_ALLOW_METHODS", '["*"]')
31+
monkeypatch.setenv("CORS_ALLOW_HEADERS", '["*"]')
2532

2633
importlib.reload(config)
27-
cfg = config.backend_config
28-
assert "/test" in cfg.logger_config.excluded_endpoints
29-
assert "http://test.com" in cfg.cors_config.allow_origins
34+
cfg = config.settings
35+
36+
assert "/test" in cfg.logger.excluded_endpoints
37+
assert "http://localhost:5173" in cfg.cors.allow_origins
38+
assert cfg.db.user == "testuser"
39+
assert cfg.db.password.get_secret_value() == "testpassword"
40+
assert cfg.db.location == "localhost"
41+
assert cfg.db.port == 5432
42+
assert cfg.db.name == "testdb"
43+
44+
45+
def test_database_connection_string():
46+
db = config.settings.db
47+
48+
assert db.password.get_secret_value() == "testpassword"
49+
expected_url = "postgresql://testuser:testpassword@localhost:5432/testdb"
50+
assert db.connection_string() == expected_url
51+
52+
53+
def test_database_missing_env(monkeypatch):
54+
monkeypatch.delenv("GS_DATABASE_PASSWORD")
55+
56+
with pytest.raises(ValidationError):
57+
DatabaseConfig()
58+
59+
60+
def test_invalid_env(monkeypatch):
61+
monkeypatch.setenv("GS_DATABASE_PORT", "test")
62+
monkeypatch.setenv("CORS_ALLOW_CREDENTIALS", "3")
63+
monkeypatch.setenv("LOGGER_EXCLUDED_ENDPOINTS", "3")
64+
65+
with pytest.raises(ValidationError):
66+
DatabaseConfig()
67+
68+
with pytest.raises(ValidationError):
69+
CORSConfig()
70+
71+
with pytest.raises(ValidationError):
72+
LoggerConfig()

0 commit comments

Comments
 (0)