-
Notifications
You must be signed in to change notification settings - Fork 75
Updated pydantic to v2, updated fastapi to v0.103, other small fixes #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Hello! Thank you so much, this is good improvement, yes I'm aware of pydantic 2, migrated in some other projects and in work, just was involved in some other projects for a while. Overall it looks good, but I will make some "end to end" testing now to be sure it still works, in an hour or so. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, i would like to propose 2 changes
Unfortunately you used main branch in fork (which makes git cry because of name collision) to create PR instead of some new branch, without write access so I think I cannot make commits to your branch.
Take your time anyway, no rush there and I will merge after changes.
This is config.py
file after updates
"""
File with environment variables and general configuration logic.
`SECRET_KEY`, `ENVIRONMENT` etc. map to env variables with the same names.
Pydantic priority ordering:
1. (Most important, will overwrite everything) - environment variables
2. `.env` file in root folder of project
3. Default values
For project name, version, description we use pyproject.toml
For the rest, we use file `.env` (gitignored), see `.env.example`
`DEFAULT_SQLALCHEMY_DATABASE_URI` and `TEST_SQLALCHEMY_DATABASE_URI`:
Both are ment to be validated at the runtime, do not change unless you know
what are you doing. All the two validators do is to build full URI (TCP protocol)
to databases to avoid typo bugs.
See https://pydantic-docs.helpmanual.io/usage/settings/
Note, complex types like lists are read as json-encoded strings.
"""
import tomllib
from functools import cached_property
from pathlib import Path
from typing import Literal
from pydantic import AnyHttpUrl, EmailStr, PostgresDsn, computed_field
from pydantic_settings import BaseSettings, SettingsConfigDict
PROJECT_DIR = Path(__file__).parent.parent.parent
with open(f"{PROJECT_DIR}/pyproject.toml", "rb") as f:
PYPROJECT_CONTENT = tomllib.load(f)["tool"]["poetry"]
class Settings(BaseSettings):
# CORE SETTINGS
SECRET_KEY: str
ENVIRONMENT: Literal["DEV", "PYTEST", "STG", "PRD"] = "DEV"
SECURITY_BCRYPT_ROUNDS: int = 12
ACCESS_TOKEN_EXPIRE_MINUTES: int = 11520 # 8 days
REFRESH_TOKEN_EXPIRE_MINUTES: int = 40320 # 28 days
BACKEND_CORS_ORIGINS: list[AnyHttpUrl] = []
ALLOWED_HOSTS: list[str] = ["localhost", "127.0.0.1"]
# PROJECT NAME, VERSION AND DESCRIPTION
PROJECT_NAME: str = PYPROJECT_CONTENT["name"]
VERSION: str = PYPROJECT_CONTENT["version"]
DESCRIPTION: str = PYPROJECT_CONTENT["description"]
# POSTGRESQL DEFAULT DATABASE
DEFAULT_DATABASE_HOSTNAME: str
DEFAULT_DATABASE_USER: str
DEFAULT_DATABASE_PASSWORD: str
DEFAULT_DATABASE_PORT: int
DEFAULT_DATABASE_DB: str
# POSTGRESQL TEST DATABASE
TEST_DATABASE_HOSTNAME: str = "postgres"
TEST_DATABASE_USER: str = "postgres"
TEST_DATABASE_PASSWORD: str = "postgres"
TEST_DATABASE_PORT: int = 5432
TEST_DATABASE_DB: str = "postgres"
# FIRST SUPERUSER
FIRST_SUPERUSER_EMAIL: EmailStr
FIRST_SUPERUSER_PASSWORD: str
@computed_field
@cached_property
def DEFAULT_SQLALCHEMY_DATABASE_URI(self) -> str:
return str(
PostgresDsn.build(
scheme="postgresql+asyncpg",
username=self.DEFAULT_DATABASE_USER,
password=self.DEFAULT_DATABASE_PASSWORD,
host=self.DEFAULT_DATABASE_HOSTNAME,
port=self.DEFAULT_DATABASE_PORT,
path=self.DEFAULT_DATABASE_DB,
)
)
@computed_field
@cached_property
def TEST_SQLALCHEMY_DATABASE_URI(self) -> str:
return str(
PostgresDsn.build(
scheme="postgresql+asyncpg",
username=self.TEST_DATABASE_USER,
password=self.TEST_DATABASE_PASSWORD,
host=self.TEST_DATABASE_HOSTNAME,
port=self.TEST_DATABASE_PORT,
path=self.TEST_DATABASE_DB,
)
)
model_config = SettingsConfigDict(
env_file=f"{PROJECT_DIR}/.env", case_sensitive=True
)
settings: Settings = Settings() # type: ignore
Nice, I didn't know about @computed_field. That's much cleaner. |
Pydantic V2 changed several things, I followed their migration guide and otherwise just updated the dependencies to latest FastAPI and Pydantic.