Done
This commit is contained in:
20
.gitignore
vendored
20
.gitignore
vendored
@@ -1,5 +1,21 @@
|
|||||||
# Python
|
# Python
|
||||||
|
__pycache__
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
python_parser/__pycache__/
|
||||||
|
python_parser/core/__pycache__/
|
||||||
|
python_parser/adapters/__pycache__/
|
||||||
|
python_parser/tests/__pycache__/
|
||||||
|
python_parser/tests/test_core/__pycache__/
|
||||||
|
python_parser/tests/test_adapters/__pycache__/
|
||||||
|
python_parser/tests/test_app/__pycache__/
|
||||||
|
python_parser/app/__pycache__/
|
||||||
|
python_parser/app/schemas/__pycache__/
|
||||||
|
python_parser/app/schemas/test_schemas/__pycache__/
|
||||||
|
python_parser/app/schemas/test_schemas/test_core/__pycache__/
|
||||||
|
python_parser/app/schemas/test_schemas/test_adapters/__pycache__/
|
||||||
|
python_parser/app/schemas/test_schemas/test_app/__pycache__/
|
||||||
|
|
||||||
|
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
*$py.class
|
*$py.class
|
||||||
*.so
|
*.so
|
||||||
@@ -152,4 +168,6 @@ htmlcov/
|
|||||||
node_modules/
|
node_modules/
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|
||||||
|
__pycache__/
|
||||||
|
|||||||
135
python_parser/SCHEMA_INTEGRATION.md
Normal file
135
python_parser/SCHEMA_INTEGRATION.md
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
# Интеграция схем Pydantic с парсерами
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
Этот документ описывает решение для устранения дублирования логики между схемами Pydantic и парсерами. Теперь схемы Pydantic являются единым источником правды для определения параметров парсеров.
|
||||||
|
|
||||||
|
## Проблема
|
||||||
|
|
||||||
|
Ранее в парсерах дублировалась информация о параметрах:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# В парсере
|
||||||
|
self.register_getter(
|
||||||
|
name="single_og",
|
||||||
|
method=self._get_single_og,
|
||||||
|
required_params=["id", "codes", "columns"], # Дублирование
|
||||||
|
optional_params=["search"], # Дублирование
|
||||||
|
description="Получение данных по одному ОГ"
|
||||||
|
)
|
||||||
|
|
||||||
|
# В схеме
|
||||||
|
class SvodkaPMSingleOGRequest(BaseModel):
|
||||||
|
id: OGID = Field(...) # Обязательное поле
|
||||||
|
codes: List[int] = Field(...) # Обязательное поле
|
||||||
|
columns: List[str] = Field(...) # Обязательное поле
|
||||||
|
search: Optional[str] = Field(None) # Необязательное поле
|
||||||
|
```
|
||||||
|
|
||||||
|
## Решение
|
||||||
|
|
||||||
|
### 1. Утилиты для работы со схемами
|
||||||
|
|
||||||
|
Создан модуль `core/schema_utils.py` с функциями:
|
||||||
|
|
||||||
|
- `get_required_fields_from_schema()` - извлекает обязательные поля
|
||||||
|
- `get_optional_fields_from_schema()` - извлекает необязательные поля
|
||||||
|
- `register_getter_from_schema()` - регистрирует геттер с использованием схемы
|
||||||
|
- `validate_params_with_schema()` - валидирует параметры с помощью схемы
|
||||||
|
|
||||||
|
### 2. Обновленные парсеры
|
||||||
|
|
||||||
|
Теперь парсеры используют схемы как единый источник правды:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def _register_default_getters(self):
|
||||||
|
"""Регистрация геттеров по умолчанию"""
|
||||||
|
# Используем схемы Pydantic как единый источник правды
|
||||||
|
register_getter_from_schema(
|
||||||
|
parser_instance=self,
|
||||||
|
getter_name="single_og",
|
||||||
|
method=self._get_single_og,
|
||||||
|
schema_class=SvodkaPMSingleOGRequest,
|
||||||
|
description="Получение данных по одному ОГ"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Валидация параметров
|
||||||
|
|
||||||
|
Методы геттеров теперь автоматически валидируют параметры:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def _get_single_og(self, params: dict):
|
||||||
|
"""Получение данных по одному ОГ"""
|
||||||
|
# Валидируем параметры с помощью схемы Pydantic
|
||||||
|
validated_params = validate_params_with_schema(params, SvodkaPMSingleOGRequest)
|
||||||
|
|
||||||
|
og_id = validated_params["id"]
|
||||||
|
codes = validated_params["codes"]
|
||||||
|
columns = validated_params["columns"]
|
||||||
|
search = validated_params.get("search")
|
||||||
|
|
||||||
|
# ... остальная логика
|
||||||
|
```
|
||||||
|
|
||||||
|
## Преимущества
|
||||||
|
|
||||||
|
1. **Единый источник правды** - информация о параметрах хранится только в схемах Pydantic
|
||||||
|
2. **Автоматическая валидация** - параметры автоматически валидируются с помощью Pydantic
|
||||||
|
3. **Синхронизация** - изменения в схемах автоматически отражаются в парсерах
|
||||||
|
4. **Типобезопасность** - использование типов Pydantic обеспечивает типобезопасность
|
||||||
|
5. **Документация** - Swagger документация автоматически генерируется из схем
|
||||||
|
|
||||||
|
## Совместимость
|
||||||
|
|
||||||
|
Решение работает с:
|
||||||
|
- Pydantic v1 (через `__fields__`)
|
||||||
|
- Pydantic v2 (через `model_fields` и `is_required()`)
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Для новых парсеров
|
||||||
|
|
||||||
|
1. Создайте схему Pydantic с нужными полями
|
||||||
|
2. Используйте `register_getter_from_schema()` для регистрации геттера
|
||||||
|
3. Используйте `validate_params_with_schema()` в методах геттеров
|
||||||
|
|
||||||
|
### Для существующих парсеров
|
||||||
|
|
||||||
|
1. Убедитесь, что у вас есть соответствующая схема Pydantic
|
||||||
|
2. Замените ручную регистрацию геттеров на `register_getter_from_schema()`
|
||||||
|
3. Добавьте валидацию параметров в методы геттеров
|
||||||
|
|
||||||
|
## Примеры
|
||||||
|
|
||||||
|
### Схема с обязательными и необязательными полями
|
||||||
|
|
||||||
|
```python
|
||||||
|
class ExampleRequest(BaseModel):
|
||||||
|
required_field: str = Field(..., description="Обязательное поле")
|
||||||
|
optional_field: Optional[str] = Field(None, description="Необязательное поле")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Регистрация геттера
|
||||||
|
|
||||||
|
```python
|
||||||
|
register_getter_from_schema(
|
||||||
|
parser_instance=self,
|
||||||
|
getter_name="example_getter",
|
||||||
|
method=self._example_method,
|
||||||
|
schema_class=ExampleRequest,
|
||||||
|
description="Пример геттера"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Валидация в методе
|
||||||
|
|
||||||
|
```python
|
||||||
|
def _example_method(self, params: dict):
|
||||||
|
validated_params = validate_params_with_schema(params, ExampleRequest)
|
||||||
|
# validated_params содержит валидированные данные
|
||||||
|
```
|
||||||
|
|
||||||
|
## Заключение
|
||||||
|
|
||||||
|
Это решение устраняет дублирование кода и обеспечивает единообразие между API схемами и парсерами. Теперь изменения в схемах автоматически отражаются в парсерах, что упрощает поддержку и развитие системы.
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,6 +3,8 @@ import re
|
|||||||
import zipfile
|
import zipfile
|
||||||
from typing import Dict, Tuple
|
from typing import Dict, Tuple
|
||||||
from core.ports import ParserPort
|
from core.ports import ParserPort
|
||||||
|
from core.schema_utils import register_getter_from_schema, validate_params_with_schema
|
||||||
|
from app.schemas.monitoring_fuel import MonitoringFuelTotalRequest, MonitoringFuelMonthRequest
|
||||||
from adapters.pconfig import data_to_json
|
from adapters.pconfig import data_to_json
|
||||||
|
|
||||||
|
|
||||||
@@ -13,37 +15,40 @@ class MonitoringFuelParser(ParserPort):
|
|||||||
|
|
||||||
def _register_default_getters(self):
|
def _register_default_getters(self):
|
||||||
"""Регистрация геттеров по умолчанию"""
|
"""Регистрация геттеров по умолчанию"""
|
||||||
self.register_getter(
|
# Используем схемы Pydantic как единый источник правды
|
||||||
name="total_by_columns",
|
register_getter_from_schema(
|
||||||
|
parser_instance=self,
|
||||||
|
getter_name="total_by_columns",
|
||||||
method=self._get_total_by_columns,
|
method=self._get_total_by_columns,
|
||||||
required_params=["columns"],
|
schema_class=MonitoringFuelTotalRequest,
|
||||||
optional_params=[],
|
|
||||||
description="Агрегация данных по колонкам"
|
description="Агрегация данных по колонкам"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.register_getter(
|
register_getter_from_schema(
|
||||||
name="month_by_code",
|
parser_instance=self,
|
||||||
|
getter_name="month_by_code",
|
||||||
method=self._get_month_by_code,
|
method=self._get_month_by_code,
|
||||||
required_params=["month"],
|
schema_class=MonitoringFuelMonthRequest,
|
||||||
optional_params=[],
|
|
||||||
description="Получение данных за конкретный месяц"
|
description="Получение данных за конкретный месяц"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_total_by_columns(self, params: dict):
|
def _get_total_by_columns(self, params: dict):
|
||||||
"""Агрегация по колонкам (обертка для совместимости)"""
|
"""Агрегация данных по колонкам"""
|
||||||
columns = params["columns"]
|
# Валидируем параметры с помощью схемы Pydantic
|
||||||
if not columns:
|
validated_params = validate_params_with_schema(params, MonitoringFuelTotalRequest)
|
||||||
raise ValueError("Отсутствуют идентификаторы столбцов")
|
|
||||||
|
columns = validated_params["columns"]
|
||||||
|
|
||||||
# TODO: Переделать под новую архитектуру
|
# TODO: Переделать под новую архитектуру
|
||||||
df_means, _ = self.aggregate_by_columns(self.df, columns)
|
df_means, _ = self.aggregate_by_columns(self.df, columns)
|
||||||
return df_means.to_dict(orient='index')
|
return df_means.to_dict(orient='index')
|
||||||
|
|
||||||
def _get_month_by_code(self, params: dict):
|
def _get_month_by_code(self, params: dict):
|
||||||
"""Получение данных за месяц (обертка для совместимости)"""
|
"""Получение данных за конкретный месяц"""
|
||||||
month = params["month"]
|
# Валидируем параметры с помощью схемы Pydantic
|
||||||
if not month:
|
validated_params = validate_params_with_schema(params, MonitoringFuelMonthRequest)
|
||||||
raise ValueError("Отсутствует идентификатор месяца")
|
|
||||||
|
month = validated_params["month"]
|
||||||
|
|
||||||
# TODO: Переделать под новую архитектуру
|
# TODO: Переделать под новую архитектуру
|
||||||
df_month = self.get_month(self.df, month)
|
df_month = self.get_month(self.df, month)
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import pandas as pd
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from core.ports import ParserPort
|
from core.ports import ParserPort
|
||||||
|
from core.schema_utils import register_getter_from_schema, validate_params_with_schema
|
||||||
|
from app.schemas.svodka_ca import SvodkaCARequest
|
||||||
from adapters.pconfig import get_og_by_name
|
from adapters.pconfig import get_og_by_name
|
||||||
|
|
||||||
|
|
||||||
@@ -12,23 +14,22 @@ class SvodkaCAParser(ParserPort):
|
|||||||
|
|
||||||
def _register_default_getters(self):
|
def _register_default_getters(self):
|
||||||
"""Регистрация геттеров по умолчанию"""
|
"""Регистрация геттеров по умолчанию"""
|
||||||
self.register_getter(
|
# Используем схемы Pydantic как единый источник правды
|
||||||
name="get_data",
|
register_getter_from_schema(
|
||||||
|
parser_instance=self,
|
||||||
|
getter_name="get_data",
|
||||||
method=self._get_data_wrapper,
|
method=self._get_data_wrapper,
|
||||||
required_params=["modes", "tables"],
|
schema_class=SvodkaCARequest,
|
||||||
optional_params=[],
|
|
||||||
description="Получение данных по режимам и таблицам"
|
description="Получение данных по режимам и таблицам"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_data_wrapper(self, params: dict):
|
def _get_data_wrapper(self, params: dict):
|
||||||
"""Обертка для получения данных (для совместимости)"""
|
"""Получение данных по режимам и таблицам"""
|
||||||
modes = params["modes"]
|
# Валидируем параметры с помощью схемы Pydantic
|
||||||
tables = params["tables"]
|
validated_params = validate_params_with_schema(params, SvodkaCARequest)
|
||||||
|
|
||||||
if not isinstance(modes, list):
|
modes = validated_params["modes"]
|
||||||
raise ValueError("Поле 'modes' должно быть списком")
|
tables = validated_params["tables"]
|
||||||
if not isinstance(tables, list):
|
|
||||||
raise ValueError("Поле 'tables' должно быть списком")
|
|
||||||
|
|
||||||
# TODO: Переделать под новую архитектуру
|
# TODO: Переделать под новую архитектуру
|
||||||
data_dict = {}
|
data_dict = {}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
from core.ports import ParserPort
|
from core.ports import ParserPort
|
||||||
|
from core.schema_utils import register_getter_from_schema, validate_params_with_schema
|
||||||
|
from app.schemas.svodka_pm import SvodkaPMSingleOGRequest, SvodkaPMTotalOGsRequest
|
||||||
from adapters.pconfig import OG_IDS, replace_id_in_path, data_to_json
|
from adapters.pconfig import OG_IDS, replace_id_in_path, data_to_json
|
||||||
|
|
||||||
|
|
||||||
@@ -11,48 +13,45 @@ class SvodkaPMParser(ParserPort):
|
|||||||
|
|
||||||
def _register_default_getters(self):
|
def _register_default_getters(self):
|
||||||
"""Регистрация геттеров по умолчанию"""
|
"""Регистрация геттеров по умолчанию"""
|
||||||
self.register_getter(
|
# Используем схемы Pydantic как единый источник правды
|
||||||
name="single_og",
|
register_getter_from_schema(
|
||||||
|
parser_instance=self,
|
||||||
|
getter_name="single_og",
|
||||||
method=self._get_single_og,
|
method=self._get_single_og,
|
||||||
required_params=["id", "codes", "columns"],
|
schema_class=SvodkaPMSingleOGRequest,
|
||||||
optional_params=["search"],
|
|
||||||
description="Получение данных по одному ОГ"
|
description="Получение данных по одному ОГ"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.register_getter(
|
register_getter_from_schema(
|
||||||
name="total_ogs",
|
parser_instance=self,
|
||||||
|
getter_name="total_ogs",
|
||||||
method=self._get_total_ogs,
|
method=self._get_total_ogs,
|
||||||
required_params=["codes", "columns"],
|
schema_class=SvodkaPMTotalOGsRequest,
|
||||||
optional_params=["search"],
|
|
||||||
description="Получение данных по всем ОГ"
|
description="Получение данных по всем ОГ"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_single_og(self, params: dict):
|
def _get_single_og(self, params: dict):
|
||||||
"""Получение данных по одному ОГ (обертка для совместимости)"""
|
"""Получение данных по одному ОГ"""
|
||||||
og_id = params["id"]
|
# Валидируем параметры с помощью схемы Pydantic
|
||||||
codes = params["codes"]
|
validated_params = validate_params_with_schema(params, SvodkaPMSingleOGRequest)
|
||||||
columns = params["columns"]
|
|
||||||
search = params.get("search")
|
|
||||||
|
|
||||||
if not isinstance(codes, list):
|
og_id = validated_params["id"]
|
||||||
raise ValueError("Поле 'codes' должно быть списком")
|
codes = validated_params["codes"]
|
||||||
if not isinstance(columns, list):
|
columns = validated_params["columns"]
|
||||||
raise ValueError("Поле 'columns' должно быть списком")
|
search = validated_params.get("search")
|
||||||
|
|
||||||
# Здесь нужно получить DataFrame из self.df, но пока используем старую логику
|
# Здесь нужно получить DataFrame из self.df, но пока используем старую логику
|
||||||
# TODO: Переделать под новую архитектуру
|
# TODO: Переделать под новую архитектуру
|
||||||
return self.get_svodka_og(self.df, og_id, codes, columns, search)
|
return self.get_svodka_og(self.df, og_id, codes, columns, search)
|
||||||
|
|
||||||
def _get_total_ogs(self, params: dict):
|
def _get_total_ogs(self, params: dict):
|
||||||
"""Получение данных по всем ОГ (обертка для совместимости)"""
|
"""Получение данных по всем ОГ"""
|
||||||
codes = params["codes"]
|
# Валидируем параметры с помощью схемы Pydantic
|
||||||
columns = params["columns"]
|
validated_params = validate_params_with_schema(params, SvodkaPMTotalOGsRequest)
|
||||||
search = params.get("search")
|
|
||||||
|
|
||||||
if not isinstance(codes, list):
|
codes = validated_params["codes"]
|
||||||
raise ValueError("Поле 'codes' должно быть списком")
|
columns = validated_params["columns"]
|
||||||
if not isinstance(columns, list):
|
search = validated_params.get("search")
|
||||||
raise ValueError("Поле 'columns' должно быть списком")
|
|
||||||
|
|
||||||
# TODO: Переделать под новую архитектуру
|
# TODO: Переделать под новую архитектуру
|
||||||
return self.get_svodka_total(self.df, codes, columns, search)
|
return self.get_svodka_total(self.df, codes, columns, search)
|
||||||
|
|||||||
Binary file not shown.
140
python_parser/core/schema_utils.py
Normal file
140
python_parser/core/schema_utils.py
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
"""
|
||||||
|
Упрощенные утилиты для работы со схемами Pydantic
|
||||||
|
"""
|
||||||
|
from typing import List, Dict, Any, Type
|
||||||
|
from pydantic import BaseModel
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
|
||||||
|
def get_required_fields_from_schema(schema_class: Type[BaseModel]) -> List[str]:
|
||||||
|
"""
|
||||||
|
Извлекает список обязательных полей из схемы Pydantic
|
||||||
|
|
||||||
|
Args:
|
||||||
|
schema_class: Класс схемы Pydantic
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Список имен обязательных полей
|
||||||
|
"""
|
||||||
|
required_fields = []
|
||||||
|
|
||||||
|
# Используем model_fields для Pydantic v2 или __fields__ для v1
|
||||||
|
if hasattr(schema_class, 'model_fields'):
|
||||||
|
fields = schema_class.model_fields
|
||||||
|
else:
|
||||||
|
fields = schema_class.__fields__
|
||||||
|
|
||||||
|
for field_name, field_info in fields.items():
|
||||||
|
# В Pydantic v2 есть метод is_required()
|
||||||
|
if hasattr(field_info, 'is_required'):
|
||||||
|
if field_info.is_required():
|
||||||
|
required_fields.append(field_name)
|
||||||
|
elif hasattr(field_info, 'required'):
|
||||||
|
if field_info.required:
|
||||||
|
required_fields.append(field_name)
|
||||||
|
else:
|
||||||
|
# Fallback для старых версий - проверяем наличие default
|
||||||
|
has_default = False
|
||||||
|
|
||||||
|
if hasattr(field_info, 'default'):
|
||||||
|
has_default = field_info.default is not ...
|
||||||
|
elif hasattr(field_info, 'default_factory'):
|
||||||
|
has_default = field_info.default_factory is not None
|
||||||
|
|
||||||
|
if not has_default:
|
||||||
|
required_fields.append(field_name)
|
||||||
|
|
||||||
|
return required_fields
|
||||||
|
|
||||||
|
|
||||||
|
def get_optional_fields_from_schema(schema_class: Type[BaseModel]) -> List[str]:
|
||||||
|
"""
|
||||||
|
Извлекает список необязательных полей из схемы Pydantic
|
||||||
|
|
||||||
|
Args:
|
||||||
|
schema_class: Класс схемы Pydantic
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Список имен необязательных полей
|
||||||
|
"""
|
||||||
|
optional_fields = []
|
||||||
|
|
||||||
|
# Используем model_fields для Pydantic v2 или __fields__ для v1
|
||||||
|
if hasattr(schema_class, 'model_fields'):
|
||||||
|
fields = schema_class.model_fields
|
||||||
|
else:
|
||||||
|
fields = schema_class.__fields__
|
||||||
|
|
||||||
|
for field_name, field_info in fields.items():
|
||||||
|
# В Pydantic v2 есть метод is_required()
|
||||||
|
if hasattr(field_info, 'is_required'):
|
||||||
|
if not field_info.is_required():
|
||||||
|
optional_fields.append(field_name)
|
||||||
|
elif hasattr(field_info, 'required'):
|
||||||
|
if not field_info.required:
|
||||||
|
optional_fields.append(field_name)
|
||||||
|
else:
|
||||||
|
# Fallback для старых версий - проверяем наличие default
|
||||||
|
has_default = False
|
||||||
|
|
||||||
|
if hasattr(field_info, 'default'):
|
||||||
|
has_default = field_info.default is not ...
|
||||||
|
elif hasattr(field_info, 'default_factory'):
|
||||||
|
has_default = field_info.default_factory is not None
|
||||||
|
|
||||||
|
if has_default:
|
||||||
|
optional_fields.append(field_name)
|
||||||
|
|
||||||
|
return optional_fields
|
||||||
|
|
||||||
|
|
||||||
|
def register_getter_from_schema(parser_instance, getter_name: str, method: callable,
|
||||||
|
schema_class: Type[BaseModel], description: str = ""):
|
||||||
|
"""
|
||||||
|
Регистрирует геттер в парсере, используя схему Pydantic для определения параметров
|
||||||
|
|
||||||
|
Args:
|
||||||
|
parser_instance: Экземпляр парсера
|
||||||
|
getter_name: Имя геттера
|
||||||
|
method: Метод для выполнения
|
||||||
|
schema_class: Класс схемы Pydantic
|
||||||
|
description: Описание геттера (если не указано, берется из docstring метода)
|
||||||
|
"""
|
||||||
|
# Извлекаем параметры из схемы
|
||||||
|
required_params = get_required_fields_from_schema(schema_class)
|
||||||
|
optional_params = get_optional_fields_from_schema(schema_class)
|
||||||
|
|
||||||
|
# Если описание не указано, берем из docstring метода
|
||||||
|
if not description:
|
||||||
|
description = inspect.getdoc(method) or ""
|
||||||
|
|
||||||
|
# Регистрируем геттер
|
||||||
|
parser_instance.register_getter(
|
||||||
|
name=getter_name,
|
||||||
|
method=method,
|
||||||
|
required_params=required_params,
|
||||||
|
optional_params=optional_params,
|
||||||
|
description=description
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_params_with_schema(params: Dict[str, Any], schema_class: Type[BaseModel]) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Валидирует параметры с помощью схемы Pydantic
|
||||||
|
|
||||||
|
Args:
|
||||||
|
params: Словарь параметров
|
||||||
|
schema_class: Класс схемы Pydantic
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Валидированные параметры
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValidationError: Если параметры не прошли валидацию
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Создаем экземпляр схемы для валидации
|
||||||
|
validated_data = schema_class(**params)
|
||||||
|
return validated_data.dict()
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError(f"Ошибка валидации параметров: {str(e)}")
|
||||||
Reference in New Issue
Block a user