/
liquid-g
/
liquid-code
Обзор
Документация
Войти
/
liquid-g
/
liquid-code
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop-0.4
src/liquidcode/application/middleware_loader.py
110 строк
5 KB
User
0.4.20 - refactor: централизация обработки исключений в ErrorHandlingMiddleware (T-003)
07 июл 2026, 22:54
07 июл 2026, 22:54
26d8fe2
Код
Авторство
О чём код?
""" Загрузчик middleware из конфигурации. Предоставляет функции для: - загрузки отдельного middleware из элемента конфига; - загрузки списка middleware с сортировкой по приоритету; - загрузки всего конфигурационного файла middleware. """ import importlib import inspect import logging logger = logging.getLogger(__name__) def load_middleware_item(app, item: dict) -> bool: """ Загружает один middleware из элемента конфигурации. Параметры конфига: - class: полное имя класса (например, 'liquidcode.middleware.ErrorHandlingMiddleware') - enabled: bool (по умолчанию True) - priority: int (чем меньше, тем раньше выполняется) - прочие ключи передаются как аргументы конструктора Автоматически передаются в конструктор (если они есть в сигнатуре): - container: DI-контейнер приложения - debug: режим отладки приложения - kernel: экземпляр ядра (для доступа к хукам и событиям) Args: app: Экземпляр Application. item: Словарь с конфигурацией middleware. Returns: True, если загрузка успешна, иначе False. """ if not item.get('enabled', True): return False class_path = item['class'] try: module_name, class_name = class_path.rsplit('.', 1) module = importlib.import_module(module_name) middleware_class = getattr(module, class_name) # Получаем сигнатуру конструктора, чтобы понять, какие параметры принимать sig = inspect.signature(middleware_class.__init__) params = {} # Автоматически передаём стандартные параметры, если они ожидаются if 'container' in sig.parameters: params['container'] = app.container if 'debug' in sig.parameters: params['debug'] = app._debug if 'kernel' in sig.parameters: params['kernel'] = app.kernel # необходимо для ErrorHandlingMiddleware # Передаём дополнительные параметры из конфига, # исключая служебные ключи class, enabled, priority for key, value in item.items(): if key not in ('class', 'enabled', 'priority') and key in sig.parameters: params[key] = value instance = middleware_class(**params) app.add_middleware(instance) logger.info(f"Загружен middleware {class_name} из конфига") return True except Exception as e: logger.error(f"Ошибка загрузки middleware {class_path}: {e}") return False def load_middleware_from_config(app, middleware_list: list) -> None: """ Загружает список middleware с сортировкой по приоритету (возрастание). Args: app: Экземпляр Application. middleware_list: Список словарей с конфигурацией middleware. """ items = sorted(middleware_list, key=lambda x: x.get('priority', 0)) for item in items: load_middleware_item(app, item) def load_middleware_config(app, file_path: str = 'config/middleware.yaml') -> None: """ Загружает middleware из отдельного YAML-конфигурационного файла. Файл должен содержать ключ 'middleware' со списком элементов. Args: app: Экземпляр Application. file_path: Путь к конфигурационному файлу. """ from ..config import load_config, ConfigError try: config = load_config(file_path) except ConfigError as e: logger.warning(f"Не удалось загрузить конфиг middleware: {e}") return items = config.get('middleware', []) items.sort(key=lambda x: x.get('priority', 0)) enabled_count = sum(1 for item in items if item.get('enabled', True)) logger.info(f"Найдено {len(items)} middleware (из них включено: {enabled_count})") for item in items: load_middleware_item(app, item)