Wrapper around the telegram.keyboard object (keyboard_markup, reply and inline)Β #4608
Description
What kind of feature are you missing? Where do you notice a shortcoming of PTB?
I want to use the.keyboard as a set of buttons rather than a nested list of rows, which are hard to manage and modify.
Indeed, I don't care which row or column contains my button.
Rows and columns are the technically unique identifiers of the button, but for human readability, the button's actual text is better because there can't be two identical buttons in the same keyboard.
In my opinion, it would be a nice fit into the telegram.ext
package as the next generation of the keyboard object that we already have.
Prerequisites:
Looking for a proper button object in a nested loop is always tedious and requires some concentration and time.
Most medium and large PTB bots require a custom Button class to respect the DRY principle and keep the code clean.
Let's do it out of the box!
Describe the solution you'd like
I think it would be nice if you would add this feature.
See the possible usage example:
Notice:
keyboard = update.message.keyboard # incoming keyboard
Return type depend on the PTB policy because PTB objects are immutable.
# Text and callback modification example
keyboard.buttons.order_the_pizza.edit_text(new_text='pizza succussfuly ordered')
# or
keyboard.buttons.order_the_pizza.text = 'pizza succussfuly ordered'
# Callback modification example:
keyboard.buttons.some_emoji.callback = 'foo'
# Another possible method names: change order | update_index | set_priority, etc.
# Pattern example:
# P.S. Read only access to the patterns
print(keyboard.pattern)
print(keyboard.buttons.coffee.pattern)
# Order modification example:
keyboard.buttons.breaking_news.change_position(new_row_index=-1, new_column_index=2)
# Another possible method names: change order | update_index, etc.
# Another sample:
last_button_text = keyboard.buttons[-1][-1].text # index access are also possible.
# Order aliases:
# Even more progressive way: buttons.last means buttons[-1][-1]
# The "last" name reserved but does the "last" may mean something else except the "last" button itself?
last_button = keyboard.buttons.last
# The same with a row:
last_row = keyboard.rows.last
first_column = keyboard.columns.first
fifty_column = keyboard.columns.fifty
from dataclasses import dataclass
from telegram import InlineKeyboardButton
@dataclass # The struct of the button
class ButtonWrapper(InlineKeyboardButton):
row_index: int # new
column_index: int # new
text: int
callback: int
... # all other regular attrs of InlineKeyboardButton
# Many possible useful methods and shortcuts
Internal implementation:
- The wrapper itself resembles the
SimpleNamespace
Python class or theDataclass
. - Order aliases (first, second, fifth, etc.) resemble the
Enum
. - Order aliases may accept an optional strict policy as a parameter.
Soft - If the count of buttons is less than the order alias (only two buttons in a row, for example), return the second button.
Mediate - returnsNone
.
Hard - raisesIndexError
.
Activity