pyTelegramBotAPI icon indicating copy to clipboard operation
pyTelegramBotAPI copied to clipboard

The need for stop_polling in async version

Open EugeneNeuron opened this issue 1 year ago • 6 comments

  1. What version of pyTelegramBotAPI are you using? 4.22.0
  2. What OS are you using? Gnu/Linux
  3. What version of python are you using? 3.10.7

I see how to gracefully stop polling using TeleBot class (#2098), but how to properly stop bot/polling using AsyncTeleBot? I tried AsyncTeleBot.close_session, but it gives an error.

ERROR Aiohttp ClientError: ClientOSError
ERROR Unhandled exception (full traceback for debug level): Request timeout. Request: method=get url=getUpdates params=<aiohttp.formdata.FormData object at 0x7fb62f4137c0> files=None request_timeout=300

I can catch it and handle myself, but maybe there's a better way?

EugeneNeuron avatar Aug 18 '24 00:08 EugeneNeuron

u close session first then stop polling

coder2020official avatar Aug 19 '24 14:08 coder2020official

To gracefully stop polling when using AsyncTeleBot in pyTelegramBotAPI, you can use the stop_polling() method in combination with await to ensure that the bot's polling is properly stopped. Since AsyncTeleBot runs asynchronously, the close_session() method will close the bot's session but might not ensure proper cleanup of all resources if not handled correctly. Here's how you can gracefully stop the bot using AsyncTeleBot:

import asyncio
from telebot.async_telebot import AsyncTeleBot

API_TOKEN = 'YOUR_BOT_API_TOKEN'
bot = AsyncTeleBot(API_TOKEN)

# Start polling
async def start_polling():
    await bot.polling(non_stop=True)

# Gracefully stop polling
async def stop_polling():
    await bot.stop_polling()  # This will stop the polling process
    await bot.close_session()  # Close the bot's aiohttp session

async def main():
    try:
        await start_polling()
    except (KeyboardInterrupt, SystemExit):
        print("Gracefully stopping the bot...")
        await stop_polling()

if __name__ == '__main__':
    asyncio.run(main())

FaridMalekpour avatar Aug 23 '24 16:08 FaridMalekpour

Thank you @coder2020official and @FaridMalekpour for your answers.

But, sorry, maybe I don't understand something, but there's literally no such method as stop_polling for AsyncTeleBot.

In [7]: bot = AsyncTeleBot(token)

In [9]: bot.stop_polling()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In [9], line 1
----> 1 bot.stop_polling()

AttributeError: 'AsyncTeleBot' object has no attribute 'stop_polling'

EugeneNeuron avatar Aug 31 '24 17:08 EugeneNeuron

Hi, yes, I am currently working on this, hence this issue is still open. Will notify you when PR is ready

coder2020official avatar Aug 31 '24 18:08 coder2020official

You may try my PR version out if you want. It should introduce(I hope) graceful & proper shutdown of polling.

coder2020official avatar Aug 31 '24 18:08 coder2020official

Hi @coder2020official,

I tried you patch and it worked for me like a charm.

I tried both the way @FaridMalekpour suggested and from inside the message_handler, like this:


        @self.bot.message_handler(commands=['stop_bot'])
        async def handle_stop_bot(message: Message):
            if message.from_user.id == self.admin:
                await self.bot.send_message(
                    message.chat.id,
                    "Bot is now shutting down gracefully."
                )
                await self.bot.stop_polling()

EugeneNeuron avatar Aug 31 '24 22:08 EugeneNeuron