155 lines
4.9 KiB
Python
155 lines
4.9 KiB
Python
from pathlib import Path
|
|
from typing import Optional
|
|
from urllib.parse import quote_plus
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
PROJECT_NAME: str = "TJWater Server"
|
|
ENVIRONMENT: str = "production"
|
|
API_V1_STR: str = "/api/v1"
|
|
|
|
NETWORK_NAME: str = "default_network"
|
|
|
|
# JWT 配置
|
|
SECRET_KEY: str = (
|
|
"your-secret-key-here-change-in-production-use-openssl-rand-hex-32"
|
|
)
|
|
ALGORITHM: str = "HS256"
|
|
ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
|
|
REFRESH_TOKEN_EXPIRE_DAYS: int = 7
|
|
|
|
# 数据加密密钥 (使用 Fernet)
|
|
ENCRYPTION_KEY: str = "" # 必须从环境变量设置
|
|
DATABASE_ENCRYPTION_KEY: str = "" # project_databases.dsn_encrypted 专用
|
|
|
|
# Database Config (PostgreSQL)
|
|
DB_NAME: str = "tjwater"
|
|
DB_HOST: str = "localhost"
|
|
DB_PORT: str = "5432"
|
|
DB_USER: str = "postgres"
|
|
DB_PASSWORD: str = "password"
|
|
|
|
# Database Config (TimescaleDB)
|
|
TIMESCALEDB_DB_NAME: str = "tjwater"
|
|
TIMESCALEDB_DB_HOST: str = "localhost"
|
|
TIMESCALEDB_DB_PORT: str = "5433"
|
|
TIMESCALEDB_DB_USER: str = "postgres"
|
|
TIMESCALEDB_DB_PASSWORD: str = "password"
|
|
# InfluxDB
|
|
INFLUXDB_URL: str = "http://localhost:8086"
|
|
INFLUXDB_TOKEN: str = "token"
|
|
INFLUXDB_ORG: str = "org"
|
|
INFLUXDB_BUCKET: str = "bucket"
|
|
|
|
# Metadata Database Config (PostgreSQL)
|
|
METADATA_DB_NAME: str = "system_hub"
|
|
METADATA_DB_HOST: str = "localhost"
|
|
METADATA_DB_PORT: str = "5432"
|
|
METADATA_DB_USER: str = "postgres"
|
|
METADATA_DB_PASSWORD: str = "password"
|
|
|
|
METADATA_DB_POOL_SIZE: int = 5
|
|
METADATA_DB_MAX_OVERFLOW: int = 10
|
|
|
|
PROJECT_PG_CACHE_SIZE: int = 50
|
|
PROJECT_TS_CACHE_SIZE: int = 50
|
|
PROJECT_PG_POOL_SIZE: int = 5
|
|
PROJECT_PG_MAX_OVERFLOW: int = 10
|
|
PROJECT_TS_POOL_MIN_SIZE: int = 1
|
|
PROJECT_TS_POOL_MAX_SIZE: int = 10
|
|
|
|
# Keycloak JWT (optional override)
|
|
KEYCLOAK_PUBLIC_KEY: str = ""
|
|
KEYCLOAK_ALGORITHM: str = "RS256"
|
|
KEYCLOAK_AUDIENCE: str = ""
|
|
|
|
@property
|
|
def SQLALCHEMY_DATABASE_URI(self) -> str:
|
|
db_password = quote_plus(self.DB_PASSWORD)
|
|
return f"postgresql://{self.DB_USER}:{db_password}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"
|
|
|
|
@property
|
|
def METADATA_DATABASE_URI(self) -> str:
|
|
metadata_password = quote_plus(self.METADATA_DB_PASSWORD)
|
|
return (
|
|
f"postgresql+psycopg://{self.METADATA_DB_USER}:{metadata_password}"
|
|
f"@{self.METADATA_DB_HOST}:{self.METADATA_DB_PORT}/{self.METADATA_DB_NAME}"
|
|
)
|
|
|
|
model_config = SettingsConfigDict(
|
|
env_file=Path(__file__).resolve().parents[2] / ".env",
|
|
extra="ignore",
|
|
)
|
|
|
|
|
|
settings = Settings()
|
|
|
|
|
|
def get_pgconn_string(
|
|
db_name: Optional[str] = None,
|
|
db_host: Optional[str] = None,
|
|
db_port: Optional[str] = None,
|
|
db_user: Optional[str] = None,
|
|
db_password: Optional[str] = None,
|
|
) -> str:
|
|
"""Return PostgreSQL connection string in psycopg conninfo format."""
|
|
resolved_db_name = db_name or settings.DB_NAME
|
|
resolved_db_host = db_host or settings.DB_HOST
|
|
resolved_db_port = db_port or settings.DB_PORT
|
|
resolved_db_user = db_user or settings.DB_USER
|
|
resolved_db_password = db_password or settings.DB_PASSWORD
|
|
return (
|
|
f"dbname={resolved_db_name} host={resolved_db_host} port={resolved_db_port} "
|
|
f"user={resolved_db_user} password={resolved_db_password}"
|
|
)
|
|
|
|
|
|
def get_pg_config() -> dict:
|
|
"""Return PostgreSQL configuration except password."""
|
|
return {
|
|
"name": settings.DB_NAME,
|
|
"host": settings.DB_HOST,
|
|
"port": settings.DB_PORT,
|
|
"user": settings.DB_USER,
|
|
}
|
|
|
|
|
|
def get_pg_password() -> str:
|
|
"""Return PostgreSQL password (use with care)."""
|
|
return settings.DB_PASSWORD
|
|
|
|
|
|
def get_timescaledb_pgconn_string(
|
|
db_name: Optional[str] = None,
|
|
db_host: Optional[str] = None,
|
|
db_port: Optional[str] = None,
|
|
db_user: Optional[str] = None,
|
|
db_password: Optional[str] = None,
|
|
) -> str:
|
|
"""Return TimescaleDB connection string in psycopg conninfo format."""
|
|
resolved_db_name = db_name or settings.TIMESCALEDB_DB_NAME
|
|
resolved_db_host = db_host or settings.TIMESCALEDB_DB_HOST
|
|
resolved_db_port = db_port or settings.TIMESCALEDB_DB_PORT
|
|
resolved_db_user = db_user or settings.TIMESCALEDB_DB_USER
|
|
resolved_db_password = db_password or settings.TIMESCALEDB_DB_PASSWORD
|
|
return (
|
|
f"dbname={resolved_db_name} host={resolved_db_host} port={resolved_db_port} "
|
|
f"user={resolved_db_user} password={resolved_db_password}"
|
|
)
|
|
|
|
|
|
def get_timescaledb_pg_config() -> dict:
|
|
"""Return TimescaleDB configuration except password."""
|
|
return {
|
|
"name": settings.TIMESCALEDB_DB_NAME,
|
|
"host": settings.TIMESCALEDB_DB_HOST,
|
|
"port": settings.TIMESCALEDB_DB_PORT,
|
|
"user": settings.TIMESCALEDB_DB_USER,
|
|
}
|
|
|
|
|
|
def get_timescaledb_pg_password() -> str:
|
|
"""Return TimescaleDB password (use with care)."""
|
|
return settings.TIMESCALEDB_DB_PASSWORD
|