Files
python_parser/python_parser/core/services.py

147 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Сервисы (бизнес-логика)
"""
import tempfile
import os
from typing import Dict, Type
from core.models import UploadRequest, UploadResult, DataRequest, DataResult
from core.ports import ParserPort, StoragePort
# Глобальный словарь парсеров
PARSERS: Dict[str, Type[ParserPort]] = {}
def get_parser(report_type: str) -> ParserPort:
"""Получение парсера по типу отчета"""
if report_type not in PARSERS:
available_parsers = list(PARSERS.keys())
raise ValueError(f"Неизвестный тип отчета '{report_type}'. Доступные типы: {available_parsers}")
return PARSERS[report_type]()
class ReportService:
"""Сервис для работы с отчетами (только S3)"""
def __init__(self, storage: StoragePort):
self.storage = storage
def upload_report(self, request: UploadRequest) -> UploadResult:
"""Загрузка отчета"""
try:
# Получаем парсер для данного типа отчета
parser = get_parser(request.report_type)
# Сохраняем файл во временную директорию
suff = "." + str(request.file_name.split('.')[-1])
with tempfile.NamedTemporaryFile(delete=False, suffix=suff) as temp_file:
temp_file.write(request.file_content)
temp_file_path = temp_file.name
try:
# Парсим файл
parse_params = request.parse_params or {}
df = parser.parse(temp_file_path, parse_params)
# Генерируем object_id
object_id = f"nin_excel_data_{request.report_type}"
# Удаляем старый объект, если он существует и хранилище доступно
if self.storage.object_exists(object_id):
self.storage.delete_object(object_id)
print(f"Старый объект удален: {object_id}")
# Сохраняем в хранилище
if self.storage.save_dataframe(df, object_id):
return UploadResult(
success=True,
message="Отчет успешно загружен",
object_id=object_id
)
else:
return UploadResult(
success=False,
message="Ошибка при сохранении в хранилище. Возможно, MinIO недоступен."
)
finally:
# Удаляем временный файл
os.unlink(temp_file_path)
except Exception as e:
return UploadResult(
success=False,
message=f"Ошибка при обработке отчета: {str(e)}"
)
def get_data(self, request: DataRequest) -> DataResult:
"""Получение данных из отчета"""
try:
# Генерируем object_id
object_id = f"nin_excel_data_{request.report_type}"
# Проверяем существование объекта
if not self.storage.object_exists(object_id):
return DataResult(
success=False,
message=f"Отчет типа '{request.report_type}' не найден. Возможно, MinIO недоступен или отчет не был загружен."
)
# Загружаем DataFrame из хранилища
df = self.storage.load_dataframe(object_id)
if df is None:
return DataResult(
success=False,
message="Ошибка при загрузке данных из хранилища. Возможно, MinIO недоступен."
)
# Получаем парсер
parser = get_parser(request.report_type)
# Устанавливаем DataFrame в парсер для использования в геттерах
parser.df = df
# Получаем параметры запроса
get_params = request.get_params or {}
# Определяем имя геттера из параметра mode
getter_name = get_params.pop("mode", None)
if not getter_name:
# Если режим не указан, берем первый доступный
available_getters = list(parser.getters.keys())
if available_getters:
getter_name = available_getters[0]
print(f"⚠️ Режим не указан, используем первый доступный: {getter_name}")
else:
return DataResult(
success=False,
message="Парсер не имеет доступных геттеров"
)
# Получаем значение через указанный геттер
try:
value = parser.get_value(getter_name, get_params)
except ValueError as e:
return DataResult(
success=False,
message=f"Ошибка параметров: {str(e)}"
)
# Формируем результат
if value is not None:
if hasattr(value, 'to_dict'):
result_data = dict(value)
else:
result_data = {"value": value}
return DataResult(success=True, data=result_data)
else:
return DataResult(success=False, message="Значение не найдено")
except Exception as e:
return DataResult(
success=False,
message=f"Ошибка при получении данных: {str(e)}"
)