From e2f936cba12dbcf8a026bcd9bf30d43351017cb4 Mon Sep 17 00:00:00 2001 From: devsmish Date: Sun, 26 Apr 2026 11:26:07 +0200 Subject: [PATCH 1/6] add homework2 for pydantic --- HWs/Sergey/homework2/homework02.py | 127 +++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 HWs/Sergey/homework2/homework02.py diff --git a/HWs/Sergey/homework2/homework02.py b/HWs/Sergey/homework2/homework02.py new file mode 100644 index 0000000..5cf4218 --- /dev/null +++ b/HWs/Sergey/homework2/homework02.py @@ -0,0 +1,127 @@ +'''Разработать систему регистрации пользователя, используя Pydantic для валидации входных данных, обработки +вложенных структур и сериализации. Система должна обрабатывать данные в формате JSON. + +Задачи: +1. Создать классы моделей данных с помощью Pydantic для пользователя и его адреса. +2. Реализовать функцию, которая принимает JSON строку, десериализует её в объекты Pydantic, валидирует данные, и в +случае успеха сериализует объект обратно в JSON и возвращает его. +3. Добавить кастомный валидатор для проверки соответствия возраста и статуса занятости пользователя. +4. Написать несколько примеров JSON строк для проверки различных сценариев валидации: успешные регистрации и случаи, +когда валидация не проходит (например возраст не соответствует статусу занятости). + +Модели: +Address: Должен содержать следующие поля: +city: строка, минимум 2 символа. +street: строка, минимум 3 символа. +house_number: число, должно быть положительным. + +User: Должен содержать следующие поля: +name: строка, должна быть только из букв, минимум 2 символа. +age: число, должно быть между 0 и 120. +email: строка, должна соответствовать формату email. +is_employed: булево значение, статус занятости пользователя. +address: вложенная модель адреса. + +Валидация: +Проверка, что если пользователь указывает, что он занят (is_employed = true), его возраст должен быть от 18 до 65 +лет. + +# Пример JSON данных для регистрации пользователя +json_input = """{ + "name": "John Doe", + "age": 70, + "email": "john.doe@example.com", + "is_employed": true, + "address": { + "city": "New York", + "street": "5th Avenue", + "house_number": 123 + } + }""" +''' + +from pydantic import BaseModel, ValidationError, Field, EmailStr, model_validator + + +class Address(BaseModel): + city: str = Field(min_length=2, description='Min length 2 characters') + street: str = Field(min_length=3, description='Min length 3 characters') + house_number: int = Field(gt=0, description='Always positive integer') + +class User(BaseModel): + name: str = Field(..., pattern=r'^[a-zA-Zа-яА-Я -]+$', min_length=2, description='Only letters and min 2 characters') + age: int = Field(..., gt=0, le=120, description='Between 0 and 120') + email: EmailStr = Field(description='Email address format') + is_employed: bool = Field(...) + address: Address + + @model_validator(mode='after') + def check_is_employed(self): + if self.is_employed and not (18 <= self.age <= 65): + raise ValueError("If user is employed, age must be between 18 and 65") + return self + +def data_validator(data): + try: + user = User.model_validate_json(data, strict=True) + return user.model_dump_json() + except ValidationError as err: + print("Validation error:", err.json()) + # except ValueError as err: + # print("ValueError error:", err) + +if __name__ == '__main__': + # valid + # json_input = """{ + # "name": "John Doe", + # "age": 70, + # "email": "john.doe@example.com", + # "is_employed": true, + # "address": { + # "city": "New York", + # "street": "5th Avenue", + # "house_number": 123 + # } + # }""" + + json_input = """{ + "name": "Michael Johnson", + "age": 52, + "email": "mjohnson@gmail.com", + "is_employed": false, + "address": { + "city": "New York", + "street": "7th Avenue", + "house_number": 25 + } + }""" + print('User registration is successful') + print(data_validator(json_input)) + + # invalid email and house_number + # json_input = """{ + # "name": "Barak Obama", + # "age": 61, + # "email": "@icloud.co", + # "is_employed": false, + # "address": { + # "city": "Washington", + # "street": "1", + # "house_number": "12a" + # } + # }""" + + # invalid age + json_invalid = """{ + "name": "Timbuktu", + "age": 70, + "email": "tb@icloud.com", + "is_employed": true, + "address": { + "city": "Boston", + "street": "Baker Street", + "house_number": 124 + } + }""" + print('User registration is not successful') + print(data_validator(json_invalid)) From b547b879c7472953e0d4a5c884b0259d36b1c73c Mon Sep 17 00:00:00 2001 From: devsmish Date: Sun, 26 Apr 2026 23:09:22 +0200 Subject: [PATCH 2/6] PEP8 --- HWs/Sergey/homework2/homework02.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/HWs/Sergey/homework2/homework02.py b/HWs/Sergey/homework2/homework02.py index 5cf4218..83d4476 100644 --- a/HWs/Sergey/homework2/homework02.py +++ b/HWs/Sergey/homework2/homework02.py @@ -48,6 +48,7 @@ class Address(BaseModel): street: str = Field(min_length=3, description='Min length 3 characters') house_number: int = Field(gt=0, description='Always positive integer') + class User(BaseModel): name: str = Field(..., pattern=r'^[a-zA-Zа-яА-Я -]+$', min_length=2, description='Only letters and min 2 characters') age: int = Field(..., gt=0, le=120, description='Between 0 and 120') @@ -55,12 +56,14 @@ class User(BaseModel): is_employed: bool = Field(...) address: Address + @model_validator(mode='after') def check_is_employed(self): if self.is_employed and not (18 <= self.age <= 65): raise ValueError("If user is employed, age must be between 18 and 65") return self + def data_validator(data): try: user = User.model_validate_json(data, strict=True) @@ -70,6 +73,7 @@ def data_validator(data): # except ValueError as err: # print("ValueError error:", err) + if __name__ == '__main__': # valid # json_input = """{ From afa7d360daaa9593477819323e006f2405e2714d Mon Sep 17 00:00:00 2001 From: Serhii Date: Tue, 28 Apr 2026 19:33:32 +0200 Subject: [PATCH 3/6] Update HWs/Sergey/homework2/homework02.py Co-authored-by: Danil <49741194+samodurOFF@users.noreply.github.com> --- HWs/Sergey/homework2/homework02.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HWs/Sergey/homework2/homework02.py b/HWs/Sergey/homework2/homework02.py index 83d4476..825396f 100644 --- a/HWs/Sergey/homework2/homework02.py +++ b/HWs/Sergey/homework2/homework02.py @@ -50,7 +50,7 @@ class Address(BaseModel): class User(BaseModel): - name: str = Field(..., pattern=r'^[a-zA-Zа-яА-Я -]+$', min_length=2, description='Only letters and min 2 characters') + name: str = Field(pattern=r'^[a-zA-Zа-яА-Я -]+$', min_length=2, description='Only letters and min 2 characters') age: int = Field(..., gt=0, le=120, description='Between 0 and 120') email: EmailStr = Field(description='Email address format') is_employed: bool = Field(...) From 1ca42531ffb595da47fb39fd34210a35009a85bd Mon Sep 17 00:00:00 2001 From: Serhii Date: Tue, 28 Apr 2026 19:34:12 +0200 Subject: [PATCH 4/6] Update HWs/Sergey/homework2/homework02.py Co-authored-by: Danil <49741194+samodurOFF@users.noreply.github.com> --- HWs/Sergey/homework2/homework02.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HWs/Sergey/homework2/homework02.py b/HWs/Sergey/homework2/homework02.py index 825396f..ff3d1a7 100644 --- a/HWs/Sergey/homework2/homework02.py +++ b/HWs/Sergey/homework2/homework02.py @@ -69,7 +69,7 @@ def data_validator(data): user = User.model_validate_json(data, strict=True) return user.model_dump_json() except ValidationError as err: - print("Validation error:", err.json()) + return err.json() # except ValueError as err: # print("ValueError error:", err) From e3dff2936db426d58cb18e1ad8af784941290b27 Mon Sep 17 00:00:00 2001 From: devsmish Date: Wed, 29 Apr 2026 12:06:54 +0200 Subject: [PATCH 5/6] refactor: remove unnecessary Field usage --- HWs/Sergey/homework2/homework02.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HWs/Sergey/homework2/homework02.py b/HWs/Sergey/homework2/homework02.py index 83d4476..124ffa9 100644 --- a/HWs/Sergey/homework2/homework02.py +++ b/HWs/Sergey/homework2/homework02.py @@ -50,10 +50,10 @@ class Address(BaseModel): class User(BaseModel): - name: str = Field(..., pattern=r'^[a-zA-Zа-яА-Я -]+$', min_length=2, description='Only letters and min 2 characters') - age: int = Field(..., gt=0, le=120, description='Between 0 and 120') + name: str = Field(pattern=r'^[a-zA-Zа-яА-Я -]+$', min_length=2, description='Only letters and min 2 characters') + age: int = Field(gt=0, le=120, description='Between 0 and 120') email: EmailStr = Field(description='Email address format') - is_employed: bool = Field(...) + is_employed: bool address: Address From d2edefe40678a8944853f897489c76d1d92cc127 Mon Sep 17 00:00:00 2001 From: devsmish Date: Wed, 29 Apr 2026 12:19:15 +0200 Subject: [PATCH 6/6] refactor: remove unnecessary Field usage --- HWs/Sergey/homework2/homework02.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HWs/Sergey/homework2/homework02.py b/HWs/Sergey/homework2/homework02.py index ff3d1a7..b183442 100644 --- a/HWs/Sergey/homework2/homework02.py +++ b/HWs/Sergey/homework2/homework02.py @@ -51,9 +51,9 @@ class Address(BaseModel): class User(BaseModel): name: str = Field(pattern=r'^[a-zA-Zа-яА-Я -]+$', min_length=2, description='Only letters and min 2 characters') - age: int = Field(..., gt=0, le=120, description='Between 0 and 120') + age: int = Field(gt=0, le=120, description='Between 0 and 120') email: EmailStr = Field(description='Email address format') - is_employed: bool = Field(...) + is_employed: bool address: Address