|
1 | 1 | import os |
2 | 2 | from enum import Enum |
3 | 3 |
|
4 | | -from pydantic import SecretStr, computed_field |
| 4 | +from pydantic import SecretStr, computed_field, field_validator |
5 | 5 | from pydantic_settings import BaseSettings, SettingsConfigDict |
6 | 6 |
|
7 | 7 |
|
8 | 8 | class AppSettings(BaseSettings): |
9 | 9 | APP_NAME: str = "FastAPI app" |
10 | 10 | APP_DESCRIPTION: str | None = None |
11 | 11 | APP_VERSION: str | None = None |
| 12 | + APP_BACKEND_HOST: str = "http://localhost:8000" |
| 13 | + APP_FRONTEND_HOST: str | None = None |
12 | 14 | LICENSE_NAME: str | None = None |
13 | 15 | CONTACT_NAME: str | None = None |
14 | 16 | CONTACT_EMAIL: str | None = None |
15 | 17 |
|
| 18 | + @field_validator("APP_BACKEND_HOST", "APP_FRONTEND_HOST", mode="after") |
| 19 | + @classmethod |
| 20 | + def validate_hosts(cls, host: str) -> str: |
| 21 | + if host is not None and not (host.startswith("http://") or host.startswith("https://")): |
| 22 | + raise ValueError( |
| 23 | + f"HOSTS must define their protocol and start with http:// or https://. Received the host {host}." |
| 24 | + ) |
| 25 | + return host |
| 26 | + |
16 | 27 |
|
17 | 28 | class CryptSettings(BaseSettings): |
18 | 29 | SECRET_KEY: SecretStr = SecretStr("secret-key") |
@@ -172,5 +183,14 @@ class Settings( |
172 | 183 | extra="ignore", |
173 | 184 | ) |
174 | 185 |
|
| 186 | + @field_validator("APP_FRONTEND_HOST") |
| 187 | + @classmethod |
| 188 | + def validate_app_frontend_host_protocol(cls, host: str) -> str: |
| 189 | + if EnvironmentSettings.ENVIRONMENT == EnvironmentOption.PRODUCTION and not host.startswith("https://"): |
| 190 | + raise ValueError( |
| 191 | + f"In production, APP_FRONTEND_HOST must start with the https:// protocol. Received the host {host}." |
| 192 | + ) |
| 193 | + return host |
| 194 | + |
175 | 195 |
|
176 | 196 | settings = Settings() |
0 commit comments