Skip to content

Commit 5fb9563

Browse files
committed
Merge branch 'develop' into feature/groups
2 parents 9320f95 + 1e8acff commit 5fb9563

File tree

97 files changed

+1497
-403
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+1497
-403
lines changed

.flake8

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ ignore=
1616
A002,
1717
# A003 class attribute "id" is shadowing a python builtin
1818
A003,
19+
# A005 A module is shadowing a Python builtin module
20+
A005,
1921
# D100 Missing docstring in public module
2022
D100,
2123
# D101 Missing docstring in public class

.github/workflows/setup.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ name: CI
66
on:
77
push:
88
branches: [develop]
9+
paths-ignore:
10+
- "docs/**"
911
pull_request:
1012
branches: [develop]
13+
paths-ignore:
14+
- "docs/**"
1115

1216
jobs:
1317
cpython:
@@ -21,22 +25,24 @@ jobs:
2125
- "3.9"
2226
- "3.10"
2327
- "3.11"
28+
- "3.12"
2429

2530
steps:
2631
- uses: actions/checkout@v2
2732
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
28-
uses: actions/setup-python@v2
33+
uses: actions/setup-python@v5
2934
with:
3035
python-version: ${{ matrix.python-version }}
3136

3237
- name: Install dependencies
3338
run: |
3439
python -m pip install --upgrade pip
3540
pip install . -r requirements_dev.txt
41+
pip install diagrams
3642
3743
- name: Run flake8
3844
run: |
39-
python -m flake8 src/aiogram_dialog tests
45+
python -m flake8 src/aiogram_dialog tests example
4046
4147
- name: Run tests
4248
run: |

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Each window consists of:
5757

5858

5959
```python
60-
from aiogram.filters.state import StatesGroup, State
60+
from aiogram.fsm.state import StatesGroup, State
6161
from aiogram_dialog.widgets.text import Format, Const
6262
from aiogram_dialog.widgets.kbd import Button
6363
from aiogram_dialog import Window
@@ -84,7 +84,7 @@ Window(
8484
Window itself can do nothing, just prepares message. To use it you need dialog:
8585

8686
```python
87-
from aiogram.filters.state import StatesGroup, State
87+
from aiogram.fsm.state import StatesGroup, State
8888
from aiogram_dialog import Dialog, Window
8989

9090

@@ -122,7 +122,7 @@ For example in `/start` command handler:
122122
async def user_start(message: Message, dialog_manager: DialogManager):
123123
await dialog_manager.start(MySG.first, mode=StartMode.RESET_STACK)
124124

125-
dp.message.register(user_start, F.text == "/start")
125+
dp.message.register(user_start, CommandStart())
126126
```
127127

128128
> **Info:** Always set `mode=StartMode.RESET_STACK` in your top level start command. Otherwise, dialogs are stacked just as they do

docs/conf.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
# import sys
1515
# sys.path.insert(0, os.path.abspath('.'))
1616

17+
import datetime
1718

1819
# -- Project information -----------------------------------------------------
1920

2021
project = 'aiogram-dialog'
21-
copyright = '2021, Tishka17'
22+
copyright = f'{datetime.date.today().year}, Tishka17'
2223
author = 'Tishka17'
2324
master_doc = 'index'
2425

@@ -29,6 +30,7 @@
2930
# ones.
3031
extensions = [
3132
'sphinx.ext.autodoc',
33+
'sphinx_copybutton',
3234
]
3335
autodoc_type_aliases = {
3436
}
@@ -42,15 +44,13 @@
4244
# This pattern also affects html_static_path and html_extra_path.
4345
exclude_patterns = []
4446

45-
4647
# -- Options for HTML output -------------------------------------------------
4748

4849
# The theme to use for HTML and HTML Help pages. See the documentation for
4950
# a list of builtin themes.
5051
#
5152
html_theme = 'furo'
5253

53-
5454
# Add any paths that contain custom static files (such as style sheets) here,
5555
# relative to this directory. They are copied after the builtin static files,
5656
# so a file named "default.css" will overwrite the builtin "default.css".

docs/helper_tools/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ State diagram
66

77
You can generate image with your states and transitions.
88

9-
Firstly you need to install [graphviz](https://graphviz.org/download/) into your system.
9+
Firstly you need to install `graphviz <https://graphviz.org/download/>`_ into your system.
1010
Check installation instructions on official site.
1111

1212
Install library with tools extras:
@@ -78,4 +78,4 @@ Just run ``aiogram-dialog-preview`` command passing path to ``Dispatcher``/``Rou
7878

7979
.. literalinclude:: ./web_preview.sh
8080

81-
See console output to get URL and error logs
81+
See console output to get URL and error logs
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
async def open_next_window(event, widget, manager: DialogManager):
2+
manager.show_mode = ShowMode.SEND
3+
await manager.next()
4+
5+
6+
async def switch_to_another_window(event, widget, manager: DialogManager):
7+
await manager.switch_to(
8+
state=SomeStatesSG.SomeState,
9+
show_mode=ShowMode.SEND,
10+
)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
How are messages updated
2+
=====================
3+
4+
ShowMode
5+
********************
6+
7+
Currently, to manage the update of the dialog, we use the feature called ShowMode.
8+
9+
When we need to change show mode we can just use show_mode setter on DialogManager or pass it in DialogManager methods (.start, .update, .switch_to, etc.)
10+
11+
.. literalinclude:: ./example.py
12+
13+
.. important::
14+
15+
ShowMode changes only for the next update and then returns to AUTO mode.
16+
17+
.. autoclass:: aiogram_dialog.api.entities.modes.ShowMode(Enum)

docs/index.rst

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ aiogram-dialog
22
=============================================
33

44
.. toctree::
5-
:caption: Contents:
5+
:maxdepth: 3
6+
:caption: Contents:
67

7-
overview/index
8-
quickstart/index
9-
widgets/index
10-
transitions/index
11-
helper_tools/index
12-
migration
13-
faq
8+
overview/index
9+
quickstart/index
10+
widgets/index
11+
transitions/index
12+
how_are_messages_updated/index
13+
helper_tools/index
14+
migration
15+
faq
1416

1517
.. toctree::
1618
:hidden:

docs/quickstart/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Install library:
88
.. literalinclude:: ./install.sh
99

1010
Let's assume that you have created your aiogram bot with dispatcher and states storage as you normally do. When we setup our ``DialogRegistry`` to use that dispatcher.
11-
It is important you have proper storage because **aiogram_dialog** uses ``FSMContext`` internally to store it state:
11+
It is important you have proper storage because **aiogram_dialog** uses ``FSMContext`` internally to store its state:
1212

1313
.. literalinclude:: ./bot.py
1414

docs/resources/toggle.gif

777 KB
Loading

docs/transitions/index.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,21 @@ To close a dialog you have to methods:
105105
Parent dialog has no access to the context of child one. But you can pass some data as a result to ``done()`` method and then process it in ``on_process_result`` callback of parent dialog.
106106

107107
.. literalinclude:: ./done.py
108+
109+
LaunchMode
110+
=================
111+
112+
**LaunchMode** is a mode for launching new dialogs. It helps manage the dialog stack and ensures dialogs are handled appropriately based on their type.
113+
114+
.. literalinclude:: ./launchmode.py
115+
116+
.. autoclass:: aiogram_dialog.api.entities.launch_mode.LaunchMode(Enum)
117+
118+
StartMode
119+
=================
120+
121+
**StartMode** is a mode for starting new dialog. It defines how the current stack should be handled when initiating a new dialog.
122+
123+
.. literalinclude:: ./startmode.py
124+
125+
.. autoclass:: aiogram_dialog.api.entities.modes.StartMode(Enum)

docs/transitions/launchmode.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dialog = Dialog(
2+
Window(...),
3+
launch_mode=LaunchMode.SINGLE_TOP,
4+
)

docs/transitions/startmode.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
async def start(message: Message, dialog_manager: DialogManager):
2+
await dialog_manager.start(..., mode=StartMode.RESET_STACK)

docs/widgets/custom_widgets/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ You can create custom widgets if your are not satisfied with existing ones.
99
If you are making Keyboard widget it is important to create ``InlineKeyboardButton`` instances on each rendering instead of reusing same instance. This is because dialogs modify ``callback_data`` in it.
1010

1111

12-
* :ref:`SwitchInlineQueryCurrentChat<_switch_inline_query_current_chat>` - opens inline query in current chat
12+
* :ref:`SwitchInlineQueryCurrentChat<switch_inline_query_current_chat>` - opens inline query in current chat
1313

1414
.. toctree::
1515
:hidden:

docs/widgets/index.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Also there are 2 general types:
1919
* ``Whenable`` can be hidden or shown depending on data or some conditions. Currently all widgets are whenable.
2020
See: :ref:`Hiding widgets<hiding_widgets>`
2121
* ``Actionable`` is any widget with action (currently only any type of keyboard). It has ``id`` and can be found by that id.
22-
It recommended for all stateful widgets (e.g Checkboxes) to have unique id within dialog.
22+
It's recommended for all stateful widgets (e.g Checkboxes) to have unique id within dialog.
2323
Buttons with different behavior also must have different ids.
2424

2525
.. note::
@@ -30,12 +30,12 @@ Also there are 2 general types:
3030
* ``hello world``, ``my:item``, ``птичка`` - invalid ids
3131

3232
.. toctree::
33+
:maxdepth: 1
34+
3335
passing_data/index
3436
text/index
3537
keyboard/index
3638
input/index
3739
media/index
3840
hiding/index
3941
custom_widgets/index
40-
41-
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from aiogram.fsm.state import State, StatesGroup
2+
from aiogram.types import ContentType, Message
3+
from aiogram_dialog import (
4+
Dialog,
5+
Window,
6+
DialogManager,
7+
)
8+
from aiogram_dialog.widgets.input import MessageInput
9+
from aiogram_dialog.widgets.text import Const
10+
11+
12+
class Main(StatesGroup):
13+
document = State()
14+
15+
16+
async def document_handler(
17+
message: Message,
18+
message_input: MessageInput,
19+
manager: DialogManager,
20+
):
21+
manager.dialog_data["document"] = message.document
22+
await message.answer(f"Your document has been verified!")
23+
await manager.done()
24+
25+
26+
dialog = Dialog(
27+
Window(
28+
Const("Submit your document for verification:"),
29+
MessageInput(document_handler, content_types=[ContentType.DOCUMENT]),
30+
state=Main.document,
31+
),
32+
)

docs/widgets/input/message_input/index.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,14 @@
22

33
MessageInput
44
*************
5+
6+
The **MessageInput** widget allows you to process incoming messages in the context of a dialog.
7+
8+
You can use filters like in `aiogram <https://docs.aiogram.dev/en/latest/dispatcher/filters/index.html>`_ to divide logic into multiple inputs.
9+
10+
Code example:
11+
12+
.. literalinclude:: ./example.py
13+
14+
.. autoclass:: aiogram_dialog.widgets.input.base.MessageInput
15+
:special-members: __init__
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from typing import Any
2+
3+
from aiogram.fsm.state import State, StatesGroup
4+
from aiogram.types import Message
5+
from aiogram_dialog import (
6+
Dialog,
7+
DialogManager,
8+
Window,
9+
)
10+
from aiogram_dialog.widgets.input import TextInput
11+
from aiogram_dialog.widgets.kbd import Next
12+
from aiogram_dialog.widgets.text import Const, Jinja
13+
14+
15+
class SG(StatesGroup):
16+
age = State()
17+
country = State()
18+
result = State()
19+
20+
21+
async def error(
22+
message: Message,
23+
dialog_: Any,
24+
manager: DialogManager,
25+
error_: ValueError
26+
):
27+
await message.answer("Age must be a number!")
28+
29+
30+
async def getter(dialog_manager: DialogManager, **kwargs):
31+
return {
32+
"age": dialog_manager.find("age").get_value(),
33+
"country": dialog_manager.find("country").get_value(),
34+
}
35+
36+
37+
dialog = Dialog(
38+
Window(
39+
Const("Enter your country:"),
40+
TextInput(id="country", on_success=Next()),
41+
state=SG.country,
42+
),
43+
Window(
44+
Const("Enter your age:"),
45+
TextInput(
46+
id="age",
47+
on_error=error,
48+
on_success=Next(),
49+
type_factory=int,
50+
),
51+
state=SG.age,
52+
),
53+
Window(
54+
Jinja(
55+
"<b>You entered</b>:\n\n"
56+
"<b>age</b>: {{age}}\n"
57+
"<b>country</b>: {{country}}\n"
58+
),
59+
state=SG.result,
60+
getter=getter,
61+
parse_mode="html",
62+
),
63+
)

docs/widgets/input/text_input/index.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
TextInput
44
*************
55

6+
The **TextInput** widget automatically saving and validating text for later processing in the dialog.
7+
8+
Parameters:
9+
10+
* ``type_factory``: allows for input validation and automatic conversion to the specified type.
11+
* ``on_success``: for handling successful input.
12+
* ``on_error``: for error handling, will work if ``type_factory`` throws ValueError.
13+
* ``filter``: support `aiogram <https://docs.aiogram.dev/en/latest/dispatcher/filters/index.html>`_ filters.
14+
15+
Code example:
16+
17+
.. literalinclude:: ./example.py
18+
619
.. autoclass:: aiogram_dialog.widgets.input.text.OnSuccess
720
:special-members: __call__
821

0 commit comments

Comments
 (0)