Skip to content

Commit caa2a48

Browse files
authored
Merge pull request #63 from febus982/pydantic_v2
Use pydantic v2
2 parents ee19398 + 20fe4f4 commit caa2a48

File tree

11 files changed

+625
-416
lines changed

11 files changed

+625
-416
lines changed

config.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import logging
22
import os
3-
from typing import List, Literal
3+
from typing import Dict, List, Literal
44

55
import structlog
66
from opentelemetry import trace
7-
from pydantic import BaseSettings
7+
from pydantic_settings import BaseSettings
88
from sqlalchemy_bind_manager import SQLAlchemyAsyncConfig
99
from structlog.typing import Processor
1010

1111
TYPE_ENVIRONMENT = Literal["local", "test", "staging", "production"]
1212

1313

1414
class AppConfig(BaseSettings):
15-
SQLALCHEMY_CONFIG = {
16-
"default": SQLAlchemyAsyncConfig(
15+
SQLALCHEMY_CONFIG: Dict[str, SQLAlchemyAsyncConfig] = dict(
16+
default=SQLAlchemyAsyncConfig(
1717
engine_url=f"sqlite+aiosqlite:///{os.path.dirname(os.path.abspath(__file__))}/sqlite.db",
1818
engine_options=dict(
1919
connect_args={
@@ -23,7 +23,7 @@ class AppConfig(BaseSettings):
2323
future=True,
2424
),
2525
),
26-
}
26+
)
2727
ENVIRONMENT: TYPE_ENVIRONMENT = "local"
2828
DEBUG: bool = False
2929

domains/books/_dto.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@ class BookData(BaseModel):
77
title: str
88
author_name: str
99

10-
class Config:
11-
orm_mode = True
12-
1310

1411
class Book(BookData):
1512
book_id: Union[int, None] = None
16-
17-
class Config:
18-
orm_mode = True

domains/books/_service.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,16 @@ async def create_book(self, book: BookData) -> Book:
2626
# Using processes could be better, but it would bring technical complexity
2727
# https://anyio.readthedocs.io/en/3.x/subprocesses.html#running-functions-in-worker-processes
2828
book_data_altered = await to_thread.run_sync(
29-
some_cpu_intensive_blocking_task, book.dict()
29+
some_cpu_intensive_blocking_task, book.model_dump()
3030
)
3131
book_model = BookModel(**book_data_altered)
32-
return Book.from_orm(await self.book_repository.save(book_model))
32+
return Book.model_validate(
33+
await self.book_repository.save(book_model), from_attributes=True
34+
)
3335

3436
async def list_books(self) -> Iterable[Book]:
3537
books = await self.book_repository.find()
36-
return [Book.from_orm(x) for x in books]
38+
return [Book.model_validate(x, from_attributes=True) for x in books]
3739

3840

3941
def some_cpu_intensive_blocking_task(book: dict) -> dict:

grpc_app/servicers/books.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ async def ListBooks(
1414
book_service = BookService()
1515
return books_messages.ListBooksResponse(
1616
books=[
17-
books_messages.Book(**x.dict()) for x in await book_service.list_books()
17+
books_messages.Book(**x.model_dump())
18+
for x in await book_service.list_books()
1819
]
1920
)

http_app/routes/api/books.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from fastapi import APIRouter, status
2-
from pydantic import BaseModel
2+
from pydantic import BaseModel, ConfigDict
33

44
from domains.books import Book, BookData, BookService
55

@@ -9,28 +9,29 @@
99

1010
class CreateBookResponse(BaseModel):
1111
book: Book
12-
13-
class Config:
14-
schema_extra = {
12+
model_config = ConfigDict(
13+
json_schema_extra={
1514
"example": {
1615
"title": "The Hitchhiker's Guide to the Galaxy",
1716
"author_name": "Douglas Adams",
1817
"book_id": 123,
1918
}
2019
}
20+
)
2121

2222

2323
class CreateBookRequest(BaseModel):
2424
title: str
2525
author_name: str
2626

27-
class Config:
28-
schema_extra = {
27+
model_config = ConfigDict(
28+
json_schema_extra={
2929
"example": {
3030
"title": "The Hitchhiker's Guide to the Galaxy",
3131
"author_name": "Douglas Adams",
3232
}
3333
}
34+
)
3435

3536

3637
"""
@@ -49,7 +50,9 @@ async def create_book(
4950
data: CreateBookRequest,
5051
) -> CreateBookResponse:
5152
book_service = BookService()
52-
created_book = await book_service.create_book(book=BookData(**data.dict()))
53+
created_book = await book_service.create_book(
54+
book=BookData.model_validate(data, from_attributes=True)
55+
)
5356
return CreateBookResponse(book=created_book)
5457

5558

@@ -59,5 +62,7 @@ async def create_book_v2(
5962
some_optional_query_param: bool = False,
6063
) -> CreateBookResponse:
6164
book_service = BookService()
62-
created_book = await book_service.create_book(book=BookData(**data.dict()))
65+
created_book = await book_service.create_book(
66+
book=BookData.model_validate(data, from_attributes=True)
67+
)
6368
return CreateBookResponse(book=created_book)

http_app/routes/graphql/resolvers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
async def list_books():
55
book_service = BookService()
66
books = await book_service.list_books()
7-
return [Book(**x.dict()) for x in books]
7+
return [Book.model_validate(x, from_attributes=True) for x in books]

http_app/routes/ping.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
from fastapi import APIRouter
2-
from pydantic import BaseModel
2+
from pydantic import BaseModel, ConfigDict
33

44
router = APIRouter()
55

66

77
class PingResponse(BaseModel):
88
ping: str
99

10-
class Config:
11-
schema_extra = {
10+
model_config = ConfigDict(
11+
json_schema_extra={
1212
"example": {
1313
"ping": "pong!",
1414
}
1515
}
16+
)
1617

1718

18-
@router.get("/ping", response_model=PingResponse)
19+
@router.get("/ping")
1920
async def ping() -> PingResponse:
2021
return PingResponse(ping="pong!")

0 commit comments

Comments
 (0)