config.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. """
  2. File with environment variables and general configuration logic.
  3. `SECRET_KEY`, `ENVIRONMENT` etc. map to env variables with the same names.
  4. Pydantic priority ordering:
  5. 1. (Most important, will overwrite everything) - environment variables
  6. 2. `.env` file in root folder of project
  7. 3. Default values
  8. For project name, version, description we use pyproject.toml
  9. For the rest, we use file `.env` (gitignored), see `.env.example`
  10. See https://pydantic-docs.helpmanual.io/usage/settings/
  11. Note, complex types like lists are read as json-encoded strings.
  12. """
  13. import tomllib
  14. from pathlib import Path
  15. from typing import Literal
  16. from pydantic import AnyHttpUrl, EmailStr
  17. from pydantic_settings import BaseSettings, SettingsConfigDict
  18. PROJECT_DIR = Path(__file__).parent.parent.parent
  19. with open(f"{PROJECT_DIR}/pyproject.toml", "rb") as f:
  20. PYPROJECT_CONTENT = tomllib.load(f)["tool"]["poetry"]
  21. def build_postgreuri(
  22. scheme: str, username: str, password: str, host: str, port: int = 0, path: str = ""
  23. ):
  24. fullhost = host + (f":{port}" if port > 0 else "")
  25. return f"{scheme}://{username}:{password}@{fullhost}{path}"
  26. class Settings(BaseSettings):
  27. # CORE SETTINGS
  28. FRONT_END_URL: str
  29. SECRET_KEY: str
  30. RESET_REQUEST_LIMIT: int = 3
  31. RESET_REQUEST_WINDOW_HOUR: int = 1
  32. ENVIRONMENT: Literal["DEV", "PYTEST", "STG", "PRD"] = "DEV"
  33. SECURITY_BCRYPT_ROUNDS: int = 12
  34. ACCESS_TOKEN_EXPIRE_MINUTES: int = 11520 # 8 days
  35. REFRESH_TOKEN_EXPIRE_MINUTES: int = 40320 # 28 days
  36. BACKEND_CORS_ORIGINS: list[AnyHttpUrl | Literal["*"]] = []
  37. ALLOWED_HOSTS: list[str] = ["localhost", "127.0.0.1"]
  38. INACTIVITY_SMS_SENDER_THRESHOLD_SECONDS: int = 180
  39. # PROJECT NAME, VERSION AND DESCRIPTION
  40. PROJECT_NAME: str = PYPROJECT_CONTENT["name"]
  41. VERSION: str = PYPROJECT_CONTENT["version"]
  42. DESCRIPTION: str = PYPROJECT_CONTENT["description"]
  43. # Email account to send reset password
  44. SMTP_HOST: str = ""
  45. SMTP_PORT: int = 587
  46. SMTP_USERNAME: str = ""
  47. SMTP_PASSWORD: str = ""
  48. SMTP_USE_TLS: bool = True
  49. EMAIL_FROM_ADDRESS: str = "no-reply@example.com"
  50. EMAIL_FROM_NAME: str = "BDLG Planner"
  51. # REDIS
  52. REDIS_URL: str = "redis://localhost:6379"
  53. # POSTGRESQL DEFAULT DATABASE
  54. DEFAULT_DATABASE_HOSTNAME: str
  55. DEFAULT_DATABASE_USER: str
  56. DEFAULT_DATABASE_PASSWORD: str
  57. DEFAULT_DATABASE_PORT: str
  58. DEFAULT_DATABASE_DB: str
  59. @property
  60. def DEFAULT_SQLALCHEMY_DATABASE_URI(self) -> str:
  61. return build_postgreuri(
  62. scheme="postgresql",
  63. username=self.DEFAULT_DATABASE_USER,
  64. password=self.DEFAULT_DATABASE_PASSWORD,
  65. host=self.DEFAULT_DATABASE_HOSTNAME,
  66. port=int(self.DEFAULT_DATABASE_PORT),
  67. path=f"/{self.DEFAULT_DATABASE_DB}",
  68. )
  69. # POSTGRESQL TEST DATABASE
  70. TEST_DATABASE_HOSTNAME: str = "postgres"
  71. TEST_DATABASE_USER: str = "postgres"
  72. TEST_DATABASE_PASSWORD: str = "postgres"
  73. TEST_DATABASE_PORT: str = "5432"
  74. TEST_DATABASE_DB: str = "postgres"
  75. @property
  76. def TEST_SQLALCHEMY_DATABASE_URI(self) -> str:
  77. return build_postgreuri(
  78. scheme="postgresql",
  79. username=self.TEST_DATABASE_USER,
  80. password=self.TEST_DATABASE_PASSWORD,
  81. host=self.TEST_DATABASE_HOSTNAME,
  82. port=int(self.TEST_DATABASE_PORT),
  83. path=f"/{self.TEST_DATABASE_DB}",
  84. )
  85. # SMS batch
  86. BATCH_SMS_PHONE_NUMBER: str = ""
  87. # FIRST SUPERUSER
  88. FIRST_SUPERUSER_EMAIL: EmailStr
  89. FIRST_SUPERUSER_PASSWORD: str
  90. model_config = SettingsConfigDict(env_file=f"{PROJECT_DIR}/.env", case_sensitive=True)
  91. settings: Settings = Settings() # type: ignore