Обновлен Python до версии 3.11.9 и изменены зависимости в Dockerfile и pyproject.toml. Удалены устаревшие файлы RATE_LIMITING_SOLUTION.md и тесты для rate limiting.
Обновлены пути к библиотекам в Dockerfile для соответствия новой версии Python. Исправлены все тесты, теперь все проходят
This commit is contained in:
109
.cursor/rules/middleware-patterns.md
Normal file
109
.cursor/rules/middleware-patterns.md
Normal 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()`** для локальной регистрации на уровне модуля
|
||||
Reference in New Issue
Block a user