Browse Source
* Use Pydantic BaseSettings for config settings * Update fastapi dep to >=0.47.0 and email_validator to email-validator * Fix deprecation warning for Pydantic >=1.0 * Properly support old-format comma separated strings for BACKEND_CORS_ORIGINS Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>pull/13907/head
committed by
GitHub
24 changed files with 173 additions and 140 deletions
@ -1,55 +1,92 @@ |
|||
import os |
|||
import secrets |
|||
from typing import List |
|||
|
|||
from pydantic import AnyHttpUrl, BaseSettings, EmailStr, HttpUrl, PostgresDsn, validator |
|||
|
|||
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 |
|||
|
|||
class Settings(BaseSettings): |
|||
|
|||
API_V1_STR = "/api/v1" |
|||
API_V1_STR: str = "/api/v1" |
|||
|
|||
SECRET_KEY = os.getenvb(b"SECRET_KEY") |
|||
if not SECRET_KEY: |
|||
SECRET_KEY = os.urandom(32) |
|||
SECRET_KEY: str = secrets.token_urlsafe(32) |
|||
|
|||
ACCESS_TOKEN_EXPIRE_MINUTES = 60 * 24 * 8 # 60 minutes * 24 hours * 8 days = 8 days |
|||
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8 # 60 minutes * 24 hours * 8 days = 8 days |
|||
|
|||
SERVER_NAME = os.getenv("SERVER_NAME") |
|||
SERVER_HOST = os.getenv("SERVER_HOST") |
|||
BACKEND_CORS_ORIGINS = os.getenv( |
|||
"BACKEND_CORS_ORIGINS" |
|||
) # a string of origins separated by commas, e.g: "http://localhost, http://localhost:4200, http://localhost:3000, http://localhost:8080, http://local.dockertoolbox.tiangolo.com" |
|||
PROJECT_NAME = os.getenv("PROJECT_NAME") |
|||
SENTRY_DSN = os.getenv("SENTRY_DSN") |
|||
SERVER_NAME: str |
|||
SERVER_HOST: AnyHttpUrl |
|||
# BACKEND_CORS_ORIGINS is a JSON-formatted list of origins |
|||
# e.g: '["http://localhost", "http://localhost:4200", "http://localhost:3000", \ |
|||
# "http://localhost:8080", "http://local.dockertoolbox.tiangolo.com"]' |
|||
BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = [] |
|||
|
|||
POSTGRES_SERVER = os.getenv("POSTGRES_SERVER") |
|||
POSTGRES_USER = os.getenv("POSTGRES_USER") |
|||
POSTGRES_PASSWORD = os.getenv("POSTGRES_PASSWORD") |
|||
POSTGRES_DB = os.getenv("POSTGRES_DB") |
|||
SQLALCHEMY_DATABASE_URI = ( |
|||
f"postgresql://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_SERVER}/{POSTGRES_DB}" |
|||
@validator("BACKEND_CORS_ORIGINS", pre=True) |
|||
def assemble_cors_origins(cls, v): |
|||
if isinstance(v, str) and not v.startswith("["): |
|||
return [i.strip() for i in v.split(",")] |
|||
return v |
|||
|
|||
PROJECT_NAME: str |
|||
SENTRY_DSN: HttpUrl = None |
|||
|
|||
@validator("SENTRY_DSN", pre=True) |
|||
def sentry_dsn_can_be_blank(cls, v): |
|||
if len(v) == 0: |
|||
return None |
|||
return v |
|||
|
|||
POSTGRES_SERVER: str |
|||
POSTGRES_USER: str |
|||
POSTGRES_PASSWORD: str |
|||
POSTGRES_DB: str |
|||
SQLALCHEMY_DATABASE_URI: PostgresDsn = None |
|||
|
|||
@validator("SQLALCHEMY_DATABASE_URI", pre=True) |
|||
def assemble_db_connection(cls, v, values): |
|||
if isinstance(v, str): |
|||
return v |
|||
return PostgresDsn.build( |
|||
scheme="postgresql", |
|||
user=values.get("POSTGRES_USER"), |
|||
password=values.get("POSTGRES_PASSWORD"), |
|||
host=values.get("POSTGRES_SERVER"), |
|||
path=f"/{values.get('POSTGRES_DB') or ''}", |
|||
) |
|||
|
|||
SMTP_TLS = getenv_boolean("SMTP_TLS", True) |
|||
SMTP_PORT = None |
|||
_SMTP_PORT = os.getenv("SMTP_PORT") |
|||
if _SMTP_PORT is not None: |
|||
SMTP_PORT = int(_SMTP_PORT) |
|||
SMTP_HOST = os.getenv("SMTP_HOST") |
|||
SMTP_USER = os.getenv("SMTP_USER") |
|||
SMTP_PASSWORD = os.getenv("SMTP_PASSWORD") |
|||
EMAILS_FROM_EMAIL = os.getenv("EMAILS_FROM_EMAIL") |
|||
EMAILS_FROM_NAME = PROJECT_NAME |
|||
EMAIL_RESET_TOKEN_EXPIRE_HOURS = 48 |
|||
EMAIL_TEMPLATES_DIR = "/app/app/email-templates/build" |
|||
EMAILS_ENABLED = SMTP_HOST and SMTP_PORT and EMAILS_FROM_EMAIL |
|||
|
|||
FIRST_SUPERUSER = os.getenv("FIRST_SUPERUSER") |
|||
FIRST_SUPERUSER_PASSWORD = os.getenv("FIRST_SUPERUSER_PASSWORD") |
|||
|
|||
USERS_OPEN_REGISTRATION = getenv_boolean("USERS_OPEN_REGISTRATION") |
|||
|
|||
EMAIL_TEST_USER = "test@example.com" |
|||
SMTP_TLS: bool = True |
|||
SMTP_PORT: int = None |
|||
SMTP_HOST: str = None |
|||
SMTP_USER: str = None |
|||
SMTP_PASSWORD: str = None |
|||
EMAILS_FROM_EMAIL: EmailStr = None |
|||
EMAILS_FROM_NAME: str = None |
|||
|
|||
@validator("EMAILS_FROM_NAME") |
|||
def get_project_name(cls, v, values): |
|||
if not v: |
|||
return values["PROJECT_NAME"] |
|||
return v |
|||
|
|||
EMAIL_RESET_TOKEN_EXPIRE_HOURS: int = 48 |
|||
EMAIL_TEMPLATES_DIR: str = "/app/app/email-templates/build" |
|||
EMAILS_ENABLED: bool = False |
|||
|
|||
@validator("EMAILS_ENABLED", pre=True) |
|||
def get_emails_enabled(cls, v, values): |
|||
return bool( |
|||
values.get("SMTP_HOST") |
|||
and values.get("SMTP_PORT") |
|||
and values.get("EMAILS_FROM_EMAIL") |
|||
) |
|||
|
|||
EMAIL_TEST_USER: EmailStr = "test@example.com" |
|||
|
|||
FIRST_SUPERUSER: EmailStr |
|||
FIRST_SUPERUSER_PASSWORD: str |
|||
|
|||
USERS_OPEN_REGISTRATION: bool = False |
|||
|
|||
class Config: |
|||
case_sensitive = True |
|||
|
|||
settings = Settings() |
|||
|
Loading…
Reference in new issue