Обновлен Python до версии 3.11.9 и изменены зависимости в Dockerfile и pyproject.toml. Удалены устаревшие файлы RATE_LIMITING_SOLUTION.md и тесты для rate limiting.

Обновлены пути к библиотекам в Dockerfile для соответствия новой версии Python.
Исправлены все тесты, теперь все проходят
This commit is contained in:
2026-01-25 16:07:27 +03:00
parent 5a90591564
commit d2d7c83575
21 changed files with 2324 additions and 409 deletions

View File

@@ -0,0 +1,109 @@
---
description: "Паттерны создания и использования middleware в aiogram"
globs: ["helper_bot/middlewares/**/*.py"]
---
# Паттерны Middleware
## Структура Middleware
Все middleware наследуются от `aiogram.BaseMiddleware`:
```python
from typing import Any, Dict
from aiogram import BaseMiddleware
from aiogram.types import TelegramObject
class CustomMiddleware(BaseMiddleware):
"""Описание middleware."""
async def __call__(
self,
handler: Callable,
event: TelegramObject,
data: Dict[str, Any]
) -> Any:
# Логика до обработки handler
...
# Вызов следующего handler в цепочке
result = await handler(event, data)
# Логика после обработки handler
...
return result
```
## Порядок регистрации Middleware
В `main.py` middleware регистрируются в следующем порядке (важно!):
```python
# 1. DependenciesMiddleware - внедрение зависимостей
dp.update.outer_middleware(DependenciesMiddleware())
# 2. MetricsMiddleware - сбор метрик
dp.update.outer_middleware(MetricsMiddleware())
# 3. BlacklistMiddleware - проверка черного списка
dp.update.outer_middleware(BlacklistMiddleware())
# 4. RateLimitMiddleware - ограничение частоты запросов
dp.update.outer_middleware(RateLimitMiddleware())
```
## DependenciesMiddleware
Внедряет глобальные зависимости во все handlers:
```python
class DependenciesMiddleware(BaseMiddleware):
async def __call__(self, handler, event: TelegramObject, data: Dict[str, Any]) -> Any:
bdf = get_global_instance()
# Внедрение зависимостей
if 'bot_db' not in data:
data['bot_db'] = bdf.get_db()
if 'settings' not in data:
data['settings'] = bdf.settings
return await handler(event, data)
```
## Обработка ошибок в Middleware
```python
class CustomMiddleware(BaseMiddleware):
async def __call__(self, handler, event, data):
try:
# Предобработка
...
result = await handler(event, data)
# Постобработка
...
return result
except Exception as e:
# Обработка ошибок
logger.error(f"Ошибка в middleware: {e}")
# Решаем: пробрасывать дальше или обработать
raise
```
## Регистрация на уровне Router
Middleware можно регистрировать на уровне конкретного router:
```python
router = Router()
router.message.middleware(SomeMiddleware()) # Только для message handlers
router.callback_query.middleware(SomeMiddleware()) # Только для callback handlers
```
## Best Practices
1. **Регистрируйте middleware в правильном порядке** - зависимости должны быть первыми
2. **Не изменяйте event** напрямую, используйте `data` для передачи информации
3. **Обрабатывайте ошибки** в middleware, но не глотайте их без логирования
4. **Используйте `outer_middleware`** для глобальной регистрации
5. **Используйте `router.middleware()`** для локальной регистрации на уровне модуля