Skip to content

Commit 9fafe3e

Browse files
committed
Introduce Builder Pattern for Updater and Dispatcher (python-telegram-bot#2646)
1 parent b99045c commit 9fafe3e

Some content is hidden

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

45 files changed

+2265
-679
lines changed

.pre-commit-config.yaml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ repos:
1414
hooks:
1515
- id: flake8
1616
- repo: https://github.com/PyCQA/pylint
17-
rev: v2.8.3
17+
rev: v2.10.2
1818
hooks:
1919
- id: pylint
2020
files: ^(telegram|examples)/.*\.py$
@@ -27,12 +27,17 @@ repos:
2727
- cachetools==4.2.2
2828
- . # this basically does `pip install -e .`
2929
- repo: https://github.com/pre-commit/mirrors-mypy
30-
rev: v0.812
30+
rev: v0.910
3131
hooks:
3232
- id: mypy
3333
name: mypy-ptb
3434
files: ^telegram/.*\.py$
3535
additional_dependencies:
36+
- types-ujson
37+
- types-pytz
38+
- types-cryptography
39+
- types-certifi
40+
- types-cachetools
3641
- certifi
3742
- tornado>=6.1
3843
- APScheduler==3.6.3
@@ -51,7 +56,7 @@ repos:
5156
- cachetools==4.2.2
5257
- . # this basically does `pip install -e .`
5358
- repo: https://github.com/asottile/pyupgrade
54-
rev: v2.19.1
59+
rev: v2.24.0
5560
hooks:
5661
- id: pyupgrade
5762
files: ^(telegram|examples|tests)/.*\.py$
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
:github_url: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/telegram/ext/builders.py
2+
3+
telegram.ext.DispatcherBuilder
4+
==============================
5+
6+
.. autoclass:: telegram.ext.DispatcherBuilder
7+
:members:

docs/source/telegram.ext.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ telegram.ext package
44
.. toctree::
55

66
telegram.ext.extbot
7+
telegram.ext.updaterbuilder
78
telegram.ext.updater
9+
telegram.ext.dispatcherbuilder
810
telegram.ext.dispatcher
911
telegram.ext.dispatcherhandlerstop
1012
telegram.ext.callbackcontext
@@ -61,4 +63,5 @@ utils
6163
.. toctree::
6264

6365
telegram.ext.utils.promise
66+
telegram.ext.utils.stack
6467
telegram.ext.utils.types
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
:github_url: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/telegram/ext/builders.py
2+
3+
telegram.ext.UpdaterBuilder
4+
===========================
5+
6+
.. autoclass:: telegram.ext.UpdaterBuilder
7+
:members:
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
:github_url: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/telegram/ext/utils/stack.py
2+
3+
telegram.ext.utils.stack Module
4+
================================
5+
6+
.. automodule:: telegram.ext.utils.stack
7+
:members:
8+
:show-inheritance:

examples/arbitrarycallbackdatabot.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,40 @@
1111

1212
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
1313
from telegram.ext import (
14-
Updater,
1514
CommandHandler,
1615
CallbackQueryHandler,
17-
CallbackContext,
1816
InvalidCallbackData,
1917
PicklePersistence,
18+
Updater,
19+
CallbackContext,
2020
)
2121

22+
23+
# Enable logging
2224
logging.basicConfig(
2325
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
2426
)
2527
logger = logging.getLogger(__name__)
2628

2729

28-
def start(update: Update, context: CallbackContext) -> None:
30+
def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
2931
"""Sends a message with 5 inline buttons attached."""
3032
number_list: List[int] = []
3133
update.message.reply_text('Please choose:', reply_markup=build_keyboard(number_list))
3234

3335

34-
def help_command(update: Update, context: CallbackContext) -> None:
36+
def help_command(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
3537
"""Displays info on how to use the bot."""
3638
update.message.reply_text(
3739
"Use /start to test this bot. Use /clear to clear the stored data so that you can see "
3840
"what happens, if the button data is not available. "
3941
)
4042

4143

42-
def clear(update: Update, context: CallbackContext) -> None:
44+
def clear(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
4345
"""Clears the callback data cache"""
44-
context.bot.callback_data_cache.clear_callback_data() # type: ignore[attr-defined]
45-
context.bot.callback_data_cache.clear_callback_queries() # type: ignore[attr-defined]
46+
context.bot.callback_data_cache.clear_callback_data()
47+
context.bot.callback_data_cache.clear_callback_queries()
4648
update.effective_message.reply_text('All clear!')
4749

4850

@@ -53,7 +55,7 @@ def build_keyboard(current_list: List[int]) -> InlineKeyboardMarkup:
5355
)
5456

5557

56-
def list_button(update: Update, context: CallbackContext) -> None:
58+
def list_button(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
5759
"""Parses the CallbackQuery and updates the message text."""
5860
query = update.callback_query
5961
query.answer()
@@ -73,7 +75,7 @@ def list_button(update: Update, context: CallbackContext) -> None:
7375
context.drop_callback_data(query)
7476

7577

76-
def handle_invalid_button(update: Update, context: CallbackContext) -> None:
78+
def handle_invalid_button(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
7779
"""Informs the user that the button is no longer available."""
7880
update.callback_query.answer()
7981
update.effective_message.edit_text(
@@ -86,7 +88,13 @@ def main() -> None:
8688
# We use persistence to demonstrate how buttons can still work after the bot was restarted
8789
persistence = PicklePersistence(filepath='arbitrarycallbackdatabot')
8890
# Create the Updater and pass it your bot's token.
89-
updater = Updater("TOKEN", persistence=persistence, arbitrary_callback_data=True)
91+
updater = (
92+
Updater.builder()
93+
.token("TOKEN")
94+
.persistence(persistence)
95+
.arbitrary_callback_data(True)
96+
.build()
97+
)
9098

9199
updater.dispatcher.add_handler(CommandHandler('start', start))
92100
updater.dispatcher.add_handler(CommandHandler('help', help_command))

examples/chatmemberbot.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@
1616

1717
from telegram import Update, Chat, ChatMember, ParseMode, ChatMemberUpdated
1818
from telegram.ext import (
19-
Updater,
2019
CommandHandler,
21-
CallbackContext,
2220
ChatMemberHandler,
21+
Updater,
22+
CallbackContext,
2323
)
2424

2525
# Enable logging
26+
2627
logging.basicConfig(
2728
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
2829
)
@@ -66,7 +67,7 @@ def extract_status_change(
6667
return was_member, is_member
6768

6869

69-
def track_chats(update: Update, context: CallbackContext) -> None:
70+
def track_chats(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
7071
"""Tracks the chats the bot is in."""
7172
result = extract_status_change(update.my_chat_member)
7273
if result is None:
@@ -101,7 +102,7 @@ def track_chats(update: Update, context: CallbackContext) -> None:
101102
context.bot_data.setdefault("channel_ids", set()).discard(chat.id)
102103

103104

104-
def show_chats(update: Update, context: CallbackContext) -> None:
105+
def show_chats(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
105106
"""Shows which chats the bot is in"""
106107
user_ids = ", ".join(str(uid) for uid in context.bot_data.setdefault("user_ids", set()))
107108
group_ids = ", ".join(str(gid) for gid in context.bot_data.setdefault("group_ids", set()))
@@ -114,7 +115,7 @@ def show_chats(update: Update, context: CallbackContext) -> None:
114115
update.effective_message.reply_text(text)
115116

116117

117-
def greet_chat_members(update: Update, context: CallbackContext) -> None:
118+
def greet_chat_members(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
118119
"""Greets new users in chats and announces when someone leaves"""
119120
result = extract_status_change(update.chat_member)
120121
if result is None:
@@ -139,7 +140,7 @@ def greet_chat_members(update: Update, context: CallbackContext) -> None:
139140
def main() -> None:
140141
"""Start the bot."""
141142
# Create the Updater and pass it your bot's token.
142-
updater = Updater("TOKEN")
143+
updater = Updater.builder().token("TOKEN").build()
143144

144145
# Get the dispatcher to register handlers
145146
dispatcher = updater.dispatcher

examples/contexttypesbot.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515

1616
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, ParseMode
1717
from telegram.ext import (
18-
Updater,
1918
CommandHandler,
2019
CallbackContext,
2120
ContextTypes,
2221
CallbackQueryHandler,
2322
TypeHandler,
2423
Dispatcher,
24+
ExtBot,
25+
Updater,
2526
)
2627

2728

@@ -32,8 +33,8 @@ def __init__(self) -> None:
3233
self.clicks_per_message: DefaultDict[int, int] = defaultdict(int)
3334

3435

35-
# The [dict, ChatData, dict] is for type checkers like mypy
36-
class CustomContext(CallbackContext[dict, ChatData, dict]):
36+
# The [ExtBot, dict, ChatData, dict] is for type checkers like mypy
37+
class CustomContext(CallbackContext[ExtBot, dict, ChatData, dict]):
3738
"""Custom class for context."""
3839

3940
def __init__(self, dispatcher: Dispatcher):
@@ -113,7 +114,7 @@ def track_users(update: Update, context: CustomContext) -> None:
113114
def main() -> None:
114115
"""Run the bot."""
115116
context_types = ContextTypes(context=CustomContext, chat_data=ChatData)
116-
updater = Updater("TOKEN", context_types=context_types)
117+
updater = Updater.builder().token("TOKEN").context_types(context_types).build()
117118

118119
dispatcher = updater.dispatcher
119120
# run track_users in its own group to not interfere with the user handlers

examples/conversationbot.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,25 @@
1818

1919
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
2020
from telegram.ext import (
21-
Updater,
2221
CommandHandler,
2322
MessageHandler,
2423
Filters,
2524
ConversationHandler,
25+
Updater,
2626
CallbackContext,
2727
)
2828

29+
2930
# Enable logging
3031
logging.basicConfig(
3132
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
3233
)
33-
3434
logger = logging.getLogger(__name__)
3535

3636
GENDER, PHOTO, LOCATION, BIO = range(4)
3737

3838

39-
def start(update: Update, context: CallbackContext) -> int:
39+
def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
4040
"""Starts the conversation and asks the user about their gender."""
4141
reply_keyboard = [['Boy', 'Girl', 'Other']]
4242

@@ -52,7 +52,7 @@ def start(update: Update, context: CallbackContext) -> int:
5252
return GENDER
5353

5454

55-
def gender(update: Update, context: CallbackContext) -> int:
55+
def gender(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
5656
"""Stores the selected gender and asks for a photo."""
5757
user = update.message.from_user
5858
logger.info("Gender of %s: %s", user.first_name, update.message.text)
@@ -65,7 +65,7 @@ def gender(update: Update, context: CallbackContext) -> int:
6565
return PHOTO
6666

6767

68-
def photo(update: Update, context: CallbackContext) -> int:
68+
def photo(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
6969
"""Stores the photo and asks for a location."""
7070
user = update.message.from_user
7171
photo_file = update.message.photo[-1].get_file()
@@ -78,7 +78,7 @@ def photo(update: Update, context: CallbackContext) -> int:
7878
return LOCATION
7979

8080

81-
def skip_photo(update: Update, context: CallbackContext) -> int:
81+
def skip_photo(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
8282
"""Skips the photo and asks for a location."""
8383
user = update.message.from_user
8484
logger.info("User %s did not send a photo.", user.first_name)
@@ -89,7 +89,7 @@ def skip_photo(update: Update, context: CallbackContext) -> int:
8989
return LOCATION
9090

9191

92-
def location(update: Update, context: CallbackContext) -> int:
92+
def location(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
9393
"""Stores the location and asks for some info about the user."""
9494
user = update.message.from_user
9595
user_location = update.message.location
@@ -103,7 +103,7 @@ def location(update: Update, context: CallbackContext) -> int:
103103
return BIO
104104

105105

106-
def skip_location(update: Update, context: CallbackContext) -> int:
106+
def skip_location(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
107107
"""Skips the location and asks for info about the user."""
108108
user = update.message.from_user
109109
logger.info("User %s did not send a location.", user.first_name)
@@ -114,7 +114,7 @@ def skip_location(update: Update, context: CallbackContext) -> int:
114114
return BIO
115115

116116

117-
def bio(update: Update, context: CallbackContext) -> int:
117+
def bio(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
118118
"""Stores the info about the user and ends the conversation."""
119119
user = update.message.from_user
120120
logger.info("Bio of %s: %s", user.first_name, update.message.text)
@@ -123,7 +123,7 @@ def bio(update: Update, context: CallbackContext) -> int:
123123
return ConversationHandler.END
124124

125125

126-
def cancel(update: Update, context: CallbackContext) -> int:
126+
def cancel(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
127127
"""Cancels and ends the conversation."""
128128
user = update.message.from_user
129129
logger.info("User %s canceled the conversation.", user.first_name)
@@ -137,7 +137,7 @@ def cancel(update: Update, context: CallbackContext) -> int:
137137
def main() -> None:
138138
"""Run the bot."""
139139
# Create the Updater and pass it your bot's token.
140-
updater = Updater("TOKEN")
140+
updater = Updater.builder().token("TOKEN").build()
141141

142142
# Get the dispatcher to register handlers
143143
dispatcher = updater.dispatcher

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy