### Full Example Summary Source: https://aiogram-dialog.readthedocs.io/en/stable/quickstart/index.html Complete implementation of the dialog setup. ```python from aiogram import Bot, Dispatcher from aiogram.filters import Command from aiogram.filters.state import State, StatesGroup from aiogram.fsm.storage.memory import MemoryStorage from aiogram.types import Message from aiogram_dialog import ( Dialog, DialogManager, setup_dialogs, StartMode, Window, ) from aiogram_dialog.widgets.kbd import Button from aiogram_dialog.widgets.text import Const class MySG(StatesGroup): main = State() main_window = Window( Const("Hello, unknown person"), Button(Const("Useless button"), id="nothing"), state=MySG.main, ) dialog = Dialog(main_window) storage = MemoryStorage() bot = Bot(token='BOT TOKEN HERE') dp = Dispatcher(storage=storage) dp.include_router(dialog) setup_dialogs(dp) @dp.message(Command("start")) async def start(message: Message, dialog_manager: DialogManager): await dialog_manager.start(MySG.main, mode=StartMode.RESET_STACK) if __name__ == '__main__': dp.run_polling(bot, skip_updates=True) ``` -------------------------------- ### Full Dialog Example with Case Widgets Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/text/case/index.html This example demonstrates a complete dialog setup including state management, data getters, and the usage of multiple Case widgets with different selector types. ```python from typing import Any from aiogram.filters.state import State, StatesGroup from magic_filter import F from aiogram_dialog import Dialog, DialogManager, Window from aiogram_dialog.widgets.text import Case, Const, Format class MySG(StatesGroup): window1 = State() window2 = State() # let's assume this is our window data getter async def get_data(**kwargs): return {"color": "red", "number": 42} # Using string selector as a `selector`. # The value of data["color"] will be used to select wich option of ``Case`` widget to show. # # `text` will produce text `Square` text = Case( { "red": Const("Square"), "green": Const("Unicorn"), "blue": Const("Moon"), ...: Const("Unknown creature"), }, selector="color", ) # Using function as a `selector`. # The result of this function will be used to select wich option of ``Case`` widget to show. # # `text2` will produce text `42 is even!` def parity_selector(data: dict, case: Case, manager: DialogManager): return data["number"] % 2 text2 = Case( { 0: Format("{number} is even!"), 1: Const("It is Odd"), }, selector=parity_selector, ) # Using F-filters as a selector. # The value of data["dialog_data"]["user"]["test_result"] will be used to select wich # option of ``Case`` widget to show. # # `text3` will produce text `Great job!` text3 = Case( { True: Const("Great job!"), False: Const("Try again.."), }, selector=F["dialog_data"]["user"]["test_result"], ) async def on_dialog_start(start_data: Any, manager: DialogManager): manager.dialog_data["user"] = { "test_result": True, } dialog = Dialog( Window( text, text2, text3, state=MySG.window1, getter=get_data, ), on_start=on_dialog_start, ) ``` -------------------------------- ### Install helper tools Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/helper_tools/index.rst.txt Install the library with the necessary extras for helper tools. ```bash pip install aiogram-dialog[tools] ``` -------------------------------- ### Full dialog preview example Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/helper_tools/index.rst.txt A complete example demonstrating how to set up and render a dialog preview. ```python from aiogram_dialog.tools import render_preview # ... your dialog setup ... await render_preview("preview.html", router) ``` -------------------------------- ### Starting a Subdialog Source: https://aiogram-dialog.readthedocs.io/en/stable/transitions/index.html Demonstrates how to define dialog states and initiate a subdialog using the dialog_manager.start method or the Start widget. ```python from aiogram.filters.state import StatesGroup, State from aiogram.types import CallbackQuery from aiogram_dialog import Dialog, DialogManager, Window from aiogram_dialog.widgets.kbd import Button, Start from aiogram_dialog.widgets.text import Const class DialogSG(StatesGroup): first = State() class SubDialogSG(StatesGroup): first = State() second = State() async def start_subdialog(callback: CallbackQuery, button: Button, manager: DialogManager): await manager.start(SubDialogSG.second, data={"key": "value"}) dialog = Dialog( Window( Const("Main dialog"), Start(Const("Start 1"), id="start", state=SubDialogSG.first), Button(Const("Start 2"), id="sec", on_click=start_subdialog), state=DialogSG.first, ), ) subdialog = Dialog( Window( Const("Subdialog: first"), state=SubDialogSG.first, ), Window( Const("Subdialog: second"), state=SubDialogSG.second, ), ) ``` -------------------------------- ### Install aiogram-dialog with tools extras Source: https://aiogram-dialog.readthedocs.io/en/stable/helper_tools/index.html Install the library with the necessary extras for using the helper tools. ```bash pip install aiogram_dialog[tools] ``` -------------------------------- ### Example of Hiding Widgets Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/widgets/hiding/index.rst.txt This example demonstrates how to use the 'when' attribute to control widget visibility. It requires the 'example.py' file to be present. ```python from aiogram_dialog import Window from aiogram_dialog.widgets.text import Const, Format from aiogram_dialog.widgets.input import MessageInput from aiogram_dialog.widgets.common import When from aiogram_dialog.api import DialogManager def getter(**kwargs): return { "extended": False, "text": "Hello", } async def handler(event): await event.update(extended=True) window = Window( Const("This text is always visible"), Const("This text is visible only when 'extended' is False", when=When(lambda data: not data["extended"])), Format("{text}", when=When(lambda data: data["extended"])), Const("This button is visible only when 'extended' is True", when=When(lambda data: data["extended"])), MessageInput(handler=handler), state=0, getter=getter, ) ``` -------------------------------- ### Starting Shared Dialogs Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/group_business.rst.txt Demonstrates how to start shared dialogs in groups or business chats using specific stack IDs or start modes. ```APIDOC ## POST /start_dialog (Conceptual) ### Description Starts a shared dialog in a group or business chat. This is a conceptual representation as the actual implementation is within the aiogram-dialog library. ### Method POST (Conceptual) ### Endpoint /start_dialog (Conceptual) ### Parameters #### Query Parameters - **stack_id** (string) - Optional - The ID of the stack to use for the dialog (e.g., `aiogram_dialog.GROUP_STACK_ID`). - **thread_id** (integer) - Optional - The ID of the thread within the chat to start the dialog in. #### Request Body - **state** (object) - Required - The initial state of the dialog. - **mode** (string) - Optional - The mode to start the dialog in (e.g., `StartMode.RESET_STACK`). ### Request Example ```python from aiogram_dialog import StartMode from aiogram_dialog.api.defaults import GROUP_STACK_ID # Assuming dialog_manager is an instance of DialogManager dialog_manager.bg(stack_id=GROUP_STACK_ID).start( MyStateGroup.MY_STATE, mode=StartMode.RESET_STACK, ) ``` ### Response (No specific response details provided in the source text for this conceptual action.) ``` -------------------------------- ### Starting Shared Dialogs Source: https://aiogram-dialog.readthedocs.io/en/stable/group_business.html Demonstrates how to start a shared dialog from a personal context using a specific stack ID or by initiating a new stack. ```APIDOC ## Starting Shared Dialogs When user sends message or other event not attached directly to some dialog, default stack is used. If you start dialogs in that stack, they can be accessed only by that user. So, the default stack in **personal**. To send a _shared_ dialog from _personal_ , you need to use other stacks. It can be `aiogram_dialog.GROUP_STACK_ID`, other predefined string or starting via `StartMode.NEW_STACK`. ### Request Example ```python from aiogram_dialog import StartMode from aiogram_dialog.api.defaults import GROUP_STACK_ID bg = dialog_manager.bg(stack_id=GROUP_STACK_ID) bg.start( MyStateGroup.MY_STATE, mode=StartMode.RESET_STACK, ) ``` If there are different topics in chat, stacks between them are isolated. To start dialog in different topic pass `thread_id` as `.bg()` argument ``` -------------------------------- ### Install aiogram-dialog Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/quickstart/index.rst.txt Install the aiogram-dialog library using pip. This is the first step before integrating it into your project. ```bash pip install aiogram-dialog ``` -------------------------------- ### Initialize a basic Calendar widget Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/calendar/index.html Demonstrates the minimal setup required to instantiate a Calendar widget and handle date selection events. ```python from datetime import date from aiogram.types import CallbackQuery from aiogram_dialog import DialogManager from aiogram_dialog.widgets.kbd import Calendar async def on_date_selected(callback: CallbackQuery, widget, manager: DialogManager, selected_date: date): await callback.answer(str(selected_date)) calendar = Calendar(id='calendar', on_click=on_date_selected) ``` -------------------------------- ### Column Widget Usage Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/column/index.html Example demonstrating how to initialize a Column widget with multiple Button components. ```APIDOC ## Column Widget ### Description The Column widget arranges its child widgets in a vertical column. It is similar to the Row widget but stacks elements vertically and ignores hierarchy. ### Usage Example ```python from aiogram_dialog.widgets.kbd import Button, Column from aiogram_dialog.widgets.text import Const column = Column( Button(Const("Go"), id="go"), Button(Const("Run"), id="run"), Button(Const("Fly"), id="fly"), ) ``` ``` -------------------------------- ### Example Usage of Next and Back Buttons Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/widgets/keyboard/next_and_back/index.rst.txt Demonstrates how to implement Next and Back buttons for dialog navigation. Ensure the necessary imports are present. ```python from aiogram_dialog.widgets.kbd import Button, Next, Back async def handler(c): await c.answer("OK") next_button = Next("next", text="Next", on_click=handler) back_button = Back("back", text="Back", on_click=handler) # Example of equal solution async def handler(c): await c.answer("OK") equal_next_button = Next("next", text="Next", on_click=handler) equal_back_button = Back("back", text="Back", on_click=handler) ``` -------------------------------- ### Initiate a dialog with StartMode Source: https://aiogram-dialog.readthedocs.io/en/stable/transitions/index.html Demonstrates how to specify a StartMode when starting a new dialog via the DialogManager. ```python async def start(message: Message, dialog_manager: DialogManager): await dialog_manager.start(..., mode=StartMode.RESET_STACK) ``` -------------------------------- ### Use the Start widget to initiate a dialog Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/start/index.html The `Start` widget is a specialized button for initiating dialogs. It simplifies the process by directly accepting `state` and `data` parameters. ```python from aiogram_dialog.widgets.kbd import Button, Start async def on_click( cq: CallbackQuery, button: Button, dialog_manager: DialogManager ): ... # your actions button = Start(..., state=SOME_STATE, data=SOME_DATA, on_click=on_click) ``` -------------------------------- ### Counter Widget Initialization Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/counter/index.html Example of how to initialize and use the Counter widget, including defining callback functions. ```APIDOC ## Counter Widget Counter widget is a simple way to input a number using `+`/`-` buttons. ### Usage Example ```python from aiogram_dialog.widgets.kbd import ManagedCounter, Counter from aiogram_dialog import CallbackQuery, DialogManager async def on_text_click( event: CallbackQuery, widget: ManagedCounter, dialog_manager: DialogManager, ) -> None: await event.answer(f"Value: {widget.get_value()}") counter = Counter( id="someid", default=0, max_value=1000, on_text_click=on_text_click, ) ``` ``` -------------------------------- ### Registry Setup in 2.0b17 Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/migration.rst.txt The `Registry` is now created without a dispatcher and requires `setup_dp` to be called afterward. `Registry.register_start_handler` now requires a router or dispatcher. ```python # registry = Registry() # registry.setup_dp(dispatcher) # registry.register_start_handler(router_or_dispatcher) ``` -------------------------------- ### Implement a Progress widget Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/text/progress/index.html Basic setup for a Progress widget using a getter to retrieve data and a background task to update the progress state. ```python import asyncio from aiogram.filters import Command from aiogram.fsm.state import StatesGroup, State from aiogram.types import Message from aiogram_dialog import Dialog, Window, DialogManager, BaseDialogManager from aiogram_dialog.widgets.text import Multi, Const, Progress class Main(StatesGroup): progress = State() async def get_bg_data(dialog_manager: DialogManager, **kwargs): return { "progress": dialog_manager.dialog_data.get("progress", 0) } async def background(manager: BaseDialogManager): count = 10 for i in range(1, count + 1): await asyncio.sleep(1) await manager.update({ "progress": i * 100 / count, }) await asyncio.sleep(1) await manager.done() dialog = Dialog( Window( Multi( Const("Your click is processing, please wait..."), Progress("progress", 10), ), state=Main.progress, getter=get_bg_data, ), ) @dp.message(Command("start")) async def start_handler(message: Message, dialog_manager: DialogManager): await dialog_manager.start(state=Main.progress) asyncio.create_task(background(dialog_manager.bg())) ``` -------------------------------- ### Generate and serve dialog previews Source: https://aiogram-dialog.readthedocs.io/en/stable/helper_tools/index.html Generate an HTML file for dialog previews using `render_preview` and serve it. This example demonstrates setting up a Dispatcher, including the dialog, and running the preview generation within an asyncio main function. ```python import asyncio from aiogram import Dispatcher from aiogram.filters.state import StatesGroup, State from aiogram_dialog import Dialog, Window from aiogram_dialog.tools import render_preview from aiogram_dialog.widgets.kbd import Cancel from aiogram_dialog.widgets.text import Format class RenderSG(StatesGroup): first = State() dialog = Dialog( Window( Format("Hello, {name}"), Cancel(), state=RenderSG.first, preview_data={"name": "Tishka17"}, ), ) dp = Dispatcher() dp.include_router(dialog) async def main(): await render_preview(dp, "preview.html") if __name__ == '__main__' asyncio.run(main()) ``` -------------------------------- ### dialog_manager.start Source: https://aiogram-dialog.readthedocs.io/en/stable/transitions/index.html Starts a new dialog by pushing it onto the stack. The dialog is identified by its starting state. ```APIDOC ## Method: dialog_manager.start ### Description Starts a new dialog. The dialog will have its own empty context and can receive initial data. ### Parameters - **state** (State) - Required - The starting state of the dialog. - **data** (dict) - Optional - Data to be stored in the dialog context, accessible via `dialog_manager.start_data`. - **mode** (StartMode) - Optional - Defines how the dialog is placed in the stack (e.g., NEW_STACK). ``` -------------------------------- ### Configuring LaunchMode Source: https://aiogram-dialog.readthedocs.io/en/stable/transitions/index.html Example of setting the launch_mode parameter in a Dialog definition to control stack behavior. ```python dialog = Dialog( Window(...), launch_mode=LaunchMode.SINGLE_TOP, ) ``` -------------------------------- ### ListGroup Example - Python Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/widgets/keyboard/list_group/index.rst.txt This example demonstrates the usage of the ListGroup widget for rendering a list of items with custom keyboard widgets and pagination. It requires importing necessary components from aiogram_dialog. ```python from aiogram_dialog.widgets.kbd import ListGroup, Button, Pager from aiogram_dialog.manager.manager import DialogManager from aiogram_dialog.manager.sub_manager import SubManager from aiogram_dialog.context.context import Context async def on_item_click(callback: CallbackQuery, widget: Button, dialog_manager: DialogManager): await dialog_manager.switch_to(State.items) async def get_items(context: Context, dialog_manager: DialogManager): return { ``` -------------------------------- ### Setup Dialog Middlewares Source: https://aiogram-dialog.readthedocs.io/en/stable/quickstart/index.html Register necessary middlewares and handlers for the dialog system. ```python from aiogram_dialog import setup_dialogs setup_dialogs(dp) ``` -------------------------------- ### Run Bot Source: https://aiogram-dialog.readthedocs.io/en/stable/quickstart/index.html Start the bot polling process. ```python if __name__ == '__main__': dp.run_polling(bot) ``` -------------------------------- ### Initialize a Counter Widget Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/counter/index.html Example showing how to define a Counter widget with a custom text click handler. ```python from aiogram_dialog.widgets.kbd import ManagedCounter, Counter async def on_text_click( event: CallbackQuery, widget: ManagedCounter, dialog_manager: DialogManager, ) -> None: await event.answer(f"Value: {widget.get_value()}") counter = Counter( id="someid", default=0, max_value=1000, on_text_click=on_text_click, ) ``` -------------------------------- ### TextInput Example Usage Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/input/text_input/index.html Example demonstrating the integration of the TextInput widget within an aiogram dialog. ```APIDOC ```python from typing import Any from aiogram.fsm.state import State, StatesGroup from aiogram.types import Message from aiogram_dialog import ( Dialog, DialogManager, Window, ) from aiogram_dialog.widgets.input import TextInput from aiogram_dialog.widgets.kbd import Next from aiogram_dialog.widgets.text import Const, Jinja class SG(StatesGroup): age = State() country = State() result = State() async def error( message: Message, dialog_: Any, manager: DialogManager, error_: ValueError ): await message.answer("Age must be a number!") async def getter(dialog_manager: DialogManager, **kwargs): return { "age": dialog_manager.find("age").get_value(), "country": dialog_manager.find("country").get_value(), } dialog = Dialog( Window( Const("Enter your country:"), TextInput(id="country", on_success=Next()), state=SG.country, ), Window( Const("Enter your age:"), TextInput( id="age", on_error=error, on_success=Next(), type_factory=int, ), state=SG.age, ), Window( Jinja( "You entered:\n\n" "age: {{age}}\n" "country: {{country}}\n" ), state=SG.result, getter=getter, parse_mode="html", ), ) ``` ``` -------------------------------- ### Start a Dialog with Command Handler Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/quickstart/index.rst.txt Create a command handler to initiate a dialog. Use DialogManager to start the dialog and optionally reset the stack to prevent multiple dialogs from running concurrently. ```python from aiogram.types import Message from aiogram_dialog import DialogManager @dp.message_handler(commands=["start"]) async def start_dialog(m: Message, dialog_manager: DialogManager): await dialog_manager.start(MyStates.first_state, reset_stack=True) ``` -------------------------------- ### Example Usage of TextInput Widget Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/widgets/input/text_input/index.rst.txt This example demonstrates how to use the TextInput widget for collecting and processing user text input. It includes type conversion and error handling. ```python from aiogram_dialog import Dialog, Window from aiogram_dialog.widgets.input import TextInput from aiogram_dialog.widgets.text import Const async def get_name(message: types.Message, widget: TextInput, dialog_manager: DialogManager): # This handler will be called when user enters text # widget is TextInput widget # dialog_manager is the manager for the current dialog await dialog_manager.switch_to(state=MyStates.next_state) async def on_error_name(message: types.Message, widget: TextInput, dialog_manager: DialogManager): # This handler will be called when user enters text and it is invalid await message.answer("Please enter a valid name") dialog = Dialog( Window( Const("Please enter your name:"), TextInput( id="name", type_factory=str, on_success=get_name, on_error=on_error_name, ), state=MyStates.input_name, ), # other windows ) ``` -------------------------------- ### Summary of aiogram-dialog Setup Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/quickstart/index.rst.txt This script provides a consolidated view of the essential components for setting up aiogram-dialog, including bot initialization, state management, dialog creation, and event handling. ```python from aiogram import Bot, Dispatcher, executor from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.contrib.fsm_storage.memory import MemoryStorage from aiogram_dialog import Dialog, DialogRegistry, Window from aiogram_dialog.widgets.text import Const from aiogram_dialog.widgets.kbd import Button from aiogram.types import Message from aiogram_dialog import DialogManager from aiogram_dialog import setup_dialogs BOT_TOKEN = "YOUR_BOT_TOKEN" class MyStates(StatesGroup): first_state = State() second_state = State() async def start_dialog(m: Message, dialog_manager: DialogManager): await dialog_manager.start(MyStates.first_state, reset_stack=True) my_window = Window( Const("This is the first window."), Button(Const("Next"), id="next_button"), state=MyStates.first_state ) my_dialog = Dialog( my_window, ) bot = Bot(token=BOT_TOKEN) storage = MemoryStorage() dp = Dispatcher(bot, storage=storage) registry = DialogRegistry(dp) registry.register(my_dialog) dp.register_message_handler(start_dialog, commands=["start"]) setup_dialogs(dp) if __name__ == "__main__": executor.start_polling(dp, skip_updates=True) ``` -------------------------------- ### Dialog Setup Changes in 2.0b18 Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/migration.rst.txt The `Registry` class has been removed. Each `Dialog` is now a `Router` and should be attached using `dp.include_router(dialog)`. `setup_dialogs` replaces `registry.setup_dp()`, and rendering methods now expect a `Dispatcher`, `Router`, or `Dialog` instance. ```python # dp.include_router(dialog) # setup_dialogs() # render_preview(dispatcher_or_router_or_dialog) # render_transitions(dispatcher_or_router_or_dialog) ``` -------------------------------- ### Implement ListGroup for dynamic product listing Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/list_group/index.html Example demonstrating how to use ListGroup to render a list of URLs based on a product data source provided by a getter. ```python from aiogram import F from aiogram.filters.state import State, StatesGroup from aiogram_dialog import ( Window, Dialog, ) from aiogram_dialog.widgets.kbd import ( Url, ListGroup, SwitchTo, Back, ) from aiogram_dialog.widgets.text import Const, Format class SG(StatesGroup): main = State() result = State() success = F["products"] fail = ~success async def actions(**kwargs): products = [ {"id": 1, "name": "Ferrari", "category": "car", "url": "https://www.ferrari.com/"}, {"id": 2, "name": "Detroit", "category": "game", "url": "https://wikipedia.org/wiki/Detroit:_Become_Human"}, ] return { "products": products, } dialog = Dialog( Window( Const("Click find products to show a list of available products:"), SwitchTo(Const("Find products"), id="search", state=SG.result), state=SG.main, ), Window( Const("Searching results:", when=success), Const("Search did not return any results", when=fail), ListGroup( Url( Format("{item[name]} ({item[category]})"), Format("{item[url]}"), id="url", ), id="select_search", item_id_getter=lambda item: item["id"], items="products", ), Back(Const("Back")), state=SG.result, getter=actions, ) ) ``` -------------------------------- ### Setup Dialogs Middlewares and Handlers Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/quickstart/index.rst.txt Call the `setup_dialogs` function to initialize necessary middlewares and core handlers for aiogram-dialog. Pass your Router or Dispatcher instance to this function. ```python from aiogram_dialog import setup_dialogs setup_dialogs(router) ``` -------------------------------- ### Style Widget Usage Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/style/index.html Example demonstrating how to create a Button with a custom style and emoji using the Style widget. ```APIDOC ## Button Style Types Style widgets can be used to customize most of keyboard widgets (e.g `Button`, `Checkbox` or `Calendar`). This includes color style (primary/danger/success) and emoji. ```python from aiogram.enums import ButtonStyle from aiogram_dialog.widgets.style import Style from aiogram_dialog.widgets.kbd import Button from aiogram_dialog.widgets.text import Const button = Button( Const("Ok"), id="okbtn", style=Style(style=ButtonStyle.PRIMARY, emoji_id="xxx"), ) ``` `Style` widget can have `when=` condition. Also, style widgets can be combined using operator `|` which requests data style/emoji from the next widgets if the first one returned None. ``` -------------------------------- ### aiogram_dialog.widgets.kbd.state.Start Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/start/index.html The Start class is a specialized button widget that triggers a dialog transition to a specified state. ```APIDOC ## Class: aiogram_dialog.widgets.kbd.state.Start ### Description A button widget that starts a new dialog when clicked, simplifying the transition process compared to manual dialog_manager.start calls. ### Parameters - **text** (TextWidget) - The text displayed on the button. - **id** (str) - Unique identifier for the widget. - **state** (State) - The target dialog state to start. - **data** (dict | list | int | str | float | None) - Data to pass to the new dialog. - **on_click** (Callable[[CallbackQuery, Button, DialogManager], Awaitable] | None) - Optional callback function executed on click. - **show_mode** (ShowMode | None) - Defines how the dialog is displayed. - **mode** (StartMode) - The start mode (default: StartMode.NORMAL). - **when** (str | MagicFilter | Predicate | None) - Condition to show the widget. - **style** (StyleWidget) - Styling object for the widget. ``` -------------------------------- ### Implement TextInput in a Dialog Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/input/text_input/index.html Example showing how to use TextInput with type conversion, error handling, and state management within a dialog window. ```python from typing import Any from aiogram.fsm.state import State, StatesGroup from aiogram.types import Message from aiogram_dialog import ( Dialog, DialogManager, Window, ) from aiogram_dialog.widgets.input import TextInput from aiogram_dialog.widgets.kbd import Next from aiogram_dialog.widgets.text import Const, Jinja class SG(StatesGroup): age = State() country = State() result = State() async def error( message: Message, dialog_: Any, manager: DialogManager, error_: ValueError ): await message.answer("Age must be a number!") async def getter(dialog_manager: DialogManager, **kwargs): return { "age": dialog_manager.find("age").get_value(), "country": dialog_manager.find("country").get_value(), } dialog = Dialog( Window( Const("Enter your country:"), TextInput(id="country", on_success=Next()), state=SG.country, ), Window( Const("Enter your age:"), TextInput( id="age", on_error=error, on_success=Next(), type_factory=int, ), state=SG.age, ), Window( Jinja( "You entered:\n\n" "age: {{age}}\n" "country: {{country}}\n" ), state=SG.result, getter=getter, parse_mode="html", ), ) ``` -------------------------------- ### Implement Multiselect Widget Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/widgets/keyboard/multiselect/index.rst.txt Example implementation of the Multiselect widget showing how to define checked and unchecked item texts. ```python Multiselect( Format("{item}"), id="m_select", item_id_getter=lambda x: x, items="items", ) ``` -------------------------------- ### Rendered HTML Output Example Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/text/jinja/index.html This is the expected HTML output generated from the Jinja template and provided data. ```html Animals list * Cat * Dog * My brother's tortoise ``` -------------------------------- ### Start Dialog Handler Source: https://aiogram-dialog.readthedocs.io/en/stable/quickstart/index.html Implement a command handler to trigger the dialog, using StartMode.RESET_STACK to prevent stacking. ```python from aiogram.filters import Command from aiogram.types import Message from aiogram_dialog import DialogManager, StartMode @dp.message(Command("start")) async def start(message: Message, dialog_manager: DialogManager): # Important: always set `mode=StartMode.RESET_STACK` you don't want to stack dialogs await dialog_manager.start(MySG.main, mode=StartMode.RESET_STACK) ``` -------------------------------- ### Starting a New Dialog Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/transitions/index.rst.txt Illustrates how to initiate a new dialog using `dialog_manager.start`. This method can be used to launch a dialog in the same stack or a new one, optionally passing initial data. ```python from aiogram_dialog import StartMode, DialogManager async def handler(event: DialogManager): await event.start( state="state_name", data={"key": "value"}, mode=StartMode.NEW_STACK ) ``` -------------------------------- ### Setup DialogRegistry with Dispatcher Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/quickstart/index.rst.txt Initialize the DialogRegistry and attach it to your aiogram dispatcher. Ensure you have a proper FSM storage configured as aiogram-dialog relies on FSMContext. ```python from aiogram import Bot, Dispatcher from aiogram.contrib.fsm_storage.memory import MemoryStorage from aiogram_dialog import DialogRegistry bot = Bot(token="YOUR_BOT_TOKEN") storage = MemoryStorage() dp = Dispatcher(bot, storage=storage) registry = DialogRegistry(dp) ``` -------------------------------- ### Example Button Implementation in Python Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/widgets/keyboard/button/index.rst.txt This snippet shows a basic implementation of a button with text, an ID, and an asynchronous callback function. The callback is automatically handled and does not require `callback.answer()`. ```python from aiogram_dialog import Dialog, Window from aiogram_dialog.widgets.text import Const from aiogram_dialog.widgets.kbd import Button def handler(event): print("Button clicked!") dialog = Dialog( Window( Const("Hello, world!\nClick the button below."), Button(Const("Click me!"), id="my_button", on_click=handler), state=0, ) ) ``` -------------------------------- ### Define Select Widget with Dynamic Items Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/select/index.html Example of creating a Select widget. It uses a Format for item text, a specific ID, an item ID getter, and fetches items from window data. An `on_click` handler is defined to process the selection. ```python import operator from typing import Any from aiogram.types import CallbackQuery from aiogram_dialog import DialogManager from aiogram_dialog.widgets.kbd import Select from aiogram_dialog.widgets.text import Format # let's assume this is our window data getter async def get_data(**kwargs): fruits = [ ("Apple", '1'), ("Pear", '2'), ("Orange", '3'), ("Banana", '4'), ] return { "fruits": fruits, "count": len(fruits), } async def on_fruit_selected(callback: CallbackQuery, widget: Any, manager: DialogManager, item_id: str): print("Fruit selected: ", item_id) fruits_kbd = Select( Format("{item[0]} ({pos}/{data[count]})"), # E.g `✓ Apple (1/4)` id="s_fruits", item_id_getter=operator.itemgetter(1), # each item is a tuple with id on a first position items="fruits", # we will use items from window data at a key `fruits` on_click=on_fruit_selected, ) ``` -------------------------------- ### Start the Bot Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/quickstart/index.rst.txt Start your aiogram bot using the standard `executor.start_polling` method. Ensure all configurations and setups are complete before running. ```python from aiogram import executor if __name__ == "__main__": executor.start_polling(dp, skip_updates=True) ``` -------------------------------- ### Example Usage of Column Widget Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/widgets/keyboard/column/index.rst.txt This snippet demonstrates how to use the Column widget to arrange elements vertically. No specific setup or imports are shown in this example. ```python from aiogram_dialog.widgets.common import Column from aiogram_dialog.widgets.text import Const from aiogram_dialog.widgets.custom import ForwardEvent async def handler(event: ForwardEvent): print(event.widget.widget_id) Column( Const("Hello"), Const("World"), id="col", ) ``` -------------------------------- ### Run web preview server Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/helper_tools/index.rst.txt Serve dialog previews via a web browser using the command-line interface. ```bash aiogram-dialog-preview path/to/dir/package.module:object_or_callable ``` -------------------------------- ### Initialize LoginURLButton Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/login_url/index.html Create a LoginURLButton instance with a text label and a target URL. The request_write_access parameter can be set to True to prompt the user for write permissions. ```python from aiogram_dialog.widgets.kbd import LoginURLButton from aiogram_dialog.widgets.text import Const login_btn = LoginURLButton( text=Const("Login"), url=Const("https://example.com/login"), request_write_access=True, ) ``` -------------------------------- ### Select Widget Initialization Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/select/index.html Documentation for the Select class constructor and its parameters. ```APIDOC ## class aiogram_dialog.widgets.kbd.Select ### Description Initializes a Select widget to display a dynamic list of selectable items. ### Parameters - **text** (TextWidget) - The text rendering logic for each item. - **id** (str) - Unique identifier for the widget. - **item_id_getter** (Callable[[Any], str|int]) - Function to extract an ID from an item. - **items** (str|Callable[[dict], Sequence]|MagicFilter|Sequence) - The collection of items to display. - **type_factory** (Callable[[str], T]) - Factory to convert string IDs to specific types. - **on_click** (OnItemClick|WidgetEventProcessor|None) - Callback triggered when an item is selected. - **when** (str|MagicFilter|Predicate|None) - Condition to show the widget. - **style** (StyleWidget) - Styling configuration. ``` -------------------------------- ### Implement LoginURLButton Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/widgets/keyboard/login_url/index.rst.txt This snippet demonstrates the basic configuration of a LoginURLButton with a label and authentication URL. ```python from aiogram_dialog.widgets.kbd import LoginURLButton from aiogram.types import LoginUrl LoginURLButton( text="Login", login_url=LoginUrl(url="https://example.com/login") ) ``` -------------------------------- ### Create a custom Calendar implementation Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/calendar/index.html Shows how to override _init_views to customize button text and headers, and _get_user_config to modify calendar settings like the first day of the week. ```python from aiogram_dialog import DialogManager from aiogram_dialog.widgets.kbd import ( Calendar, CalendarScope, CalendarUserConfig, ) from aiogram_dialog.widgets.kbd.calendar_kbd import ( CalendarDaysView, CalendarMonthView, CalendarScopeView, CalendarYearsView, ) from aiogram_dialog.widgets.text import Const, Format class CustomCalendar(Calendar): def _init_views(self) -> dict[CalendarScope, CalendarScopeView]: return { CalendarScope.DAYS: CalendarDaysView( self._item_callback_data, self.config, today_text=Format("***"), header_text=Format("> {date: %B %Y} <"), ), CalendarScope.MONTHS: CalendarMonthView( self._item_callback_data, self.config, ), CalendarScope.YEARS: CalendarYearsView( self._item_callback_data, self.config, ), } async def _get_user_config( self, data: dict, manager: DialogManager, ) -> CalendarUserConfig: return CalendarUserConfig( firstweekday=7, ) ``` -------------------------------- ### Start Shared Dialog in Group Stack Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/group_business.rst.txt Use this to start a shared dialog in a group stack, ensuring it's accessible within that group context. Requires importing GROUP_STACK_ID and StartMode. ```python bg = dialog_manager.bg(stack_id=GROUP_STACK_ID) bg.start( MyStateGroup.MY_STATE, mode=StartMode.RESET_STACK, ) ``` -------------------------------- ### Define a custom button click handler for starting a dialog Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/start/index.html Use this pattern when you need custom logic before starting a dialog. The `on_click` handler receives callback query, button, and dialog manager objects. ```python from aiogram_dialog.widgets.kbd import Button async def on_click( cq: CallbackQuery, button: Button, dialog_manager: DialogManager ): ... # your actions await dialog_manager.start(SOME_STATE, SOME_DATA) button = Button(..., on_click=on_click) ``` -------------------------------- ### Serve dialog previews via command line Source: https://aiogram-dialog.readthedocs.io/en/stable/helper_tools/index.html Serve dialog previews directly using the `aiogram-dialog-preview` command. Pass the path to your Dispatcher, Router, or Dialog object in the format `path/to/dir/package.module:object_or_callable`. ```bash aiogram-dialog-preview example/subdialog:dialog_router ``` -------------------------------- ### Implement Checkbox Widget Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/widgets/keyboard/checkbox/index.rst.txt Example usage of the Checkbox widget within an aiogram-dialog structure. ```python from aiogram_dialog.widgets.kbd import Checkbox from aiogram_dialog.widgets.text import Const checkbox = Checkbox( checked_text=Const("✓ Checked"), unchecked_text=Const("☐ Unchecked"), id="my_checkbox", on_state_changed=my_callback ) ``` -------------------------------- ### StartMode Replacement in 1.0 Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/migration.rst.txt The `reset_stack` option has been replaced by `StartMode`. For example, `reset_stack=True` is now `mode=StartMode.RESET_STACK`. ```python mode=StartMode.RESET_STACK ``` -------------------------------- ### StartMode Enumeration Source: https://aiogram-dialog.readthedocs.io/en/stable/transitions/index.html Defines the available modes for starting a new dialog within the aiogram-dialog framework. ```APIDOC ## StartMode Enum ### Description StartMode is an enumeration used to define how the current dialog stack should be handled when initiating a new dialog. ### Modes - **NORMAL** - Default mode. Continues from the current state without resetting or creating a new stack. - **RESET_STACK** - Clears the existing stack and starts fresh. Used when the existing stack needs to be discarded. - **NEW_STACK** - Initiates a new stack while retaining the old one. Useful for starting a new sequence of operations alongside the current one. ### Usage Example ```python async def start(message: Message, dialog_manager: DialogManager): await dialog_manager.start(..., mode=StartMode.RESET_STACK) ``` ``` -------------------------------- ### Initialize Dialog Source: https://aiogram-dialog.readthedocs.io/en/stable/quickstart/index.html Create a dialog instance using defined windows. ```python from aiogram_dialog import Dialog dialog = Dialog(main_window) ``` -------------------------------- ### Limiting Access to Dialogs Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/group_business.rst.txt Shows how to restrict access to a dialog to specific user IDs when starting it. ```APIDOC ## POST /start_dialog_with_access (Conceptual) ### Description Starts a dialog with specific access settings, limiting interaction to a predefined set of users. ### Method POST (Conceptual) ### Endpoint /start_dialog_with_access (Conceptual) ### Parameters #### Query Parameters - **mode** (string) - Optional - The mode to start the dialog in (e.g., `StartMode.RESET_STACK`). #### Request Body - **state** (object) - Required - The initial state of the dialog. - **access_settings** (object) - Required - Settings to control access to the dialog. - **user_ids** (array of integers) - Required - A list of user IDs allowed to interact with the dialog. ### Request Example ```python from aiogram_dialog import StartMode from aiogram_dialog.api.access import AccessSettings # Assuming dialog_manager is an instance of DialogManager dialog_manager.start( MyStateGroup.MY_STATE, mode=StartMode.RESET_STACK, access_settings=AccessSettings(user_ids=[123456]), ) ``` ### Response (No specific response details provided in the source text for this conceptual action.) ``` -------------------------------- ### Configure preview data Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/helper_tools/index.rst.txt Provide sample data for previewing windows using the preview_data parameter. ```python Window( ..., preview_data={"key": "value"}, ) ``` -------------------------------- ### Configure Dispatcher and Storage Source: https://aiogram-dialog.readthedocs.io/en/stable/quickstart/index.html Initialize the bot and dispatcher with FSM storage, which is required for dialog state management. ```python from aiogram import Bot, Dispatcher from aiogram.fsm.storage.memory import MemoryStorage storage = MemoryStorage() bot = Bot(token='BOT TOKEN HERE') dp = Dispatcher(storage=storage) ``` -------------------------------- ### LaunchMode and StartMode Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/transitions/index.rst.txt Documentation for LaunchMode and StartMode enums used to manage dialog stacks and initiation behavior. ```APIDOC ## LaunchMode ### Description LaunchMode is a mode for launching new dialogs, helping to manage the dialog stack and ensuring appropriate handling based on dialog type. ## StartMode ### Description StartMode defines how the current dialog stack should be handled when initiating a new dialog. ``` -------------------------------- ### Radio Widget Implementation Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/widgets/keyboard/radio/index.rst.txt Example implementation of the Radio widget showing how to define checked and unchecked states. ```python Radio( items="fruits", item_id_getter=lambda x: x, id="radio", checked_text=Format("✅ {item}"), unchecked_text=Format("❌ {item}"), ) ``` -------------------------------- ### Subdialog Result Callback in 1.0 Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/migration.rst.txt The signature of the `on_process_result` callback has changed. It now accepts the start data used to launch the subdialog. ```python # on_process_result callback now accepts start data used to start subdialog ``` -------------------------------- ### Using StaticMedia Widget with a File Path Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/media/static_media/index.html Demonstrates how to use the StaticMedia widget to share a media file using its local path. Ensure the path is correct and consider the working directory when using relative paths. The content type can be specified, and additional parameters can be passed via `media_params`. ```python from aiogram.types import ContentType from aiogram_dialog import Window from aiogram_dialog.widgets.media import StaticMedia windows = Window( StaticMedia( path="/home/tishka17/python_logo.png", type=ContentType.PHOTO, ), ) ``` -------------------------------- ### Render dialog preview Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/helper_tools/index.rst.txt Generate an HTML preview file by passing the router and target filename. ```python await render_preview("preview.html", router) ``` -------------------------------- ### Use magic_filter with Pager widgets Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/faq.rst.txt Example of using magic_filter to conditionally show pager widgets based on data returned by a getter. ```python from aiogram_dialog.widgets.kbd import NextPage from aiogram_dialog.widgets.text import Const from magic_filter import F next_page = NextPage( text=Const("Next page"), scroll="some_scroll", when=F["data"]["show_next_page"], ) ``` -------------------------------- ### Initialize SwitchInlineQuery Source: https://aiogram-dialog.readthedocs.io/en/stable/widgets/keyboard/switch_inline_query/index.html Creates an inline button that prompts the user to select a chat and inserts the specified query text. ```python from aiogram_dialog.widgets.kbd import SwitchInlineQuery from aiogram_dialog.widgets.text import Const switch_query = SwitchInlineQuery( Const("Some search"), # Button text Const("order") # Additional text to search ) ``` -------------------------------- ### Example Usage of SwitchInlineQueryCurrentChat Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/widgets/custom_widgets/switch_inline_query_current_chat/index.rst.txt This snippet demonstrates the usage of SwitchInlineQueryCurrentChat. It is similar to SwitchInlineQuery but specifically targets the current chat for inline queries. ```python from aiogram.types import InlineQuery, InputTextMessageContent, InlineQueryResultArticle from aiogram.utils.helper import InlineKeyboardBuilder async def inline_query_handler(query: InlineQuery): results = [] # Example: Create an inline query result results.append( InlineQueryResultArticle( id="unique_id", title="Example Result", input_message_content=InputTextMessageContent(message_text="This is a sample message."), reply_markup=InlineKeyboardBuilder().add( InlineKeyboardButton( text="Open in Current Chat", switch_inline_query_current_chat="some_query" ) ).as_markup() ) ) await query.answer(results, cache_time=1) ``` -------------------------------- ### Implement manual dialog transitions Source: https://aiogram-dialog.readthedocs.io/en/stable/transitions/index.html Demonstrates using DialogManager methods switch_to, back, and next to navigate between windows within a dialog. ```python from aiogram.filters.state import StatesGroup, State from aiogram.types import CallbackQuery from aiogram_dialog import Dialog, DialogManager, Window from aiogram_dialog.widgets.kbd import Button, Row from aiogram_dialog.widgets.text import Const class DialogSG(StatesGroup): first = State() second = State() third = State() async def to_second(callback: CallbackQuery, button: Button, manager: DialogManager): await manager.switch_to(DialogSG.second) async def go_back(callback: CallbackQuery, button: Button, manager: DialogManager): await manager.back() async def go_next(callback: CallbackQuery, button: Button, manager: DialogManager): await manager.next() dialog = Dialog( Window( Const("First"), Button(Const("To second"), id="sec", on_click=to_second), state=DialogSG.first, ), Window( Const("Second"), Row( Button(Const("Back"), id="back2", on_click=go_back), Button(Const("Next"), id="next2", on_click=go_next), ), state=DialogSG.second, ), Window( Const("Third"), Button(Const("Back"), id="back3", on_click=go_back), state=DialogSG.third, ) ) ``` -------------------------------- ### Import preview rendering method Source: https://aiogram-dialog.readthedocs.io/en/stable/_sources/helper_tools/index.rst.txt Import the function required to render dialog previews. ```python from aiogram_dialog.tools import render_preview ```