Skip to content
This repository was archived by the owner on Jan 3, 2026. It is now read-only.

Commit 0c8caca

Browse files
committed
feat: Added the ability to use Redis as an FSM state store
Signed-off-by: rin-gil <91410075+rin-gil@users.noreply.github.com>
1 parent 7c080a2 commit 0c8caca

File tree

7 files changed

+65
-10
lines changed

7 files changed

+65
-10
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
<a href="https://pypi.org/project/numpy/1.25.2/">
2525
<img src="https://img.shields.io/badge/numpy-v1.25.2-informational" alt="numpy version">
2626
</a>
27+
<a href="https://pypi.org/project/redis/4.6.0/">
28+
<img src="https://img.shields.io/badge/redis-v4.6.0-informational" alt="redis version">
29+
</a>
2730
<a href="https://pypi.org/project/yt-dlp/22023.7.6/">
2831
<img src="https://img.shields.io/badge/yt_dlp-v2023.7.6-informational" alt="yt-dlp version">
2932
</a>

README.ru.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
<a href="https://pypi.org/project/numpy/1.25.2/">
2525
<img src="https://img.shields.io/badge/numpy-v1.25.2-informational" alt="numpy version">
2626
</a>
27+
<a href="https://pypi.org/project/redis/4.6.0/">
28+
<img src="https://img.shields.io/badge/redis-v4.6.0-informational" alt="redis version">
29+
</a>
2730
<a href="https://pypi.org/project/yt-dlp/22023.7.6/">
2831
<img src="https://img.shields.io/badge/yt_dlp-v2023.7.6-informational" alt="yt-dlp version">
2932
</a>

README.ua.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
<a href="https://pypi.org/project/numpy/1.25.2/">
2525
<img src="https://img.shields.io/badge/numpy-v1.25.2-informational" alt="numpy version">
2626
</a>
27+
<a href="https://pypi.org/project/redis/4.6.0/">
28+
<img src="https://img.shields.io/badge/redis-v4.6.0-informational" alt="redis version">
29+
</a>
2730
<a href="https://pypi.org/project/yt-dlp/22023.7.6/">
2831
<img src="https://img.shields.io/badge/yt_dlp-v2023.7.6-informational" alt="yt-dlp version">
2932
</a>

src/.env.example

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@ POSTGRES_DB_NAME=
99
POSTGRES_DB_USER=
1010
POSTGRES_DB_PASSWORD=
1111

12+
# Redis database
13+
REDIS_HOST=
14+
REDIS_PORT=
15+
REDIS_DB_INDEX=
16+
REDIS_DB_PASS=
17+
1218
# Webhook credentials
1319
WEBHOOK_HOST=
1420
WEBHOOK_PATH=
1521
WEBHOOK_TOKEN=
16-
WEBAPP_HOST=
17-
WEBAPP_PORT=
22+
APP_HOST=
23+
APP_PORT=

src/bot.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from aiogram import Bot, Dispatcher
66
from aiogram.contrib.fsm_storage.memory import MemoryStorage
7+
from aiogram.contrib.fsm_storage.redis import RedisStorage2
78
from aiogram.utils.executor import start_polling, start_webhook
89
from aiohttp import ClientSession
910

@@ -67,7 +68,18 @@ def start_bot() -> None:
6768
"""Starts the bot"""
6869
config: Config = load_config()
6970
bot: Bot = Bot(token=config.tg_bot.token, parse_mode="HTML")
70-
dp: Dispatcher = Dispatcher(bot=bot, storage=MemoryStorage())
71+
storage: MemoryStorage | RedisStorage2 = (
72+
RedisStorage2(
73+
host=config.redis.host,
74+
port=config.redis.port,
75+
db=config.redis.database_index,
76+
password=config.redis.password,
77+
prefix="ymdb_fsm",
78+
)
79+
if config.redis
80+
else MemoryStorage()
81+
)
82+
dp: Dispatcher = Dispatcher(bot=bot, storage=storage)
7183
database: Database = Database(db_config=config.db)
7284
bot["config"] = config
7385
bot["db"] = database

src/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ environs==9.5.0
55
imageio-ffmpeg==0.4.8
66
matplotlib==3.7.2
77
numpy==1.25.2
8+
redis==4.6.0
89
yt-dlp==2023.7.6

src/tgbot/config.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ class DbConfig(NamedTuple):
1717
database: str
1818

1919

20+
class RedisConfig(NamedTuple):
21+
"""Redis database configuration"""
22+
23+
host: str
24+
port: int
25+
database_index: int
26+
password: str
27+
28+
2029
class WebhookCredentials(NamedTuple):
2130
"""Represents credentials to use webhook"""
2231

@@ -39,12 +48,16 @@ class Config(NamedTuple):
3948

4049
tg_bot: TgBot
4150
db: DbConfig
51+
redis: RedisConfig | None
4252
webhook: WebhookCredentials | None
4353

4454

4555
# Change USE_WEBHOOK to True to use a webhook instead of long polling
4656
USE_WEBHOOK: bool = False
4757

58+
# Change USE_REDIS to True to use redis storage for FSM instead of memory
59+
USE_REDIS: bool = False
60+
4861
_BASE_DIR: Path = Path(__file__).resolve().parent.parent
4962
LOCALES_DIR: str = normpath(join(_BASE_DIR, "tgbot/locales"))
5063
TEMP_DIR: str = normpath(join(_BASE_DIR, "tgbot/temp"))
@@ -71,11 +84,25 @@ def load_config() -> Config:
7184
user=env.str("POSTGRES_DB_USER"),
7285
database=env.str("POSTGRES_DB_NAME"),
7386
),
74-
webhook=WebhookCredentials(
75-
wh_host=env.str("WEBHOOK_HOST"),
76-
wh_path=env.str("WEBHOOK_PATH"),
77-
wh_token=env.str("WEBHOOK_TOKEN"),
78-
app_host=env.str("APP_HOST"),
79-
app_port=env.int("APP_PORT"),
80-
) if USE_WEBHOOK else None
87+
redis=(
88+
RedisConfig(
89+
host=env.str("REDIS_HOST"),
90+
port=env.int("REDIS_PORT"),
91+
database_index=env.int("REDIS_DB_INDEX"),
92+
password=env.str("REDIS_DB_PASS"),
93+
)
94+
if USE_REDIS
95+
else None
96+
),
97+
webhook=(
98+
WebhookCredentials(
99+
wh_host=env.str("WEBHOOK_HOST"),
100+
wh_path=env.str("WEBHOOK_PATH"),
101+
wh_token=env.str("WEBHOOK_TOKEN"),
102+
app_host=env.str("APP_HOST"),
103+
app_port=env.int("APP_PORT"),
104+
)
105+
if USE_WEBHOOK
106+
else None
107+
),
81108
)

0 commit comments

Comments
 (0)