
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
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.
Modele baz danych: Kluczowe rodzaje i ich zrozumienie
Zrozumienie różnych modeli baz danych to podstawa dla każdego specjalisty IT. Wśród nich wyróżniamy modele relacyjne, obiektowe, hierarchiczne, sieciowe i inne. Każdy z nich ma swoje unikalne cechy i zastosowania. W niniejszym artykule przyjrzymy się najważniejszym typom baz danych, by lepiej zrozumieć ich rolę i funkcjonowanie w świecie informatyki.
Backend-as-a-Service (BaaS): Co to jest i jakie są główne zalety korzystania z tego modelu usługowego?
Backend-as-a-Service, czyli BaaS, to model usługowy zdobywający powoli coraz większe uznanie w świecie IT. Dlaczego? Ponieważ pozwala na szybszą i tańszą realizację projektów związanych z tworzeniem aplikacji webowych i mobilnych. W tym artykule przyjrzymy się definicji BaaS oraz kluczowym korzyściom wynikającym z jego zastosowania.
Data Definition Language: Co to jest i jak go używać?
Data Definition Language (DDL) to część języka SQL, który jest nieodłącznym elementem w strukturze danych. W naszym przewodniku omówimy dokładniej, czym jest DDL, jakie posiada składniki oraz na przykładach pokażemy jego praktyczne zastosowanie. Zapraszamy do lektury!
Data Manipulation Language: Klucz do zrozumienia manipulacji danymi
Technologia ewoluuje w zawrotnym tempie, a sukces w świecie IT zależy od ciągłego rozwijania umiejętności. Jednym z kluczy do opanowania dziedziny baz danych jest zrozumienie języka manipulacji danymi (DML). DML pozwala na efektywne zarządzanie danymi przechowywanymi w relacyjnych bazach danych. Ta wiedza jest nieoceniona zarówno dla nowicjuszy jak i doświadczonych programistów.
Architektura mikroserwisowa: Przyszłość tworzenia i zarządzania aplikacjami
Architektura mikroserwisowa staje się nowym standardem w budowie i zarządzaniu aplikacjami. Pozwalając na podzielenie całego systemu na mniejsze, niezależne serwisy, ułatwia naszą pracę, podnosi wydajność i skalowalność. Czy to oznacza, że mikroserwisy są przyszłością IT? Przyjrzyjmy się bliżej tej koncepcji.





