Skip to content

Commit 60b2b76

Browse files
authored
Merge pull request #52 from zezOtik/feature/borodin
Laba2 Ready
2 parents 57e19e5 + 5f45cbb commit 60b2b76

File tree

4 files changed

+117
-0
lines changed

4 files changed

+117
-0
lines changed
File renamed without changes.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
market_place_orders:
2+
- order_id: 123321
3+
user_info:
4+
user_id: 1000
5+
username: Вроде
6+
surname: Русский
7+
email: test@mail.ru
8+
status: active
9+
bio: студент
10+
url: https://folder.ru
11+
items_line:
12+
- order_id: 123321
13+
order_line_id: 1
14+
item_line:
15+
service_id: 101
16+
name: Доставка
17+
desc: Клиентская доставка
18+
price: 359.0
19+
quantity: 1.0
20+
line_price: 359.0
21+
22+
- order_id: 123321
23+
order_line_id: 2
24+
item_line:
25+
service_id: 9999
26+
name: Лампа
27+
desc: Настольная лампа
28+
price: 990.0
29+
quantity: 1.0
30+
line_price: 990.0
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import logging
2+
import yaml
3+
from pydantic import BaseModel, Field, ConfigDict, model_validator
4+
from pydantic import EmailStr, HttpUrl
5+
from typing import Literal, Union, List
6+
7+
logging.basicConfig(level=logging.INFO,
8+
format='%(asctime)s - %(levelname)s - %(message)s')
9+
RUS_RE = r'^[а-яА-ЯёЁ\s]+$'
10+
11+
12+
class UserSpec(BaseModel):
13+
user_id: int
14+
username: str = Field(..., pattern=RUS_RE)
15+
surname: str = Field(..., pattern=RUS_RE)
16+
second_name: str = Field(None, pattern=RUS_RE)
17+
email: EmailStr
18+
status: Literal['active', 'non-active']
19+
model_config = ConfigDict(extra="forbid")
20+
21+
class ProfileSpec(UserSpec):
22+
bio: str = Field(..., pattern=RUS_RE)
23+
url: HttpUrl
24+
model_config = ConfigDict(extra="forbid")
25+
26+
class ItemSpec(BaseModel):
27+
item_id: int
28+
name: str = Field(..., pattern=RUS_RE)
29+
decs: str = Field(..., pattern=RUS_RE)
30+
price: float = Field(..., gt=0)
31+
model_config = ConfigDict(extra="forbid")
32+
33+
class ServiceSpec(BaseModel):
34+
service_id: int
35+
name: str = Field(..., pattern=RUS_RE)
36+
desc: str = Field(..., pattern=RUS_RE)
37+
price: float = Field(..., gt=0)
38+
model_config = ConfigDict(extra="forbid")
39+
40+
class OrderLineSpec(BaseModel):
41+
order_id: int
42+
order_line_id: int
43+
item_line: Union[ServiceSpec, ItemSpec]
44+
quantity: float = Field(..., gt=0)
45+
line_price: float = Field(..., gt=0)
46+
47+
@model_validator(mode='after')
48+
def check_line_prices(self):
49+
check = self.quantity * self.item_line.price
50+
if self.line_price != check:
51+
raise ValueError(f'line_price{self.line_price} != '
52+
f'quantity * item_line.price{self.quantity * self.item_line.price}')
53+
return self
54+
55+
model_config = ConfigDict(extra="forbid")
56+
57+
class OrderSpec(BaseModel):
58+
order_id: int
59+
user_info: ProfileSpec
60+
items_line: List[OrderLineSpec]
61+
62+
model_config = ConfigDict(extra="forbid")
63+
64+
class OrdersSpec(BaseModel):
65+
market_place_orders: List[OrderSpec]
66+
67+
model_config = ConfigDict(extra="forbid")
68+
69+
def get_data_from_yaml(yaml_path: str) -> OrdersSpec:
70+
"""
71+
Загружает и валидирует данные из YAML-файла с использованием Pydantic.
72+
"""
73+
try:
74+
with open(yaml_path, 'r', encoding='utf-8') as f:
75+
data = yaml.safe_load(f)
76+
orders = OrdersSpec.model_validate(data)
77+
logging.info("Данные успешно загружены и валидированы.")
78+
logging.info(orders.model_dump_json(indent=2, ensure_ascii=False))
79+
return orders
80+
except yaml.YAMLError as e:
81+
logging.error(f"Ошибка при чтении YAML: {e}")
82+
raise
83+
except Exception as e:
84+
logging.error(f"Ошибка валидации данных: {e}")
85+
raise
86+
87+
orders = get_data_from_yaml("students_folder/Borodin/LabaMore1/data.yaml")

0 commit comments

Comments
 (0)