From 88c5b3a606dcea8c3ac88b0eb9b98c83a5faf734 Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Fri, 21 Sep 2018 22:44:11 +0300 Subject: [PATCH] Update FSM example. --- .../finite_state_machine_example_2.rst | 16 --- docs/source/examples/index.rst | 1 - examples/finite_state_machine_example.py | 30 ++--- examples/finite_state_machine_example_2.py | 126 ------------------ 4 files changed, 15 insertions(+), 158 deletions(-) delete mode 100644 docs/source/examples/finite_state_machine_example_2.rst delete mode 100644 examples/finite_state_machine_example_2.py diff --git a/docs/source/examples/finite_state_machine_example_2.rst b/docs/source/examples/finite_state_machine_example_2.rst deleted file mode 100644 index a0c6c1a0..00000000 --- a/docs/source/examples/finite_state_machine_example_2.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. Autogenerated file at 2018-09-08 02:07:37.580949 - -============================== -Finite state machine example 2 -============================== - -This example is equals with 'finite_state_machine_example.py' but with FSM Middleware -Note that FSM Middleware implements the more simple methods for working with storage. -With that middleware all data from storage will be loaded before event will be processed -and data will be stored after processing the event. - -.. literalinclude:: ../../../examples/finite_state_machine_example_2.py - :caption: finite_state_machine_example_2.py - :language: python - :linenos: - :lines: 9- diff --git a/docs/source/examples/index.rst b/docs/source/examples/index.rst index 3028819c..ab417bf4 100644 --- a/docs/source/examples/index.rst +++ b/docs/source/examples/index.rst @@ -9,7 +9,6 @@ Examples adwanced_executor_example proxy_and_emojize finite_state_machine_example - finite_state_machine_example_2 throtling_example i18n_example regexp_commands_filter_example diff --git a/examples/finite_state_machine_example.py b/examples/finite_state_machine_example.py index 7a989e5b..58b8053c 100644 --- a/examples/finite_state_machine_example.py +++ b/examples/finite_state_machine_example.py @@ -59,9 +59,10 @@ async def process_name(message: types.Message, state: FSMContext): """ Process user name """ - await Form.next() - await state.update_data(name=message.text) + async with state.proxy() as data: + data['name'] = message.text + await Form.next() await message.reply("How old are you?") @@ -98,22 +99,21 @@ async def failed_process_gender(message: types.Message): @dp.message_handler(state=Form.gender) async def process_gender(message: types.Message, state: FSMContext): - data = await state.get_data() - data['gender'] = message.text + async with state.proxy() as data: + data['gender'] = message.text - # Remove keyboard - markup = types.ReplyKeyboardRemove() + # Remove keyboard + markup = types.ReplyKeyboardRemove() - # And send message - await bot.send_message(message.chat.id, md.text( - md.text('Hi! Nice to meet you,', md.bold(data['name'])), - md.text('Age:', data['age']), - md.text('Gender:', data['gender']), - sep='\n'), reply_markup=markup, parse_mode=ParseMode.MARKDOWN) + # And send message + await bot.send_message(message.chat.id, md.text( + md.text('Hi! Nice to meet you,', md.bold(data['name'])), + md.text('Age:', data['age']), + md.text('Gender:', data['gender']), + sep='\n'), reply_markup=markup, parse_mode=ParseMode.MARKDOWN) - # Finish conversation - # WARNING! This method will destroy all data in storage for current user! - await state.finish() + # Finish conversation + data.state = None if __name__ == '__main__': diff --git a/examples/finite_state_machine_example_2.py b/examples/finite_state_machine_example_2.py deleted file mode 100644 index 5a2996bd..00000000 --- a/examples/finite_state_machine_example_2.py +++ /dev/null @@ -1,126 +0,0 @@ -""" -This example is equals with 'finite_state_machine_example.py' but with FSM Middleware - -Note that FSM Middleware implements the more simple methods for working with storage. - -With that middleware all data from storage will be loaded before event will be processed -and data will be stored after processing the event. -""" -import asyncio - -import aiogram.utils.markdown as md -from aiogram import Bot, Dispatcher, types -from aiogram.contrib.fsm_storage.memory import MemoryStorage -from aiogram.contrib.middlewares.fsm import FSMMiddleware, FSMSStorageProxy -from aiogram.dispatcher.filters.state import State, StatesGroup -from aiogram.utils import executor - -API_TOKEN = 'BOT TOKEN HERE' - -loop = asyncio.get_event_loop() - -bot = Bot(token=API_TOKEN, loop=loop) - -# For example use simple MemoryStorage for Dispatcher. -storage = MemoryStorage() -dp = Dispatcher(bot, storage=storage) -dp.middleware.setup(FSMMiddleware()) - - -# States -class Form(StatesGroup): - name = State() # Will be represented in storage as 'Form:name' - age = State() # Will be represented in storage as 'Form:age' - gender = State() # Will be represented in storage as 'Form:gender' - - -@dp.message_handler(commands=['start']) -async def cmd_start(message: types.Message): - """ - Conversation's entry point - """ - # Set state - await Form.first() - - await message.reply("Hi there! What's your name?") - - -# You can use state '*' if you need to handle all states -@dp.message_handler(state='*', commands=['cancel']) -@dp.message_handler(lambda message: message.text.lower() == 'cancel', state='*') -async def cancel_handler(message: types.Message, state_data: FSMSStorageProxy): - """ - Allow user to cancel any action - """ - if state_data.state is None: - return - - # Cancel state and inform user about it - del state_data.state - # And remove keyboard (just in case) - await message.reply('Canceled.', reply_markup=types.ReplyKeyboardRemove()) - - -@dp.message_handler(state=Form.name) -async def process_name(message: types.Message, state_data: FSMSStorageProxy): - """ - Process user name - """ - state_data.state = Form.age - state_data['name'] = message.text - - await message.reply("How old are you?") - - -# Check age. Age gotta be digit -@dp.message_handler(lambda message: not message.text.isdigit(), state=Form.age) -async def failed_process_age(message: types.Message): - """ - If age is invalid - """ - return await message.reply("Age gotta be a number.\nHow old are you? (digits only)") - - -@dp.message_handler(lambda message: message.text.isdigit(), state=Form.age) -async def process_age(message: types.Message, state_data: FSMSStorageProxy): - # Update state and data - state_data.state = Form.gender - state_data['age'] = int(message.text) - - # Configure ReplyKeyboardMarkup - markup = types.ReplyKeyboardMarkup(resize_keyboard=True, selective=True) - markup.add("Male", "Female") - markup.add("Other") - - await message.reply("What is your gender?", reply_markup=markup) - - -@dp.message_handler(lambda message: message.text not in ["Male", "Female", "Other"], state=Form.gender) -async def failed_process_gender(message: types.Message): - """ - In this example gender has to be one of: Male, Female, Other. - """ - return await message.reply("Bad gender name. Choose you gender from keyboard.") - - -@dp.message_handler(state=Form.gender) -async def process_gender(message: types.Message, state_data: FSMSStorageProxy): - state_data['gender'] = message.text - - # Remove keyboard - markup = types.ReplyKeyboardRemove() - - # And send message - await bot.send_message(message.chat.id, md.text( - md.text('Hi! Nice to meet you,', md.bold(state_data['name'])), - md.text('Age:', state_data['age']), - md.text('Gender:', state_data['gender']), - sep='\n'), reply_markup=markup, parse_mode=types.ParseMode.MARKDOWN) - - # Finish conversation - # WARNING! This method will destroy all data in storage for current user! - state_data.clear() - - -if __name__ == '__main__': - executor.start_polling(dp, loop=loop, skip_updates=True)