├── 6_serialization.py ├── 4_computed_fields.py ├── 5_nested_models.py ├── 3_model_validator.py ├── 1_pydantic_why.py └── 2_field_validator.py /6_serialization.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | class Address(BaseModel): 4 | 5 | city: str 6 | state: str 7 | pin: str 8 | 9 | class Patient(BaseModel): 10 | 11 | name: str 12 | gender: str = 'Male' 13 | age: int 14 | address: Address 15 | 16 | address_dict = {'city': 'gurgaon', 'state': 'haryana', 'pin': '122001'} 17 | 18 | address1 = Address(**address_dict) 19 | 20 | patient_dict = {'name': 'nitish', 'age': 35, 'address': address1} 21 | 22 | patient1 = Patient(**patient_dict) 23 | 24 | temp = patient1.model_dump(exclude_unset=True) 25 | 26 | print(temp) 27 | print(type(temp)) 28 | -------------------------------------------------------------------------------- /4_computed_fields.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, EmailStr, computed_field 2 | from typing import List, Dict 3 | 4 | class Patient(BaseModel): 5 | 6 | name: str 7 | email: EmailStr 8 | age: int 9 | weight: float # kg 10 | height: float # mtr 11 | married: bool 12 | allergies: List[str] 13 | contact_details: Dict[str, str] 14 | 15 | @computed_field 16 | @property 17 | def bmi(self) -> float: 18 | bmi = round(self.weight/(self.height**2),2) 19 | return bmi 20 | 21 | 22 | 23 | def update_patient_data(patient: Patient): 24 | 25 | print(patient.name) 26 | print(patient.age) 27 | print(patient.allergies) 28 | print(patient.married) 29 | print('BMI', patient.bmi) 30 | print('updated') 31 | 32 | patient_info = {'name':'nitish', 'email':'abc@icici.com', 'age': '65', 'weight': 75.2, 'height': 1.72, 'married': True, 'allergies': ['pollen', 'dust'], 'contact_details':{'phone':'2353462', 'emergency':'235236'}} 33 | 34 | patient1 = Patient(**patient_info) 35 | 36 | update_patient_data(patient1) 37 | -------------------------------------------------------------------------------- /5_nested_models.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | class Address(BaseModel): 4 | 5 | city: str 6 | state: str 7 | pin: str 8 | 9 | class Patient(BaseModel): 10 | 11 | name: str 12 | gender: str 13 | age: int 14 | address: Address 15 | 16 | address_dict = {'city': 'gurgaon', 'state': 'haryana', 'pin': '122001'} 17 | 18 | address1 = Address(**address_dict) 19 | 20 | patient_dict = {'name': 'nitish', 'gender': 'male', 'age': 35, 'address': address1} 21 | 22 | patient1 = Patient(**patient_dict) 23 | 24 | temp = patient1.model_dump(include=) 25 | 26 | print(type(temp)) 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | # Better organization of related data (e.g., vitals, address, insurance) 51 | 52 | # Reusability: Use Vitals in multiple models (e.g., Patient, MedicalRecord) 53 | 54 | # Readability: Easier for developers and API consumers to understand 55 | 56 | # Validation: Nested models are validated automatically—no extra work needed 57 | -------------------------------------------------------------------------------- /3_model_validator.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, EmailStr, model_validator 2 | from typing import List, Dict 3 | 4 | class Patient(BaseModel): 5 | 6 | name: str 7 | email: EmailStr 8 | age: int 9 | weight: float 10 | married: bool 11 | allergies: List[str] 12 | contact_details: Dict[str, str] 13 | 14 | @model_validator(mode='after') 15 | def validate_emergency_contact(cls, model): 16 | if model.age > 60 and 'emergency' not in model.contact_details: 17 | raise ValueError('Patients older than 60 must have an emergency contact') 18 | return model 19 | 20 | 21 | 22 | def update_patient_data(patient: Patient): 23 | 24 | print(patient.name) 25 | print(patient.age) 26 | print(patient.allergies) 27 | print(patient.married) 28 | print('updated') 29 | 30 | patient_info = {'name':'nitish', 'email':'abc@icici.com', 'age': '65', 'weight': 75.2, 'married': True, 'allergies': ['pollen', 'dust'], 'contact_details':{'phone':'2353462', 'emergency':'235236'}} 31 | 32 | patient1 = Patient(**patient_info) 33 | 34 | update_patient_data(patient1) 35 | -------------------------------------------------------------------------------- /1_pydantic_why.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, EmailStr, AnyUrl, Field 2 | from typing import List, Dict, Optional, Annotated 3 | 4 | class Patient(BaseModel): 5 | 6 | name: Annotated[str, Field(max_length=50, title='Name of the patient', description='Give the name of the patient in less than 50 chars', examples=['Nitish', 'Amit'])] 7 | email: EmailStr 8 | linkedin_url: AnyUrl 9 | age: int = Field(gt=0, lt=120) 10 | weight: Annotated[float, Field(gt=0, strict=True)] 11 | married: Annotated[bool, Field(default=None, description='Is the patient married or not')] 12 | allergies: Annotated[Optional[List[str]], Field(default=None, max_length=5)] 13 | contact_details: Dict[str, str] 14 | 15 | 16 | def update_patient_data(patient: Patient): 17 | 18 | print(patient.name) 19 | print(patient.age) 20 | print(patient.allergies) 21 | print(patient.married) 22 | print('updated') 23 | 24 | patient_info = {'name':'nitish', 'email':'abc@gmail.com', 'linkedin_url':'http://linkedin.com/1322', 'age': '30', 'weight': 75.2,'contact_details':{'phone':'2353462'}} 25 | 26 | patient1 = Patient(**patient_info) 27 | 28 | update_patient_data(patient1) 29 | -------------------------------------------------------------------------------- /2_field_validator.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, EmailStr, AnyUrl, Field, field_validator 2 | from typing import List, Dict, Optional, Annotated 3 | 4 | class Patient(BaseModel): 5 | 6 | name: str 7 | email: EmailStr 8 | age: int 9 | weight: float 10 | married: bool 11 | allergies: List[str] 12 | contact_details: Dict[str, str] 13 | 14 | @field_validator('email') 15 | @classmethod 16 | def email_validator(cls, value): 17 | 18 | valid_domains = ['hdfc.com', 'icici.com'] 19 | # abc@gmail.com 20 | domain_name = value.split('@')[-1] 21 | 22 | if domain_name not in valid_domains: 23 | raise ValueError('Not a valid domain') 24 | 25 | return value 26 | 27 | @field_validator('name') 28 | @classmethod 29 | def transform_name(cls, value): 30 | return value.upper() 31 | 32 | @field_validator('age', mode='after') 33 | @classmethod 34 | def validate_age(cls, value): 35 | if 0 < value < 100: 36 | return value 37 | else: 38 | raise ValueError('Age should be in between 0 and 100') 39 | 40 | 41 | def update_patient_data(patient: Patient): 42 | 43 | print(patient.name) 44 | print(patient.age) 45 | print(patient.allergies) 46 | print(patient.married) 47 | print('updated') 48 | 49 | patient_info = {'name':'nitish', 'email':'abc@icici.com', 'age': '30', 'weight': 75.2, 'married': True, 'allergies': ['pollen', 'dust'], 'contact_details':{'phone':'2353462'}} 50 | 51 | patient1 = Patient(**patient_info) # validation -> type coercion 52 | 53 | update_patient_data(patient1) 54 | --------------------------------------------------------------------------------