Herzlich willkommen zu meinem ersten TechUp! Ich freue mich, euch heute ein cooles Modul vorzustellen: Pydantic. 🎉
In meinem ersten TechUp geht es um Pydantic. Jeder Programmierer kennt diesen Moment: Plötzlich wirft eine Funktion einen Fehler, weil der Typ der übergebenen Daten nicht korrekt ist. Um dieses Problem zu adressieren, wurde Pydantic entwickelt. Heute werde ich euch dieses Modul vorstellen und zeigen, wie es auf unterschiedliche Weise Lösungen bietet. Falls du das Repository sehen möchtest, findest du es hier: https://github.com/b-nova-techhub/pydantic
Zusammenfassend bietet Pydantic folgende Features, die ich mit euch durchgehen werde:
- Empfehlungen
- Validation
- Serialisierung
- JSON Schema
- Eigene Typen Erstellung
Aber halt! Bevor wir starten, lass mich dir noch ein paar wichtige Eckdaten über Pydantic geben.
Eckdaten
Zuerst kommen wir zu paar Details über Pydantic.😀 Samuel Colvin ist der Gründer von Pydantic. Das Ziel vom Pydantic Python Modul ist die Typisierung zu vereinfachen. Wenn die Daten fehlen oder inkorrekt sind, erzeugt Pydantic Validierungsfehler. Das ist optimal für grössere Firmen die auf eine saubere Datenstruktur angewiesen sind. Der Kern von Pydantic ist in Rust geschrieben. Das bedeutet, dass wir richtig viel Power⚡️ unter der Haube haben und die Sache schnell läuft. Darüber hinaus verfügt Pydantic über eine grosse Community und wird von führenden Unternehmen wie Microsoft und Netflix verwendet. Nicht nur das – Pydantic ist auch Open Source und existiert bereits seit 2018.
Installation
Die installation von Pydantic ist so einfach wie es aussieht. Zuerst führst du folgenden Befehl aus:
|
|
Damit die Features von Pydantic richtig funktionieren, empfehle ich dir auch noch das IntelliJ Plugin Pydantic zu installieren.
Damit hast du Pydantic installiert und kannst loslegen. 🎉🎉🎉
Basic Model
Nach der Installation von Pydantic können wir mit dem ersten Schritt beginnen. Wir erstellen ein Base Model. In unserem Beispiel verwenden wir User als Objekt.
|
|
Beim Basic Modell definieren wir ganz einfach die Struktur der Daten. Danach können wir in anderen Files die Typen verwenden.
In unserem Fall haben wir ein Modell User
mit den Typen str
int
und bool
erstellt.
Bei Aufruf des User-Objekts mit zwei Parametern, die nicht im Basismodell definiert sind, erhalten wir folgenden Output:
Wie du in der Abbildung erkennen kannst, markiert Pydantic die undefinierten Typen in unserem Fall – hier filepath – gelb. Selbst wenn du alle Typen definiert hast, funktioniert das Programm beim Ausführen dennoch und der fehlende Typ wird ignoriert.
Auch empfiehlt mir Pydantic die Verwendung der zwei Parameter die ich komischerweise vergessen habe 😄 is_active und is_admin. Dies macht es viel einfacher, die erforderlichen Parameter zu setzen. Zudem wird eine Exception ausgelöst, wenn ein Parameter fehlt. (Was bei Dataclasses nicht der Fall wäre.) Wichtig ist, dass du das entsprechende Plugin installiert hast, denn ohne dieses hat das Feature anfangs nicht funktioniert.
Der grösste Vorteil von Pydantic besteht darin, dass Typenfehler automatisch erkannt werden: Wenn wir beispielsweise name
in unserem speziellen Fall als Integer definieren, obwohl es im BaseModel als String festgelegt wurde, wird eine Exception ausgelöst.
Dies kannst du auch im Bild sehen.
Nicht nur die Einfachheit von Pydantic ist beeindruckend, sondern auch die Vielfalt der angebotenen Typen, die Dataclasses nicht zur Verfügung stellen. Auf der Webseite https://docs.pydantic.dev/1.10/usage/types/ kannst du dir alle verfügbaren Typen ansehen. In meinem Beitrag werde ich speziell die Typen Email und FilePath vorstellen.
Für die Validierung von E-Mails muss zusätzlich ein weiteres Modul installiert werden.
|
|
Danach kannst du einfach in den Imports EmailStr und FilPath verwenden.
|
|
Bei einer Mail die nicht korrekt ist, wird ein Fehler geworfen. Auch wenn der FilePath nicht existiert wird ein Fehler geworfen. Das ist wirklich sehr angenehm. Das gleiche gilt auch für die anderen Typen die Pydantic anbietet.
EmailStr
FilePath
Output bei erfolgreicher Validierung
Wurden alle Typen richtig definiert, werden die Daten in einem Dictionary ausgegeben.
JSON Schema
Willst du deinen Output in JSON Format so gibt es auch eine Möglichkeit dazu mit Pydantic.
Dazu fügst du einfach dein Model und model_json.schema()
hinzu. siehe unten.
In meinem Fall printe ich das JSON direkt aus.
|
|
Eigene Typen erstellen
Möchtest du ein eigenen Typ definieren bietet Pydantic auch die Möglichkeit dazu.
Dafür musst du einfach zuerst from typing import Annotated
importieren.
Danach kannst du mit Annotated
deinen eigenen Typen erstellen. Leider ist auf Website der Import falsch und deshalb empfehle ich die Github Repos anzuschauen um sicherzustellen das ihr es richtig macht.
Zum Beispiel ist Annotated[int, Field(gt=0)]
veraltet. Stattdessen sollte Annotated[int, (Gt(0)]
verwendet werden.
https://github.com/annotated-types/annotated-types Mit Gt wird definiert, dass nur Zahlen die grösser als die definierte Zahl also in unserem Fall 0 akzeptiert werden. Damit wir auch eine Exception erhalten muss ein ValidationError hinzugefügt werden. Durch den TypeAdapter wird der Typ in das Modell eingefügt und benutzbar. Wie in dem folgenden Code ersichtlich ist.
|
|
Durch das Erstellen des eigenen Typs haben wir jetzt ein positivInt erstellt. Dieser Typ akzeptiert nur Zahlen die grösser als 0 sind. Optimal für ein E-Commerce Projekt, bei welchem die Anzahl der Produkte nicht kleiner als 0 sein darf 🎉🙂 .
Eigeneerstellte Typ Ausgabe
In meinem Beispiel habe ich bought=0 definiert. Da 0 nicht grösser als 0 ist, wird ein Fehler geworfen. Ist die Zahl höher als 0 wird die Ausgabe wie gewohnt ausgegeben.
|
|
Dataclass Modifikationen
Hast du dein Projekt schon mit Dataclasses aufgebaut willst aber Features von Pydantic nutzen? Dafür bietet Pydantic mit einem Wrapper um Dataclasses die Möglichkeit dazu.
Um das zu erstellen musst du einfach from pydantic.dataclasses import dataclass
importieren.
Danach kannst du einfach @dataclass
über deine Dataclasses schreiben und schon hast du manche Features von Pydantic.
Natürlich bietet das Basemodel von Pydantic selber mehr Features als Dataclasses. Deshalb empfehle ich die Verwendung von Pydantic Modellen.
Jedoch ist es eine gute Möglichkeit Validierungen in bestehende Projekte zu integrieren.
Hier ein Beispiel ohne Pydantic :)
|
|
Hier ein Beispiel mit Pydantic als Wrapper. Mit Pydantic dazu hat man den Vorteil der Validierung. Auch kannst du zum Beispiel den Typ EmailStr durch ein Import verwenden. Alles ersichtlich im folgenden Code. Der grosse Vorteil ist darin, dass du dann auch Validierungsfehler erhältst.
|
|
Warum Pydantic und nicht Dataclasses?
Wenn du an einem grossen Projekt arbeitest oder Typen wie Email, Filepath oder andere gerne nutzen möchtest, empfehle ich dir Pydantic zu verwenden. Auch kannst du wie ich dir im Techup gezeigt habe einen JSON Output erzeugen was natürlich für manche Projekte sehr nützlich ist. Bei Dataclasses müsstest du die Validierung selber schreiben. In Pydantic passiert das automatisch.
Fazit
Mein Fazit zu Pydantic ist, dass es ein sehr gutes Modul ist. Es ist einfach zu verwenden, hat eine grosse Tech-Gemeinschaft und bietet viele Typen an. Wichtig ist, dass man sich vor allem in Github für die Dokumentation orientiert. Auf der Website sind manche Sachen falsch oder funktionieren nicht so, wie sie angegeben sind. Falls ihr ein grösseres Projekt habt wird es sicherlich ein sehr gutes Tool zur Typisierung und Validierung sein.
Ich hoffe, dass ich dir mit meinem Techup weiterhelfen konnte und wünsche dir viel Spass beim Programmieren mit Pydantic. :) Wenn dich weitere Details zu Pydantic interessieren, so lass es mich wissen :) Falls du Fragen hast, melde dich einfach!