diff --git a/main.py b/main.py index 21ebb31..5372093 100644 --- a/main.py +++ b/main.py @@ -1,30 +1,54 @@ # example from root.cz # https://www.root.cz/clanky/validace-dat-v-pythonu-s-vyuzitim-knihovny-pydantic/ - -from models.User import User, UserNone, UserUnion, UserPositiveInt, UserFieldValidator, UserMaxLength +from models.address import Address +from models.character import CharacterModel, CharacterModelOptionalAddress +from models.user import User, UserNone, UserUnion, UserPositiveInt, UserFieldValidator, UserMaxLength def main(): + + # Basic validation print("Hello from pydantic-demo!") - print(f"{User(name="John", surname="Doe", age=42, registered=True)=}") - print(f"{User(name="Adam", surname="Bernau", age=52, registered=True)=}") - print(f"{UserNone(name="Adam", surname="Bernau", age=None)=}") - print(f"{UserUnion(name="Adam", surname="Bernau", age=None)=}") - print(f"{UserUnion(name="Adam", surname="Bernau")=}") - print(f"{UserPositiveInt(name="Adam", surname="Bernau")=}") - #print(f"{UserPositiveInt(name="Adam", surname="Bernau", age=-50)=}") - print(f"{UserFieldValidator(name="Adam", surname="Bernau", age=18)=}") - print(f"{UserMaxLength(name="Adam", surname="Bernau", age=18)=}") - #print(f"{UserMaxLength(name="Adam", surname="Bernaukjghsmtlmgchs", age=18)=}") + print(f"{User(name='John', surname='Doe', age=42, registered=True)=}") + print(f"{User(name='Adam', surname='Kameník', age=52, registered=True)=}") + print(f"{UserNone(name='Tomáš', surname='Macek', age=None)=}") # preferred variant + print(f"{UserUnion(name='Adam', surname='Bernau', age=None)=}") + print(f"{UserUnion(name='Adam', surname='Bernau')=}") + print(f"{UserPositiveInt(name='Adam', surname='Bernau')=}") + #print(f"{UserPositiveInt(name="Adam', surname='Bernau', age=-50)=}") + print(f"{UserFieldValidator(name='Adam', surname='Bernau', age=18)=}") + print(f"{UserMaxLength(name='Adam', surname='Bernau', age=18)=}") + #print(f"{UserMaxLength(name='Adam', surname='Bernaukjghsmtlmgchs', age=18)=}") # JSON data = """ - {"name": "John", - "surname": "Doe", - "age": 18 + {"name": "Marek", + "surname": "Kdolský", + "age": 50 } """ - print(f"{UserMaxLength.model_validate_json(data)=}") + user1 = UserMaxLength.model_validate_json(data) + print(f"{user1=}") + print(f"{user1.model_dump_json()=}") + print(user1.model_dump_json(indent=4)) + + # Nested structure and JSON + character = CharacterModel( + role='Director', + user=User(name='John', surname='Doe', age=42, registered=True), + address=Address(street='Dlouhá', house_number=77, city='Prague'), + ) + print(f"{character=}") + print(character.model_dump_json(indent=4)) + + + character1 = CharacterModelOptionalAddress( + role='Director', + user=UserFieldValidator(name='John', surname='Doe', age=19, registered=True), + # address=Address(street='Dlouhá', house_number=77, city='Prague'), + ) + print(f"Optional address {character1=}") + print(character1.model_dump_json(indent=4)) if __name__ == "__main__": main() diff --git a/models/address.py b/models/address.py new file mode 100644 index 0000000..caa48d9 --- /dev/null +++ b/models/address.py @@ -0,0 +1,9 @@ +from __future__ import annotations + +from pydantic import BaseModel + + +class Address(BaseModel): + street: str + house_number: int | str + city: str diff --git a/models/character.py b/models/character.py new file mode 100644 index 0000000..44e0ec8 --- /dev/null +++ b/models/character.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from pydantic import BaseModel + +from models.address import Address +from models.user import User, UserFieldValidator + + +class CharacterModel(BaseModel): + role: str + user: User + address: Address + +class CharacterModelOptionalAddress(BaseModel): + role: str + user: UserFieldValidator + address: Address | None = None + diff --git a/models/User.py b/models/user.py similarity index 78% rename from models/User.py rename to models/user.py index 0e014c8..f4df9f2 100644 --- a/models/User.py +++ b/models/user.py @@ -1,7 +1,7 @@ from __future__ import annotations from typing import Union, Optional -from pydantic import BaseModel, PositiveInt, field_validator, Field +from pydantic import BaseModel, PositiveInt, field_validator, Field, ValidationError class User(BaseModel): @@ -38,24 +38,28 @@ class UserPositiveInt(BaseModel): class UserFieldValidator(BaseModel): name: str surname: str - age: PositiveInt | None + age: int | None registered: bool = False @field_validator("age") def validate_age(cls, value): + if value < 0: + raise ValidationError("age must be positive") if value < 18: - raise ValueError("age must be at least 18") + raise ValidationError("age must be at least 18") return value class UserMaxLength(BaseModel): name: str = Field(..., max_length=10) - surname: str = Field(..., max_length=10) - age: PositiveInt | None + surname: str = Field(..., max_length=12) + age: int | None registered: bool = False @field_validator("age") def check_age(cls, value): + if value < 0: + raise ValidationError("age must be positive") if value < 18: raise ValueError("You are too young to register") return value