
Czym jest Pydantic?
Pydantic to biblioteka dla języka Python, która pozwala na szybkie i łatwe tworzenie modeli danych z walidacją danych. Pydantic jest oparty na popularnej bibliotece Python - dataclasses i pozwala na definiowanie modeli danych jako klasy Python,
CEO
30 cze 2022
Jednym ze sposobów przechowywania zorganizowanych danych w Pythonie są klasy. Można użyć normalnej klasy z metodą __init__, można też tworzyć modele za pomocą wbudowanych modułów Pythona, takich jak dataclasses. Jednak jedną z bardziej rozbudowanych i wygodniejszych opcji jest biblioteka Pydantic. Umożliwia ona modelowanie, walidację i modyfikowanie danych w bardzo wygodny sposób. Spójrzmy na praktyczny przykład - załóżmy, że chcemy stworzyć zwykłą to-do listę. Będziemy potrzebować modelu ListItem i modelu samej listy, nazwijmy go ToDoList. ListItem powinien mieć treść i flagę mówiącą, czy task jest skończony, czy nie. ToDoList powinna mieć nazwę i listę obiektów klasy ListItem jako membera. W vanilla Pythonie wygląda to tak:
class ListItem:
def __init__(self, content: str, done: bool = False):
self.content = content
self.done = done
class ToDoList:
def __init__(self, name: str, items: typing.List[ListItem]):
self.name = name
self.items = items
Problem pojawia się już na samym początku, mianowicie tu:
list_item1 = ListItem(123, False)
Jak możemy zabezpieczyć naszą klasę przed złym typem atrybutu, który może być zagrożeniem przy zapisie danych do bazy lub wprowadzaniu danych od strony użytkownika?
Mamy taką opcję:
def __init__(self, content: str, done: bool = False):
if not isinstance(content, str):
raise Exception("Wrong type of content")
self.content = content
self.done = done
Z naszego kodu w tym momencie zaczyna robić się niezłe spaghetti. Zabezpieczenie w ten sposób każdej klasy będzie niepraktyczne, pracochłonne i podatne na błędy. Jest jeszcze jeden problem:
print(list_item1) # <__main__.ListItem object at 0x7f641ca7d4c0>
Nie mamy szybkiego dostępu do zawartości naszej klasy w razie potrzeby sprawdzenia jej printem podczas modyfikacji lub “testowania” naszego kodu. Zawsze możemy dodać metodę __repr__, która zmieni reprezentację obiektu, jednak są to kolejne linijki kodu do napisania. Te problemy rozwiązuje Pydantic. Zobaczmy jak wygląda nasz kod po konwersji na Pydantic:
from pydantic import BaseModel
import typing
class ListItem(BaseModel):
content: str
done: bool = False
class ToDoList(BaseModel):
name: str
items: typing.List[ListItem]
A teraz spójrzmy jak zachowuje się nasza klasa w kwestii walidacji i reprezentacji:
list_item1 = ListItem(content=123, done=True)
print(list_item) # ListItem(content='123', done=True)
Pydantic przekonwertuje typ atrybutu, jeśli jest to możliwe, lub wyrzuci nam wyjątek, jeśli nie ma możliwości konwersji. Dodatkowo od razu otrzymujemy czytelną i pełną informacji reprezentację instancji. Dostajemy także wygodny sposób tworzenia słownika z danych naszej instancji poprzez metodę .dict(). A co jeśli chcemy dokonać bardziej złożonej walidacji? Załóżmy, że mamy klasę reprezentującą człowieka, która przechowuje numer PESEL. Dla uproszczenia przyjmijmy, że mamy funkcję sprawdzającą liczbę kontrolną numeru PESEL, zwracającą True lub False:
from pydantic import BaseModel, validator
class Human(BaseModel):
pesel: int
@validator('pesel')
def validate_pesel(cls, v):
if is_control_number_valid(v) is False:
raise ValueError('Given PESEL number is invalid')
return v
W argumencie v dostajemy wartość numeru PESEL już po konwersji typów (tworzenie modeli zachodzi od dołu do góry struktury danych), w razie nieprawidłowości wyrzucamy ValueError, który zostaje przekonwertowany przez Pydantic na pydantic.ValidationError. Możemy w tym miejscu sprawdzić długość stringa, lub znak liczby całkowitej. Można także modyfikować opcje walidacji, takie jak walidacja przy przypisaniu wartości czy zastosowanie walidacji dla każdego elementu, jeśli pole jest kolekcją. Dostęp do pozostałych wartości przekazanych do instancji, możemy otrzymać poprzez argument values funkcji walidującej.
Warto również wspomnieć, że Pydantic jest natywnie wspierany przez framework webowy FastAPI, co pozwala na łatwą walidację wartości przesyłanych do endpointów typu POST i PUT, oraz jasne i sztywne określenie struktury danych zwracanych przez endpointy typu GET.
Podsumowując, Pydantic jest świetną biblioteką do modelowania klas, ułatwiającą pisanie czystego, prostego i przede wszystkim działającego kodu, która oferuje masę niezwykle przydatnych funkcjonalności.
Powiązane case studies


Marketplace premium kosmetyków na 9 rynkach europejskich - Shopify Plus
Klient: Baza Cosmetics

Platforma edukacyjna generująca materiały do nauki programowania z ChatGPT
Klient: Klient (Aplikacja webowa do nauki programowania)
Branża: Edukacja / EdTech
FAQ
FAQ – najczęstsze pytania o Pydantic
Pydantic to biblioteka Pythona służąca do modelowania, walidacji i modyfikowania danych. Pozwala definiować klasy danych na podstawie BaseModel, w których każde pole ma określony typ. Pydantic automatycznie waliduje wartości przekazywane do instancji – konwertuje typy, jeśli to możliwe, lub rzuca pydantic.ValidationError, gdy konwersja jest niemożliwa. Eliminuje potrzebę ręcznego pisania kodu walidującego w __init__.
W zwykłej klasie z __init__ trzeba ręcznie sprawdzać typy każdego atrybutu (`if not isinstance(content, str): raise Exception`), co prowadzi do spaghetti i jest pracochłonne. Domyślne repr (`<__main__.ListItem object at 0x7f...>`) jest nieczytelne. Pydantic rozwiązuje oba problemy – waliduje typy automatycznie i dostarcza czytelną reprezentację instancji, np. `ListItem(content='123', done=True)`.
Gdy do pola Pydantic przekazana jest wartość niezgodna z deklarowanym typem, biblioteka próbuje ją skonwertować. Na przykład `ListItem(content=123, done=True)` zostanie zapisane jako `ListItem(content='123', done=True)` – int automatycznie zamienia się w str. Jeśli konwersja jest niemożliwa, Pydantic zgłasza wyjątek. Dzięki temu zabezpieczenie przed niewłaściwymi typami danych nie wymaga ręcznego kodu w klasie.
Do bardziej złożonej walidacji służy dekorator @validator. Przykład: dla klasy `Human(BaseModel)` z polem `pesel: int` można dodać metodę z `@validator('pesel')`, która sprawdza liczbę kontrolną i rzuca ValueError, jeśli numer jest nieprawidłowy. Pydantic konwertuje ValueError na pydantic.ValidationError. Można też uzyskać dostęp do pozostałych wartości instancji przez argument `values` funkcji walidującej.
Pydantic jest natywnie wspierany przez framework webowy FastAPI. Pozwala to na łatwą walidację wartości przesyłanych do endpointów typu POST i PUT – jeśli żądanie nie pasuje do modelu, FastAPI automatycznie zwraca błąd walidacji. Pydantic umożliwia też jasne i sztywne określenie struktury danych zwracanych przez endpointy typu GET, dzięki czemu API jest dobrze udokumentowane i przewidywalne.
Pydantic dostarcza wygodną metodę .dict(), która zwraca słownik z danych instancji modelu. Pozwala to łatwo serializować obiekty do formatów takich jak JSON, zapisywać do bazy danych lub przesyłać przez API. Można też modyfikować opcje walidacji, takie jak walidacja przy przypisaniu wartości (validate_assignment) czy stosowanie walidacji dla każdego elementu, jeśli pole jest kolekcją.
Blog
Powiązane artykuły
GraalVM: Rewolucja w świecie wirtualnych maszyn
GraalVM wprowadza przełom w świecie wirtualnych maszyn, oferując wyjątkową uniwersalność i wydajność. Zaprojektowany z myślą o współczesnych wymaganiach programistycznych, umożliwia uruchamianie kodu napisanego w wielu językach, w tym Java, JavaScript, Python, i innych, na jednej platformie.
GRPC: kiedy i dlaczego warto używać?
gRPC to nowoczesny, otwartoźródłowy framework zdalnego wywoływania procedur, który zdobywa coraz szersze uznanie wśród deweloperów. Ten artykuł wyjaśni kluczowe przewagi gRPC, omówi sytuacje, w której jego zastosowanie może okazać się szczególnie korzystne i przedstawi istotne aspekty pracy z tą technologią.
Headless CMS - lista popularnych technologii
W ostatnim czasie coraz więcej firm decyduje się na wykorzystanie technologii Headless CMS. Jest to spowodowane coraz większym zapotrzebowaniem na elastyczność i możliwość tworzenia aplikacji internetowych, które będą dostosowane do indywidualnych potrzeb użytkownika.
Czym jest HTTP 301 i kiedy warto go użyć?
HTTP 301 to status kodu, który informuje przeglądarkę oraz wyszukiwarki, że zasób, którego dotyczy żądanie, został przeniesiony na stałe do nowego adresu URL. Oznacza to, że zasób już nie jest dostępny pod starym adresem URL, a wszystkie przyszłe żądania powinny kierować do nowego adresu.
Co to jest Joomla i jakie daje możliwości?
Joomla to popularny system zarządzania treścią (CMS), który pozwala na łatwe tworzenie i zarządzanie witrynami internetowymi. Jest to otwarty i darmowy system, który jest dostępny dla każdego, kto chce stworzyć profesjonalną stronę internetową.
Assembler - niskopoziomowy język programowania
Assembler to niskopoziomowy język programowania, który umożliwia bezpośrednie manipulowanie sprzętem komputera. Choć coraz rzadziej używany, wciąż stanowi cenną umiejętność dla programistów zajmujących się optymalizacją lub tworzeniem oprogramowania wbudowanego.





