settings.py
1 import json 2 import secrets 3 from typing import Any, Literal 4 5 import jq 6 from jq import _Program 7 from pydantic import BaseModel, BaseSettings, Field, validator 8 9 10 class OAuthProvider(BaseModel): 11 name: str 12 client_id: str 13 client_secret: str 14 authorize_url: str 15 token_url: str 16 userinfo_url: str 17 userinfo_headers: dict[str, str] 18 userinfo_id_path: _Program 19 userinfo_name_path: _Program 20 21 @validator("userinfo_headers", pre=True) 22 def _validate_userinfo_headers(cls, value: str) -> Any: # noqa: N805 23 return json.loads(value) 24 25 @validator("userinfo_id_path", pre=True) 26 def _validate_userinfo_id_path(cls, value: str) -> _Program: # noqa: N805 27 return jq.compile(value) 28 29 @validator("userinfo_name_path", pre=True) 30 def _validate_userinfo_name_path(cls, value: str) -> _Program: # noqa: N805 31 return jq.compile(value) 32 33 class Config: 34 arbitrary_types_allowed = True 35 36 37 class Settings(BaseSettings): 38 log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "INFO" 39 40 host: str = "0.0.0.0" # noqa: S104 41 port: int = 8000 42 root_path: str = "" 43 44 debug: bool = False 45 reload: bool = False 46 47 jwt_secret: str = secrets.token_urlsafe(64) 48 49 internal_jwt_ttl: int = 10 50 51 access_token_ttl: int = 300 52 refresh_token_ttl: int = 2592000 53 oauth_register_token_ttl: int = 600 54 hash_time_cost: int = 2 55 hash_memory_cost: int = 102400 56 mfa_valid_window: int = 1 57 login_fails_before_captcha: int = 3 58 59 recaptcha_sitekey: str | None = None 60 recaptcha_secret: str | None = None 61 62 admin_username: str = "admin" 63 admin_password: str = "admin" 64 65 open_registration: bool = False 66 open_oauth_registration: bool = False 67 68 database_url: str = Field( 69 "mysql+aiomysql://fastapi:fastapi@mariadb:3306/fastapi", 70 regex=r"^(mysql\+aiomysql|postgresql\+asyncpg|sqlite\+aiosqlite)://.*$", 71 ) 72 pool_recycle: int = 300 73 pool_size: int = 20 74 max_overflow: int = 20 75 sql_show_statements: bool = False 76 77 redis_url: str = Field("redis://redis:6379/0", regex=r"^redis://.*$") 78 79 sentry_dsn: str | None = None 80 81 oauth_providers: dict[str, OAuthProvider] = {} 82 83 class Config: 84 env_nested_delimiter = "__" 85 86 87 settings = Settings()