Как интегрировать Redis с библиотекой aiogram?

Я не спрашиваю о том, как заменить стандартный FSMContext aiogram на FSMContext с использованием Redis. <br/><br/> Я заметил, что у FSMContext есть метод .storage, который, как я понимаю, предназначен для взаимодействия с дополнительным хранилищем. <br/><br/> Однако возникает проблема: в RedisStorage есть методы .set, где ключом ячейки является просто строка, тогда как в state.storage.update_data ключ представляет собой нечто более сложное, включая KeyBuilder и другие элементы, которые мне не совсем ясны. <br/><br/> Интересно, что в документации не содержится подробной информации о KeyBuilder или о том, как правильно использовать FSMContext. <br/><br/> Может ли RedisStorage быть использован в качестве дополнительного noSQL хранилища?
  • 27 апреля 2025 г. 14:05
Ответы на вопрос 1
Да, Redis может быть использован в качестве хранилища для ваших данных в библиотеке aiogram, и это может быть сделано через механизм `FSMContext` (Finite State Machine Context). Однако, как вы заметили, использование RedisStorage требует некоторых дополнительных шагов, чтобы правильно установить и интегрировать его с вашими состояниями.

Вот основные шаги по интеграции Redis с библиотекой aiogram, включая работу с `FSMContext` и `RedisStorage`.

### 1. Установка необходимых библиотек

Во-первых, убедитесь, что у вас установлены нужные пакеты. Вам нужно установить aiogram и aioredis.

```bash
pip install aiogram aioredis
```

### 2. Настройка Redis

Импортируйте необходимые модули и настройте Redis. Вы можете использовать aiogram’s `RedisStorage` как хранилище для вашего `Dispatcher`.

```python
from aiogram import Bot, Dispatcher
from aiogram.contrib.fsm_storage.redis import RedisStorage
import redis
import asyncio

# Конфигурация Redis
redis_host = 'localhost'  # Убедитесь, что Redis запущен на этом хосте
redis_port = 6379          # Порт по умолчанию
redis_db = 0               # Номер базы данных (по умолчанию 0)

# Создаем экземпляр RedisStorage
storage = RedisStorage(host=redis_host, port=redis_port, db=redis_db)

# Создаем экземпляры Bot и Dispatcher
bot = Bot(token='YOUR_BOT_TOKEN')
dp = Dispatcher(bot, storage=storage)
```

### 3. Использование FSMContext

Теперь вы можете использовать `FSMContext`, как обычно, но любые данные, сохраняемые с его помощью, будут храниться в Redis. Ниже приведен пример использования состояний:

```python
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher import State, StatesGroup
from aiogram import types

class Form(StatesGroup):
    name = State()  # Ожидание ввода имени
    age = State()   # Ожидание ввода возраста

@dp.message_handler(commands='start')
async def cmd_start(message: types.Message):
    await Form.name.set()  # Устанавливаем состояние
    await message.answer("Привет! Как тебя зовут?")

@dp.message_handler(state=Form.name)
async def process_name(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['name'] = message.text  # Сохраняем имя в состоянии

    await Form.next()  # Переходим к следующему состоянию
    await message.answer("Сколько вам лет?")

@dp.message_handler(state=Form.age)
async def process_age(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['age'] = message.text  # Сохраняем возраст в состоянии

    await message.answer(f"Ваше имя: {data['name']}, ваш возраст: {data['age']}")
    await state.finish()  # Завершаем состояние
```

### 4. Закрытие соединения

Обязательно закройте соединение с Redis после завершения работы с ботом.

```python
async def on_shutdown(dp):
    await storage.close()
    await storage.wait_closed()

if __name__ == '__main__':
    from aiogram import executor
    executor.start_polling(dp, on_shutdown=on_shutdown)
```

### О ключах и KeyBuilder

По поводу вашего вопроса о `KeyBuilder` и ключах, используемых для хранения данных в `FSMContext`:

- Aiogram создает ключи, используя комбинацию идентификатора пользователя (user_id), идентификатора чата (chat_id) и идентификатор состояния (state), чтобы гарантировать уникальность хранящихся данных.
- При работе с пользовательскими данными вам не нужно беспокоиться о том, как создаются ключи - просто работайте с методами `update_data`, `get_data` и т. д., и aiogram автоматически позаботится о ключах.

Таким образом, RedisStorage вполне может быть использован как дополнительное noSQL хранилище с помощью библиотеки aiogram.
Похожие вопросы