Mark some examples with Pydantic versions

This commit is contained in:
Yerassyl Zhanymkanov
2023-09-02 00:23:34 +06:00
parent 1fe5dd0031
commit 4df45d3899

View File

@@ -514,7 +514,8 @@ Will generate docs like this:
### 10. Use Pydantic's BaseSettings for configs ### 10. Use Pydantic's BaseSettings for configs
Pydantic gives a [powerful tool](https://pydantic-docs.helpmanual.io/usage/settings/) to parse environment variables and process them with its validators. Pydantic gives a [powerful tool](https://pydantic-docs.helpmanual.io/usage/settings/) to parse environment variables and process them with its validators.
```python ```python
from pydantic import AnyUrl, BaseSettings, PostgresDsn from pydantic import AnyUrl, PostgresDsn
from pydantic_settings import BaseSettings # pydantic v2
class AppSettings(BaseSettings): class AppSettings(BaseSettings):
class Config: class Config:
@@ -634,7 +635,7 @@ async def save_video(video_file: UploadFile):
while chunk := await video_file.read(DEFAULT_CHUNK_SIZE): while chunk := await video_file.read(DEFAULT_CHUNK_SIZE):
await f.write(chunk) await f.write(chunk)
``` ```
### 18. Be careful with dynamic pydantic fields ### 18. Be careful with dynamic pydantic fields (Pydantic v1)
If you have a pydantic field that can accept a union of types, be sure the validator explicitly knows the difference between those types. If you have a pydantic field that can accept a union of types, be sure the validator explicitly knows the difference between those types.
```python ```python
from pydantic import BaseModel from pydantic import BaseModel
@@ -685,7 +686,7 @@ class Video(BaseModel):
class Post(BaseModel): class Post(BaseModel):
content: Article | Video content: Article | Video
``` ```
2. Use Pydantic's Smart Union (>v1.9) if fields are simple 2. Use Pydantic's Smart Union (>v1.9, <2.0) if fields are simple
It's a good solution if the fields are simple like `int` or `bool`, It's a good solution if the fields are simple like `int` or `bool`,
but it doesn't work for complex fields like classes. but it doesn't work for complex fields like classes.
@@ -867,7 +868,7 @@ ALLOWED_MEDIA_URLS = {"mysite.com", "mysite.org"}
class CompanyMediaUrl(AnyUrl): class CompanyMediaUrl(AnyUrl):
@classmethod @classmethod
def validate_host(cls, parts: dict) -> tuple[str, str, str, bool]: def validate_host(cls, parts: dict) -> tuple[str, str, str, bool]: # pydantic v1
"""Extend pydantic's AnyUrl validation to whitelist URL hosts.""" """Extend pydantic's AnyUrl validation to whitelist URL hosts."""
host, tld, host_type, rebuild = super().validate_host(parts) host, tld, host_type, rebuild = super().validate_host(parts)
if host not in ALLOWED_MEDIA_URLS: if host not in ALLOWED_MEDIA_URLS:
@@ -891,7 +892,7 @@ from pydantic import BaseModel, validator
class ProfileCreate(BaseModel): class ProfileCreate(BaseModel):
username: str username: str
@validator("username") @validator("username") # pydantic v1
def validate_bad_words(cls, username: str): def validate_bad_words(cls, username: str):
if username == "me": if username == "me":
raise ValueError("bad username, choose another") raise ValueError("bad username, choose another")
@@ -964,19 +965,18 @@ async def call_my_sync_library():
client = SyncAPIClient() client = SyncAPIClient()
await run_in_threadpool(client.make_request, data=my_data) await run_in_threadpool(client.make_request, data=my_data)
``` ```
### 24. Use linters (black, isort, autoflake) ### 24. Use linters (black, ruff)
With linters, you can forget about formatting the code and focus on writing the business logic. With linters, you can forget about formatting the code and focus on writing the business logic.
Black is the uncompromising code formatter that eliminates so many small decisions you have to make during development. Black is the uncompromising code formatter that eliminates so many small decisions you have to make during development.
Other linters help you write cleaner code and follow the PEP8. Ruff is "blazingly-fast" new linter that replaces autoflake and isort, and supports more than 600 lint rules.
It's a popular good practice to use pre-commit hooks, but just using the script was ok for us. It's a popular good practice to use pre-commit hooks, but just using the script was ok for us.
```shell ```shell
#!/bin/sh -e #!/bin/sh -e
set -x set -x
autoflake --remove-all-unused-imports --recursive --remove-unused-variables --in-place src tests --exclude=__init__.py ruff --fix
isort src tests --profile black
black src tests black src tests
``` ```
### Bonus Section ### Bonus Section