Question: How to shutdown properly? #801
I really fear to bring up a question that was answered 1000 times now but since i searched the issues and didn’t find anything related, examples didn’t include anything relevant and i didn’t get a satisfying answer in the telegram group, i have to ask:
How to shutdown the bot without executing another script with
os.execl(os.dirname(__file__) + ‘/shutdown.py’, ‘—‘) ?
Is this really the only way to shutdown? Seems weird (in my case) to create an empty script that is just there to server the purpose to shutdown. I don’t want to dump anything on exit. I would really just like to shutdown cleanly and easily. I can’t imagine that this is such a huge problem.
EDIT: Well, not even the provided example works. I didn’t test it before because it’s not an option for me
Application¶
This class dispatches all kinds of updates to its registered handlers, and is the entry point to a PTB application.
This class may not be initialized directly. Use telegram.ext.ApplicationBuilder or builder() (for convenience).
Instances of this class can be used as asyncio context managers, where
is roughly equivalent to
Changed in version 20.0:
Initialization is now done through the telegram.ext.ApplicationBuilder .
Removed the attribute groups .
The bot object that should be passed to the handlers.
The synchronized queue that will contain the updates.
Optional. The updater used by this application.
A dictionary handlers can use to store data for the chat. For each integer chat id, the corresponding value of this mapping is available as telegram.ext.CallbackContext.chat_data in handler callbacks for updates from that chat.
Changed in version 20.0: chat_data is now read-only. Note that the values of the mapping are still mutable, i.e. editing context.chat_data within a handler callback is possible (and encouraged), but editing the mapping application.chat_data itself is not.
Manually modifying chat_data is almost never needed and unadvisable.
Entries are never deleted automatically from this mapping. If you want to delete the data associated with a specific chat, e.g. if the bot got removed from that chat, please use drop_chat_data() .
A dictionary handlers can use to store data for the user. For each integer user id, the corresponding value of this mapping is available as telegram.ext.CallbackContext.user_data in handler callbacks for updates from that user.
Changed in version 20.0: user_data is now read-only. Note that the values of the mapping are still mutable, i.e. editing context.user_data within a handler callback is possible (and encouraged), but editing the mapping application.user_data itself is not.
Manually modifying user_data is almost never needed and unadvisable.
Entries are never deleted automatically from this mapping. If you want to delete the data associated with a specific user, e.g. if that user blocked the bot, please use drop_user_data() .
A dictionary handlers can use to store data for the bot.
The persistence class to store data that should be persistent over restarts.
A dictionary mapping each handler group to the list of handlers registered to that group.
A dictionary where the keys are error handlers and the values indicate whether they are to be run blocking.
Specifies the types used by this dispatcher for the context argument of handler and job callbacks.
Optional. A callback that will be executed by Application.run_polling() and Application.run_webhook() after initializing the application via initialize() .
Optional. A callback that will be executed by Application.run_polling() and Application.run_webhook() after shutting down the application via shutdown() .
Optional. A callback that will be executed by Application.run_polling() and Application.run_webhook() after stopping the application via stop() .
New in version 20.1.
add_error_handler ( callback , block = True ) [source] ¶
Registers an error handler in the Application. This handler will receive every error which happens in your bot. See the docs of process_error() for more details on how errors are handled.
Attempts to add the same callback multiple times will be ignored.
The callback function for this error handler. Will be called when an error is raised. Callback signature:
The error that happened will be present in telegram.ext.CallbackContext.error .
block ( bool , optional) – Determines whether the return value of the callback should be awaited before processing the next error handler in process_error() . Defaults to True .
Register a handler.
TL;DR: Order and priority counts. 0 or 1 handlers per group will be used. End handling of update with telegram.ext.ApplicationHandlerStop .
A handler must be an instance of a subclass of telegram.ext.BaseHandler . All handlers are organized in groups with a numeric value. The default group is 0. All groups will be evaluated for handling an update, but only 0 or 1 handler per group will be used. If telegram.ext.ApplicationHandlerStop is raised from one of the handlers, no further handlers (regardless of the group) will be called.
The priority/order of handlers is determined as follows:
-
Priority of the group (lower group number == higher priority)
-
The first handler in a group which can handle an update (see telegram.ext.BaseHandler.check_update ) will be used. Other handlers from the group will not be used. The order in which handlers were added to the group defines the priority.
Adding persistent telegram.ext.ConversationHandler after the application has been initialized is discouraged. This is because the persisted conversation states need to be loaded into memory while the application is already processing updates, which might lead to race conditions and undesired behavior. In particular, current conversation states may be overridden by the loaded data.
group ( int , optional) – The group identifier. Default is 0 .
Registers multiple handlers at once. The order of the handlers in the passed sequence(s) matters. See add_handler() for details.
New in version 20.0.
handlers (List[ telegram.ext.BaseHandler ] | Dict[int, List[ telegram.ext.BaseHandler ]]) – Specify a sequence of handlers or a dictionary where the keys are groups and values are handlers.
group ( int , optional) – Specify which group the sequence of handlers should be added to. Defaults to 0 .
New in version 20.0.
The number of concurrent updates that will be processed in parallel. A value of 0 indicates updates are not being processed concurrently.
Changed in version NEXT.VERSION: This is now just a shortcut to update_processor.max_concurrent_updates .
create_task ( coroutine , update = None ) [source] ¶
Thin wrapper around asyncio.create_task() that handles exceptions raised by the coroutine with process_error() .
If coroutine raises an exception, it will be set on the task created by this method even though it’s handled by process_error() .
If the application is currently running, tasks created by this method will be awaited with stop() .
The awaitable to run as task.
Changed in version 20.2: Accepts asyncio.Future and generator-based coroutine functions.
update ( object , optional) – If set, will be passed to process_error() as additional information for the error handlers. Moreover, the corresponding chat_data and user_data entries will be updated in the next run of update_persistence() after the coroutine is finished.
The created task.
Drops the corresponding entry from the chat_data . Will also be deleted from the persistence on the next run of update_persistence() , if applicable.
When using concurrent_updates or the job_queue , process_update() or telegram.ext.Job.run() may re-create this entry due to the asynchronous nature of these features. Please make sure that your program can avoid or handle such situations.
New in version 20.0.
chat_id ( int ) – The chat id to delete. The entry will be deleted even if it is not empty.
Drops the corresponding entry from the user_data . Will also be deleted from the persistence on the next run of update_persistence() , if applicable.
When using concurrent_updates or the job_queue , process_update() or telegram.ext.Job.run() may re-create this entry due to the asynchronous nature of these features. Please make sure that your program can avoid or handle such situations.
New in version 20.0.
user_id ( int ) – The user id to delete. The entry will be deleted even if it is not empty.
Initializes the Application by initializing:
The persistence , by loading persistent conversations and data.
mark_data_for_update_persistence ( chat_ids = None , user_ids = None ) [source] ¶
Mark entries of chat_data and user_data to be updated on the next run of update_persistence() .
Use this method sparingly. If you have to use this method, it likely means that you access and modify context.application.chat/user_data[some_id] within a callback. Note that for data which should be available globally in all handler callbacks independent of the chat/user, it is recommended to use bot_data instead.
New in version 20.3.
chat_ids ( int | Collection[ int ], optional) – Chat IDs to mark.
user_ids ( int | Collection[ int ], optional) – User IDs to mark.
Moves the contents of chat_data at key old_chat_id to the key new_chat_id . Also marks the entries to be updated accordingly in the next run of update_persistence() .
Any data stored in chat_data at key new_chat_id will be overridden
The key old_chat_id of chat_data will be deleted
This does not update the chat_id attribute of any scheduled telegram.ext.Job .
When using concurrent_updates or the job_queue , process_update() or telegram.ext.Job.run() may re-create the old entry due to the asynchronous nature of these features. Please make sure that your program can avoid or handle such situations.
A message with either migrate_from_chat_id or migrate_to_chat_id . Mutually exclusive with passing old_chat_id and new_chat_id .
old_chat_id ( int , optional) – The old chat ID. Mutually exclusive with passing message
new_chat_id ( int , optional) – The new chat ID. Mutually exclusive with passing message
async process_error ( update , error , job = None , coroutine = None ) [source] ¶
Processes an error by passing it to all error handlers registered with add_error_handler() . If one of the error handlers raises telegram.ext.ApplicationHandlerStop , the error will not be handled by other error handlers. Raising telegram.ext.ApplicationHandlerStop also stops processing of the update when this method is called by process_update() , i.e. no further handlers (even in other groups) will handle the update. All other exceptions raised by an error handler will just be logged.
Changed in version 20.0:
dispatch_error was renamed to process_error() .
Exceptions raised by error handlers are now properly logged.
telegram.ext.ApplicationHandlerStop is no longer reraised but converted into the return value.
The job that caused the error.
New in version 20.0.
True , if one of the error handlers raised telegram.ext.ApplicationHandlerStop . False , otherwise.
Processes a single update and marks the update to be updated by the persistence later. Exceptions raised by handler callbacks will be processed by process_error() .
Changed in version 20.0: Persistence is now updated in an interval set by telegram.ext.BasePersistence.update_interval .
RuntimeError – If the application was not initialized.
Removes an error handler.
remove_handler ( handler , group = 0 ) [source] ¶
Remove a handler from the specified group.
group ( object , optional) – The group identifier. Default is 0 .
Convenience method that takes care of initializing and starting the app, polling updates from Telegram using telegram.ext.Updater.start_polling() and a graceful shutdown of the app on exit.
The app will shut down when KeyboardInterrupt or SystemExit is raised. On unix, the app will also shut down on receiving the signals specified by stop_signals .
The order of execution by run_polling is roughly as follows:
Run the application until the users stops it
When combining python-telegram-bot with other asyncio based frameworks, using this method is likely not the best choice, as it blocks the event loop until it receives a stop signal as described above. Instead, you can manually call the methods listed below to start and shut down the application and the updater . Keeping the event loop running and listening for a stop signal is then up to you.
poll_interval ( float , optional) – Time to wait between polling updates from Telegram in seconds. Default is 0.0 .
Whether the bootstrapping phase of the telegram.ext.Updater will retry on failures on the Telegram server.
< 0 — retry indefinitely (default)
> 0 — retry up to X times
drop_pending_updates ( bool , optional) – Whether to clean any pending updates on Telegram servers before actually starting to poll. Default is False .
If True , the current event loop will be closed upon shutdown. Defaults to True .
Signals that will shut down the app. Pass None to not use stop signals. Defaults to signal.SIGINT , signal.SIGTERM and signal.SIGABRT on non Windows platforms.
Not every asyncio.AbstractEventLoop implements asyncio.loop.add_signal_handler() . Most notably, the standard event loop on Windows, asyncio.ProactorEventLoop , does not implement this method. If this method is not available, stop signals can not be set.
run_webhook ( listen = ‘127.0.0.1’ , port = 80 , url_path = » , cert = None , key = None , bootstrap_retries = 0 , webhook_url = None , allowed_updates = None , drop_pending_updates = None , ip_address = None , max_connections = 40 , close_loop = True , stop_signals = None , secret_token = None ) [source] ¶
Convenience method that takes care of initializing and starting the app, listening for updates from Telegram using telegram.ext.Updater.start_webhook() and a graceful shutdown of the app on exit.
The app will shut down when KeyboardInterrupt or SystemExit is raised. On unix, the app will also shut down on receiving the signals specified by stop_signals .