new bot structure

This commit is contained in:
2025-09-25 13:22:14 +03:00
parent f043d5a0a7
commit 8c801eb66e
22 changed files with 85 additions and 47 deletions

3
.env.example Normal file
View File

@@ -0,0 +1,3 @@
ENV_FOR_DYNACONF=production
BOT_TOKEN=

4
.gitignore vendored
View File

@@ -1,4 +1,6 @@
__pycache__
.venv
.env
*.db
*.db
# Ignore dynaconf secret files
.secrets.*

3
app/bot/__init__.py Normal file
View File

@@ -0,0 +1,3 @@
from .bot import main
__all__ = ["main"]

View File

@@ -2,21 +2,19 @@ import asyncio
from aiogram import Bot, Dispatcher
from aiogram_dialog import setup_dialogs
from bestconfig import Config
from app.dialogs import dialogs_router
from app.handlers import handlers_router
from app.bot.dialogs.flows import dialogs_router
from app.bot.handlers.commands import commands_router
from config.config import settings
cfg = Config()
bot = Bot(token=cfg.get("bot_token"))
bot = Bot(token=settings.bot_token)
dp = Dispatcher()
async def main():
dp.include_router(handlers_router)
dp.include_router(dialogs_router)
setup_dialogs(dp)
dp.include_router(commands_router)
dp.include_router(dialogs_router)
await dp.start_polling(bot)

View File

@@ -0,0 +1,8 @@
from aiogram import Router
from .admin import admin_router
from .user import user_router
dialogs_router = Router(name="dialogs")
dialogs_router.include_router(admin_router)
dialogs_router.include_router(user_router)

View File

@@ -0,0 +1,3 @@
from aiogram import Router
admin_router = Router(name="admin dialogs")

View File

@@ -0,0 +1,6 @@
from aiogram import Router
from .start.dialogs import start_dialog
user_router = Router(name="user")
user_router.include_router(start_dialog)

View File

@@ -0,0 +1,14 @@
from aiogram_dialog import Dialog, Window
from aiogram_dialog.widgets.text import Format
from app.bot.dialogs.widgets.getters import username_getter
from .states import StartSG
start_dialog = Dialog(
Window(
Format("Hello, {username}"),
getter=username_getter,
state=StartSG.start,
)
)

View File

@@ -0,0 +1,5 @@
from aiogram.fsm.state import State, StatesGroup
class StartSG(StatesGroup):
start = State()

View File

@@ -4,5 +4,5 @@ from aiogram_dialog import DialogManager
async def username_getter(
dialog_manager: DialogManager, event_from_user: User, **kwargs
):
) -> dict[str, str]:
return {"username": event_from_user.username}

View File

@@ -3,10 +3,10 @@ from aiogram.filters import CommandStart
from aiogram.types import Message
from aiogram_dialog import DialogManager
from app.dialogs.user_dialog import StartSG
from app.bot.dialogs.flows.user.start.states import StartSG
router = Router(name="user_handlers")
commands_router = Router(name="commands_router")
@router.message(CommandStart())
@commands_router.message(CommandStart())
async def command_start_process(message: Message, dialog_manager: DialogManager):
await dialog_manager.start(state=StartSG.start)

View File

@@ -1,6 +0,0 @@
from aiogram import Router
from .user_dialog import router as user_router
dialogs_router = Router(name="dialogs")
dialogs_router.include_router(user_router)

View File

@@ -1,22 +0,0 @@
from aiogram import Router
from aiogram.fsm.state import State, StatesGroup
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
from aiogram_dialog.widgets.text import Format
from app.utils.getters import username_getter
class StartSG(StatesGroup):
start = State()
start_dialog = Dialog(
Window(
Format("Hello, {username}"),
getter=username_getter,
state=StartSG.start
)
)
router = Router(name="user_dialogs")
router.include_router(start_dialog)

View File

@@ -1,6 +0,0 @@
from aiogram import Router
from .user_handlers import router as user_router
handlers_router = Router(name="handlers")
handlers_router.include_router(user_router)

12
config/config.py Normal file
View File

@@ -0,0 +1,12 @@
from dynaconf import Dynaconf
settings = Dynaconf(
envvar_prefix=False,
environments=True,
env_switcher="ENV_FOR_DYNACONF",
settings_files=["settings.toml"],
load_dotenv=True
)
# `envvar_prefix` = export envvars with `export DYNACONF_FOO=bar`.
# `settings_files` = Load these files in the order.

1
config/settings.toml Normal file
View File

@@ -0,0 +1 @@
[DEVELOPMENT]

5
main.py Normal file
View File

@@ -0,0 +1,5 @@
import asyncio
from app.bot import main
asyncio.run(main())

View File

@@ -6,6 +6,7 @@ dependencies = [
"aiogram>=3.22.0",
"aiogram-dialog>=2.4.0",
"bestconfig>=1.3.6",
"dynaconf>=3.2.11",
"psycopg>=3.2.10",
"sqlalchemy>=2.0.43",
]

11
uv.lock generated
View File

@@ -163,6 +163,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" },
]
[[package]]
name = "dynaconf"
version = "3.2.11"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/62/eb/e9d1249ff56b11e63fd8c7d0fcc1f94704e21693c16862bf0ebfb07bd61a/dynaconf-3.2.11.tar.gz", hash = "sha256:4cfc6a730c533bf1a1d0bf266ae202133a22236bb3227d23eff4b8542d4034a5", size = 234694, upload-time = "2025-05-06T15:44:59.16Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/36/64/580c74003a356c5662e7b1da43ecd7cbda6e8f970c87b30c5a654c8ccb53/dynaconf-3.2.11-py2.py3-none-any.whl", hash = "sha256:660de90879d4da236f79195692a7d197957224d7acf922bcc6899187dc7b4a27", size = 236536, upload-time = "2025-05-06T15:44:56.18Z" },
]
[[package]]
name = "frozenlist"
version = "1.7.0"
@@ -607,6 +616,7 @@ dependencies = [
{ name = "aiogram" },
{ name = "aiogram-dialog" },
{ name = "bestconfig" },
{ name = "dynaconf" },
{ name = "psycopg" },
{ name = "sqlalchemy" },
]
@@ -616,6 +626,7 @@ requires-dist = [
{ name = "aiogram", specifier = ">=3.22.0" },
{ name = "aiogram-dialog", specifier = ">=2.4.0" },
{ name = "bestconfig", specifier = ">=1.3.6" },
{ name = "dynaconf", specifier = ">=3.2.11" },
{ name = "psycopg", specifier = ">=3.2.10" },
{ name = "sqlalchemy", specifier = ">=2.0.43" },
]