Skip to content

Commit 963adb0

Browse files
committed
Added AGENTS.md
1 parent c74c4ba commit 963adb0

File tree

3 files changed

+115
-21
lines changed

3 files changed

+115
-21
lines changed

.editorconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
charset = utf-8
7+
indent_style = space
8+
indent_size = 4
9+
trim_trailing_whitespace = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false
13+
14+
[*.{yml,yaml}]
15+
indent_size = 2

AGENTS.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Agent Instructions
2+
3+
This is a Telegram bot project.
4+
5+
## Project Structure
6+
7+
The project has a modular structure where each component has a clearly defined responsibility.
8+
9+
- `/bot/callbacks/`: Contains `CallbackData` factories for handling inline button clicks.
10+
- `/bot/configs/`: Manages configuration using `pydantic-settings`. Settings are loaded from environment variables and a
11+
`.env` file.
12+
- `/bot/handlers/`: The main logic for processing incoming messages and callbacks from Telegram. The `Handlers` class
13+
contains all the handler methods.
14+
- `/bot/i18n/`: Implements internationalization (i18n). Contains translation files (`ru.py`, `en.py`) and the `Lexicon`
15+
class for accessing texts in the desired language.
16+
- `/bot/keyboards/`: The `Keyboards` class for generating Reply and Inline keyboards.
17+
- `/bot/middlewares/`: Middleware.
18+
- `i18n.py`: Determines the user's language.
19+
- `throttling.py`: Limits the rate of user requests.
20+
- `context.py`: Gathers dependencies into a single context object.
21+
- `/bot/services/`: The service layer and business logic.
22+
- `bot_service.py`: An example of a service with business logic (e.g., `upper()`).
23+
- `context.py`: The `HandlerContext` `dataclass` which aggregates all major dependencies.
24+
- `/bot/states/`: State definitions for the FSM (Finite State Machine) using `StatesGroup`.
25+
- `main.py`: The application's entry point. This is where the initialization of `FastAPI`, the bot, the dispatcher, and
26+
the registration of all handlers, middlewares, and dependencies occurs.
27+
28+
## Architecture Overview
29+
30+
The project is built on the **aiogram 3**, **FastAPI**, and **Pydantic** stack. It uses webhooks to receive updates from
31+
Telegram, which is the preferred method for a production environment.
32+
33+
### Dependency Injection (DI) with a Context Object
34+
35+
Instead of passing multiple dependencies into each handler, we use a single context object.
36+
37+
**How it works:**
38+
39+
1. **Singleton Initialization:** In `main.py`, within the `register_workflow_data` function, we create a single instance
40+
of all key services (`Keyboards`, `BotService`, `Lexicon`) and store them in `dp.workflow_data`.
41+
2. **Context Assembly:** The `ContextMiddleware` runs with every incoming update. It retrieves the previously created
42+
services from `data` and packs them into the `HandlerContext` `dataclass`.
43+
3. **Injection into Handler:** The prepared `ctx: HandlerContext` object is automatically passed as an argument to any
44+
handler that requests it via a type hint.
45+
46+
**Agent Instruction:**
47+
> When adding new functionality that requires access to services (e.g., a database), follow this
48+
> pattern:
49+
> 1. Create a new service class (e.g., `DatabaseService`).
50+
> 2. Add an instance of it to `workflow_data` in `main.py`.
51+
> 3. Add a new field to the `HandlerContext` `dataclass`.
52+
> 4. Add the initialization for this field in `ContextMiddleware`.
53+
> 5. You can now access your service in any handler via `ctx.database_service`.
54+
55+
### Update Flow
56+
57+
1. Telegram sends a JSON update to the FastAPI endpoint (`/webhook/tg`).
58+
2. The `webhook_handler` in `main.py` validates the data and passes it to `dispatcher.feed_update()`.
59+
3. The dispatcher sequentially runs the **outer middlewares**:
60+
- `I18nMiddleware` determines the `user_lang`.
61+
- `ThrottlingMiddleware` checks the request frequency.
62+
- `ContextMiddleware` assembles the `ctx` object.
63+
4. The dispatcher finds a suitable handler based on filters (`CommandStart`, `F.text`, etc.).
64+
5. The dispatcher calls the found handler, passing it all necessary data, including `message`, `state`, and our `ctx`.
65+
66+
## Coding Style & Naming Conventions
67+
68+
Maintaining a consistent code style is critically important for the project's readability and maintainability.
69+
70+
- **Language:** Python 3.12+, line length 120. Strict typing is non-negotiable.
71+
- **Type Hinting:** **Mandatory.** All new functions, methods, and variables must have strict type annotations. This is
72+
the foundation for DI and static analysis.
73+
- **Naming:**
74+
- Classes: `PascalCase` (e.g., `BotService`, `HandlerContext`).
75+
- Functions, methods, variables: `snake_case` (e.g., `start_command`, `user_lang`).
76+
- Constants: `UPPER_SNAKE_CASE` (e.g., `LEXICON_RU`).
77+
- Modules: `snake_case` (e.g., `bot_service.py`).
78+
- **Internationalization:** All user-visible strings (messages, button text) must be moved to the lexicon files in
79+
`/i18n/` and retrieved using `ctx.lexicon.get_text()`. Do not hardcode strings in handlers and keyboards.

requirements.txt

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
aiofiles==24.1.0
2-
aiogram==3.17.0
3-
aiohappyeyeballs==2.4.6
4-
aiohttp==3.11.12
5-
aiosignal==1.3.2
2+
aiogram==3.22.0
3+
aiohappyeyeballs==2.6.1
4+
aiohttp==3.12.15
5+
aiosignal==1.4.0
66
annotated-types==0.7.0
7-
anyio==4.8.0
8-
attrs==25.1.0
9-
cachetools==5.5.1
10-
certifi==2025.1.31
11-
click==8.1.8
7+
anyio==4.11.0
8+
attrs==25.3.0
9+
cachetools==6.2.0
10+
certifi==2025.8.3
11+
click==8.3.0
1212
colorama==0.4.6
13-
fastapi==0.115.8
14-
frozenlist==1.5.0
15-
h11==0.14.0
13+
fastapi==0.117.1
14+
frozenlist==1.7.0
15+
h11==0.16.0
1616
idna==3.10
1717
magic-filter==1.0.12
18-
multidict==6.1.0
19-
pydantic==2.10.6
20-
pydantic-settings==2.7.1
21-
pydantic_core==2.27.2
22-
python-dotenv==1.0.1
18+
multidict==6.6.4
19+
pydantic==2.11.9
20+
pydantic-settings==2.11.0
21+
pydantic_core==2.33.2
22+
python-dotenv==1.1.1
2323
sniffio==1.3.1
24-
starlette==0.45.3
25-
typing_extensions==4.12.2
26-
uvicorn==0.34.0
27-
yarl==1.18.3
24+
starlette==0.48.0
25+
typing_extensions==4.15.0
26+
uvicorn==0.37.0
27+
yarl==1.20.1

0 commit comments

Comments
 (0)