I'm creating a simple telegram bot in which I'm making use of the telegram bot and telethon api(as I want to retrieve all members in a chat and with the bot api, i can't do this unless all users are admins). I'm able to currently print out the users in a chat successfully.
However when I terminate the script, I keep getting RuntimeErrors and warnings on certain telethon API coroutines not being awaited and Runtime errors for closed event loops
I did do some reading up on asyncio: https://medium.com/dev-bits/a-minimalistic-guide-for-understanding-asyncio-in-python-52c436c244ea and added the following code to my main function to run the client. Here's a sample of what it looks like:
from typing import Final
from telethon import TelegramClient, events
from telegram import Update, Bot
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
TOKEN: Final = <token>
api_id = <api_id>
api_hash = <api_hash>
BOT_USERNAME = <bot_username>
bot = Bot(token=TOKEN)
bot_client = TelegramClient('sessions/session_master', api_id, api_hash).start(bot_token=TOKEN)
async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text('hello, bot starting..')
async def tag_all_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
await tag_all(update)
async def tag_all(update: Update):
group_members = await bot_client.get_participants(update.effective_chat.id)
for user in group_members:
if user.username or user.first_name:
print(f' {user.username or user.first_name}')
if __name__ == '__main__':
print('Starting bot...')
app = Application.builder().token(TOKEN).build()
# Commands
app.add_handler(CommandHandler('start', start_command))
app.add_handler(CommandHandler('all', tag_all_command))
# Messages
app.add_handler(MessageHandler(filters.TEXT, handle_message))
# Polling
print('Polling...')
app.run_polling(poll_interval=3)
try:
bot_client.run_until_disconnected()
except KeyboardInterrupt:
bot_client.disconnect()
With the code above , I thought this would safely close the event loop, however whenever I terminate the script in pycharm, I get the following errors below, could someone help me pinpoint my mistake?:
C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\client\telegrambaseclient.py:643: RuntimeWarning: coroutine 'TelegramBaseClient._disconnect_coro' was never awaited
pass
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Traceback (most recent call last):
File "C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\bot.py", line 104, in <module>
bot_client.run_until_disconnected()
File "C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\client\updates.py", line 95, in run_until_disconnected
return self.loop.run_until_complete(self._run_until_disconnected())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 628, in run_until_complete
self._check_closed()
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 519, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
sys:1: RuntimeWarning: coroutine 'UpdateMethods._run_until_disconnected' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Task was destroyed but it is pending!
task: <Task pending name='Task-3' coro=<Connection._send_loop() running at C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\network\connection\connection.py:313> wait_for=<Future pending cb=[Task.task_wakeup()]>>
Task was destroyed but it is pending!
task: <Task pending name='Task-4' coro=<Connection._recv_loop() running at C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\network\connection\connection.py:332> wait_for=<Future pending cb=[Task.task_wakeup()]>>
Task was destroyed but it is pending!
task: <Task pending name='Task-5' coro=<MTProtoSender._send_loop() running at C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\network\mtprotosender.py:462> wait_for=<Future pending cb=[Task.task_wakeup()]>>
Task was destroyed but it is pending!
task: <Task pending name='Task-6' coro=<MTProtoSender._recv_loop() running at C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\network\mtprotosender.py:505> wait_for=<Future pending cb=[Task.task_wakeup()]>>
Task was destroyed but it is pending!
task: <Task pending name='Task-7' coro=<UpdateMethods._update_loop() running at C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\client\updates.py:425> wait_for=<Future pending cb=[Task.task_wakeup()]>>
Task was destroyed but it is pending!
task: <Task pending name='Task-8' coro=<UpdateMethods._keepalive_loop() running at C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\client\updates.py:459> wait_for=<Future pending cb=[Task.task_wakeup()]>>
Unexpected exception in the send loop
Traceback (most recent call last):
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\queues.py", line 158, in get
await getter
GeneratorExit
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\network\connection\connection.py", line 313, in _send_loop
self._send(await self._send_queue.get())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\queues.py", line 160, in get
getter.cancel() # Just in case getter is not done yet.
^^^^^^^^^^^^^^^
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 761, in call_soon
self._check_closed()
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 519, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Exception ignored in: <coroutine object Connection._send_loop at 0x000001F8E5CD8740>
RuntimeError: coroutine ignored GeneratorExit
Exception ignored in: <coroutine object Connection._recv_loop at 0x000001F8E5CDC8B0>
Traceback (most recent call last):
File "C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\network\connection\connection.py", line 350, in _recv_loop
File "C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\network\connection\connection.py", line 258, in disconnect
File "C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\helpers.py", line 174, in _cancel
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 761, in call_soon
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 519, in _check_closed
RuntimeError: Event loop is closed
Unhandled error while receiving data
Traceback (most recent call last):
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\queues.py", line 158, in get
await getter
GeneratorExit
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\network\mtprotosender.py", line 505, in _recv_loop
body = await self._connection.recv()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\network\connection\connection.py", line 299, in recv
result, err = await self._recv_queue.get()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\queues.py", line 160, in get
getter.cancel() # Just in case getter is not done yet.
^^^^^^^^^^^^^^^
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 761, in call_soon
self._check_closed()
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 519, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Exception ignored in: <coroutine object MTProtoSender._recv_loop at 0x000001F8E5CB5B40>
Traceback (most recent call last):
File "C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\network\mtprotosender.py", line 520, in _recv_loop
File "C:\Users\Jeevan Mahtani\PycharmProjects\pythonProject\venv\Lib\site-packages\telethon\network\mtprotosender.py", line 428, in _start_reconnect
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 434, in create_task
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 519, in _check_closed
RuntimeError: Event loop is closed
sys:1: RuntimeWarning: coroutine 'MTProtoSender._reconnect' was never awaited
Task was destroyed but it is pending!
task: <Task pending name='Task-20' coro=<Queue.get() running at C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\queues.py:158> wait_for=<Future pending cb=[Task.task_wakeup()]> cb=[_release_waiter(<Future pendi...ask_wakeup()]>)() at C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py:421]>
Exception ignored in: <coroutine object Queue.get at 0x000001F8E5CD8E40>
Traceback (most recent call last):
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\queues.py", line 160, in get
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 761, in call_soon
File "C:\Users\Jeevan Mahtani\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 519, in _check_closed
RuntimeError: Event loop is closed
Process finished with exit code 1
telegram
package by default is evasive from some aspects, so you need to specify some stuff manually, you have couple issues:
main one is run_polling' close_loop
not being set to False, it will close the loop on KeyboardInterrupt
too and shutdown without giving chance for telethon to disconnect since they share the same loop.
run_polling
also handles KeyboardInterrupt
for you, no need for you to have your own try except.
and finally, using telethon's run_until_disconnected
is useless and wrong. because run_polling
will lock and run the event loop for telethon too. run_until_disconnected
was never reached to begin with, until you exit run_polling
with a signal. only then then it will run, and lock twice, so you shouldn't use it.
something like this should do:
print('Polling...')
try:
app.run_polling(poll_interval=3, close_loop=False)
finally:
bot_client.disconnect()