Update FSM example.

This commit is contained in:
Alex Root Junior 2018-09-21 22:44:11 +03:00
parent 2c749e485f
commit 88c5b3a606
4 changed files with 15 additions and 158 deletions

View file

@ -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-

View file

@ -9,7 +9,6 @@ Examples
adwanced_executor_example adwanced_executor_example
proxy_and_emojize proxy_and_emojize
finite_state_machine_example finite_state_machine_example
finite_state_machine_example_2
throtling_example throtling_example
i18n_example i18n_example
regexp_commands_filter_example regexp_commands_filter_example

View file

@ -59,9 +59,10 @@ async def process_name(message: types.Message, state: FSMContext):
""" """
Process user name Process user name
""" """
await Form.next() async with state.proxy() as data:
await state.update_data(name=message.text) data['name'] = message.text
await Form.next()
await message.reply("How old are you?") 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) @dp.message_handler(state=Form.gender)
async def process_gender(message: types.Message, state: FSMContext): async def process_gender(message: types.Message, state: FSMContext):
data = await state.get_data() async with state.proxy() as data:
data['gender'] = message.text data['gender'] = message.text
# Remove keyboard # Remove keyboard
markup = types.ReplyKeyboardRemove() markup = types.ReplyKeyboardRemove()
# And send message # And send message
await bot.send_message(message.chat.id, md.text( await bot.send_message(message.chat.id, md.text(
md.text('Hi! Nice to meet you,', md.bold(data['name'])), md.text('Hi! Nice to meet you,', md.bold(data['name'])),
md.text('Age:', data['age']), md.text('Age:', data['age']),
md.text('Gender:', data['gender']), md.text('Gender:', data['gender']),
sep='\n'), reply_markup=markup, parse_mode=ParseMode.MARKDOWN) sep='\n'), reply_markup=markup, parse_mode=ParseMode.MARKDOWN)
# Finish conversation # Finish conversation
# WARNING! This method will destroy all data in storage for current user! data.state = None
await state.finish()
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -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)