felicity-lims/felicity/core/config.py

140 lines
5.2 KiB
Python
Raw Normal View History

2023-08-14 02:08:08 +08:00
import os
from typing import Any
2023-09-11 12:57:19 +08:00
from pydantic import AnyHttpUrl, EmailStr, field_validator, ConfigDict
from pydantic_core.core_schema import FieldValidationInfo
2023-08-14 02:08:08 +08:00
from pydantic_settings import BaseSettings
def getenv_boolean(var_name, default_value=False):
result = default_value
env_value = os.getenv(var_name)
if env_value is not None:
result = env_value.upper() in ("TRUE", "1")
return result
def getenv_value(value, default_value=None):
env_value = os.getenv(value)
if env_value is None:
env_value = default_value
return env_value
class Settings(BaseSettings):
2023-09-11 13:02:05 +08:00
BASE_DIR: str = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
2023-08-14 02:08:08 +08:00
STATIC_DIR: str = os.path.join(BASE_DIR, "static")
API_V1_STR: str = "/api/v1"
2023-11-24 06:22:22 +08:00
ALGORITHM: str = "HS256"
2023-08-14 02:08:08 +08:00
SECRET_KEY: str = (
# secrets.token_urlsafe(32)
"uIM7aXFRzaIxWr1NEy_RMQg9iIuDkLAlkOPs5zpgbts"
)
2023-11-24 06:22:22 +08:00
REFRESH_SECRET_KEY: str = (
# secrets.token_urlsafe(32)
"v0hilmAK-_iu_F-E2I89kVGKNgk2oeKIpyYW2qT3Brg"
)
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 8 * 1 # 8 hours
REFRESH_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 1 # 1 day / 24 hours
2023-08-14 02:08:08 +08:00
SERVER_NAME: str = getenv_value("SERVER_NAME", "felicity")
SERVER_HOST: AnyHttpUrl = getenv_value("SERVER_HOST", "https://localhost")
CORS_ORIGINS: list[str] = [
"http://localhost:5173",
2023-09-11 12:57:19 +08:00
"http://localhost:3000",
"http://localhost:8000"
2023-08-14 02:08:08 +08:00
]
CORS_SUPPORTS_CREDENTIALS: bool = True
CORS_ALLOW_HEADERS: list[str] = [
2023-09-11 13:02:05 +08:00
"Authorization",
"access-control-allow-methods",
"content-type",
"access-control-allow-origin",
"access-control-allow-headers",
2023-08-14 02:08:08 +08:00
]
2023-09-11 13:02:05 +08:00
2023-08-14 02:08:08 +08:00
TESTING: bool = getenv_boolean("TESTING", False)
RETAIN_TESTING_DB_DATA: bool = getenv_boolean("RETAIN_TESTING_DB_DATA", True)
PROJECT_NAME: str = getenv_value("PROJECT_NAME", "FELLICITY LIMS")
2023-09-11 13:02:05 +08:00
POSTGRES_SERVER: str = getenv_value("POSTGRES_SERVER", "localhost") # felicity_db
2023-08-14 02:08:08 +08:00
POSTGRES_USER: str = getenv_value("POSTGRES_USER", "felicity")
POSTGRES_PASSWORD: str = getenv_value("POSTGRES_PASSWORD", "felicity")
2023-09-11 14:49:44 +08:00
POSTGRES_DB: str = getenv_value("POSTGRES_DB", "felicity_lims")
2023-08-14 02:08:08 +08:00
SQLALCHEMY_DATABASE_URI: str | None = None
SQLALCHEMY_TEST_DATABASE_URI: str | None = None
2023-09-11 12:57:19 +08:00
@field_validator("SQLALCHEMY_DATABASE_URI")
def assemble_async_db_connection(
cls, v: str | None, info: FieldValidationInfo
) -> Any:
2023-08-14 02:08:08 +08:00
if isinstance(v, str):
return v
2023-09-11 12:57:19 +08:00
return f'postgresql+asyncpg://{info.data.get("POSTGRES_USER")}:{info.data.get("POSTGRES_PASSWORD")}@{info.data.get("POSTGRES_SERVER")}/{info.data.get("POSTGRES_DB") or ""}'
2023-08-14 02:08:08 +08:00
2023-09-11 12:57:19 +08:00
@field_validator("SQLALCHEMY_TEST_DATABASE_URI")
2023-08-14 02:08:08 +08:00
def assemble_async_test_db_connection(
2023-09-11 12:57:19 +08:00
cls, v: str | None, info: FieldValidationInfo
2023-08-14 02:08:08 +08:00
) -> Any:
if isinstance(v, str):
return v
2023-09-14 16:35:24 +08:00
return f'postgresql+asyncpg://{info.data.get("POSTGRES_USER")}:{info.data.get("POSTGRES_PASSWORD")}@{info.data.get("POSTGRES_SERVER")}/test_{info.data.get("POSTGRES_DB") or ""}'
2023-08-14 02:08:08 +08:00
SMTP_TLS: bool = getenv_boolean("SMTP_TLS", False)
SMTP_PORT: int | None = getenv_value("SMTP_PORT", 1025)
SMTP_HOST: str | None = getenv_value("SMTP_HOST", "localhost")
SMTP_USER: str | None = getenv_value("SMTP_USER", "")
SMTP_PASSWORD: str | None = getenv_value("SMTP_PASSWORD", "")
EMAILS_FROM_EMAIL: EmailStr | None = getenv_value(
"EMAILS_FROM_EMAIL", "felicity@felicity.labs"
)
2023-09-11 13:02:05 +08:00
EMAILS_FROM_NAME: str | None = getenv_value("EMAILS_FROM_NAME", "felicity")
2023-08-14 02:08:08 +08:00
2023-09-11 12:57:19 +08:00
@field_validator("EMAILS_FROM_NAME")
def get_project_name(cls, v: str | None, info: FieldValidationInfo) -> str:
2023-08-14 02:08:08 +08:00
if not v:
2023-09-11 12:57:19 +08:00
return info.data["PROJECT_NAME"]
2023-08-14 02:08:08 +08:00
return v
EMAIL_RESET_TOKEN_EXPIRE_HOURS: int = 48
EMAIL_TEMPLATES_DIR: str = BASE_DIR + "/utils/email/email-templates/output"
EMAILS_ENABLED: bool = False
2023-09-11 12:57:19 +08:00
@field_validator("EMAILS_ENABLED")
def get_emails_enabled(cls, v: bool, info: FieldValidationInfo) -> bool:
2023-08-14 02:08:08 +08:00
return bool(
2023-09-11 12:57:19 +08:00
info.data.get("SMTP_HOST")
and info.data.get("SMTP_PORT")
and info.data.get("EMAILS_FROM_EMAIL")
2023-08-14 02:08:08 +08:00
)
EMAIL_TEST_USER: EmailStr = "admin@stanchionlabs.inc"
FIRST_SUPERUSER_EMAIL: EmailStr = getenv_value(
"FIRST_SUPERUSER", "admin@felicitylabs.com"
)
2023-09-11 13:02:05 +08:00
FIRST_SEPERUSER_USERNAME: str = getenv_value("FIRST_SEPERUSER_USERNAME", "admin")
2023-08-14 02:08:08 +08:00
FIRST_SUPERUSER_PASSWORD: str = getenv_value(
"FIRST_SUPERUSER_PASSWORD", "!Felicity#100"
)
# Reserved System User
SYSTEM_DAEMONUSER_EMAIL: EmailStr = "system_daemon@system.daemon"
SYSTEM_DAEMONUSER_USERNAME: str = "system_daemon"
SYSTEM_DAEMONUSER_PASSWORD: str = "!System@Daemon#100"
#
USERS_OPEN_REGISTRATION: bool = False
LOAD_SETUP_DATA: bool = getenv_boolean("LOAD_SETUP_DATA", False)
2023-11-11 00:48:39 +08:00
SERVE_WEBAPP: bool = getenv_boolean("SERVE_WEBAPP", True)
2023-08-14 02:08:08 +08:00
# Tracing
RUN_OPEN_TRACING: bool = getenv_boolean("RUN_OPEN_TRACING", False)
OTLP_SPAN_EXPORT_URL: str = getenv_value(
2023-09-11 13:02:05 +08:00
"OTLP_SPAN_EXPORT_URL", "http://localhost:4317"
)
2023-08-14 02:08:08 +08:00
2023-09-11 12:57:19 +08:00
model_config = ConfigDict(case_sensitive=True)
2023-08-14 02:08:08 +08:00
2023-09-11 13:02:05 +08:00
settings = Settings()