136 lines
4.6 KiB
Python
136 lines
4.6 KiB
Python
from __future__ import annotations
|
|
|
|
from functools import lru_cache
|
|
from urllib.parse import quote_plus
|
|
|
|
from pydantic import Field
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(
|
|
env_file=".env",
|
|
env_file_encoding="utf-8",
|
|
extra="ignore",
|
|
)
|
|
|
|
app_name: str = "otel-bi-backend"
|
|
app_env: str = "dev"
|
|
log_level: str = "INFO"
|
|
|
|
api_host: str = "0.0.0.0"
|
|
api_port: int = 8000
|
|
|
|
cors_origins: str = "http://localhost:5173"
|
|
request_timeout_seconds: float = 20.0
|
|
|
|
mssql_host: str = "localhost"
|
|
mssql_port: int = 1433
|
|
mssql_username: str = "sa"
|
|
mssql_password: str = "Password!123"
|
|
mssql_driver: str = "ODBC Driver 18 for SQL Server"
|
|
mssql_trust_server_certificate: bool = False
|
|
|
|
wwi_database: str = "WorldWideImporters"
|
|
aw_database: str = "AdventureWorks2022DWH"
|
|
wwi_connection_string: str | None = None
|
|
aw_connection_string: str | None = None
|
|
postgres_host: str = "localhost"
|
|
postgres_port: int = 5432
|
|
postgres_database: str = "otel_bi_app"
|
|
postgres_username: str = "otel_bi_app"
|
|
postgres_password: str = "otel_bi_app"
|
|
postgres_sslmode: str = "require"
|
|
postgres_connection_string: str | None = None
|
|
postgres_required: bool = True
|
|
query_service_url: str = "http://localhost:8101"
|
|
analytics_service_url: str = "http://localhost:8102"
|
|
persistence_service_url: str = "http://localhost:8103"
|
|
require_frontend_auth: bool = True
|
|
frontend_jwt_issuer_url: str = ""
|
|
frontend_jwt_audience: str = ""
|
|
frontend_jwt_jwks_url: str | None = None
|
|
frontend_jwt_algorithm: str = "RS256"
|
|
frontend_required_scopes: str = ""
|
|
frontend_clock_skew_seconds: int = Field(default=30, ge=0, le=300)
|
|
internal_service_auth_enabled: bool = True
|
|
internal_service_shared_secret: str = "change-me"
|
|
internal_service_token_ttl_seconds: int = Field(default=120, ge=30, le=900)
|
|
internal_service_token_audience: str = "bi-internal"
|
|
internal_service_allowed_issuers: str = "api-gateway"
|
|
internal_token_clock_skew_seconds: int = Field(default=15, ge=0, le=120)
|
|
|
|
otel_service_name: str = "otel-bi-backend"
|
|
otel_service_namespace: str = "final-thesis"
|
|
otel_collector_endpoint: str = "http://localhost:4318"
|
|
otel_export_timeout_ms: int = 10000
|
|
|
|
forecast_horizon_days: int = Field(default=30, ge=7, le=180)
|
|
default_history_days: int = Field(default=365, ge=30, le=1460)
|
|
ranking_default_top_n: int = Field(default=10, ge=3, le=100)
|
|
storage_default_limit: int = Field(default=50, ge=10, le=500)
|
|
|
|
@property
|
|
def cors_origins_list(self) -> list[str]:
|
|
return [
|
|
origin.strip() for origin in self.cors_origins.split(",") if origin.strip()
|
|
]
|
|
|
|
@property
|
|
def frontend_required_scopes_list(self) -> list[str]:
|
|
return [
|
|
scope.strip()
|
|
for scope in self.frontend_required_scopes.split(" ")
|
|
if scope.strip()
|
|
]
|
|
|
|
@property
|
|
def internal_service_allowed_issuers_list(self) -> list[str]:
|
|
return [
|
|
issuer.strip()
|
|
for issuer in self.internal_service_allowed_issuers.split(",")
|
|
if issuer.strip()
|
|
]
|
|
|
|
def _build_mssql_connection_url(self, database: str) -> str:
|
|
driver = quote_plus(self.mssql_driver)
|
|
user = quote_plus(self.mssql_username)
|
|
password = quote_plus(self.mssql_password)
|
|
trust_cert = "yes" if self.mssql_trust_server_certificate else "no"
|
|
return (
|
|
f"mssql+pyodbc://{user}:{password}@{self.mssql_host}:{self.mssql_port}/{database}"
|
|
f"?driver={driver}&TrustServerCertificate={trust_cert}&ApplicationIntent=ReadOnly"
|
|
)
|
|
|
|
@property
|
|
def wwi_connection_url(self) -> str:
|
|
return self.wwi_connection_string or self._build_mssql_connection_url(
|
|
self.wwi_database
|
|
)
|
|
|
|
@property
|
|
def aw_connection_url(self) -> str:
|
|
return self.aw_connection_string or self._build_mssql_connection_url(
|
|
self.aw_database
|
|
)
|
|
|
|
@property
|
|
def postgres_connection_url(self) -> str:
|
|
if self.postgres_connection_string:
|
|
return self.postgres_connection_string
|
|
|
|
user = quote_plus(self.postgres_username)
|
|
password = quote_plus(self.postgres_password)
|
|
return (
|
|
f"postgresql+psycopg://{user}:{password}@{self.postgres_host}:{self.postgres_port}/"
|
|
f"{self.postgres_database}?sslmode={self.postgres_sslmode}"
|
|
)
|
|
|
|
|
|
@lru_cache
|
|
def get_settings() -> Settings:
|
|
return Settings()
|
|
|
|
|
|
settings = get_settings()
|