So, I'm building a pretty sizeable bot and I've ran into a problem: for some reason in a very specific part of my code I just can't run a coroutine.
I am getting the error when I call bot.send_message
.
I've already tried creating tasks, new threads, etc. I even tried using exec() with some global variables, but the result was the same.
I didn't think sending a message would be this much trouble. By the way, I can send a message without a problem elsewhere in my code (mainly I do that as responses to user messages).
I will be grateful if someone shows me the way out.
import nest_asyncio; nest_asyncio.apply()
from threading import Thread
from aiogram import Bot, Dispatcher, executor
import asyncio
bot = Bot("bot token here")
dp = Dispatcher(bot)
async def get_message():
return "message"
async def resend_code(id: int):
message = await get_message()
await bot.send_message(id, message)
def polling():
asyncio.set_event_loop(asyncio.new_event_loop())
executor.start_polling(dp, skip_updates=True)
async def update():
print("resend")
await asyncio.sleep(3)
try:
await resend_code(1234567890)
except Exception as ex:
print(ex)
async def main():
Thread(target=loop.run_until_complete, args=(update(), )).start()
Thread(target=polling, daemon=True).start()
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
while True: pass
When resend_code is called, variable message
does contain the desired dictionary, only bot.send_message fails.
Traceback:
File "C:\Users\Asus\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 267, in __step
result = coro.send(None)
^^^^^^^^^^^^^^^
File "bot.py", line 89, in resend_code
await bot.send_message(id, message)
File "C:\Users\Asus\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\bot\bot.py", line 346, in send_message
result = await self.request(api.Methods.SEND_MESSAGE, payload)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Asus\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\bot\base.py", line 236, in request
return await api.make_request(await self.get_session(), self.server, self.__token, method, data, files,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Asus\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\bot\api.py", line 139, in make_request
async with session.post(url, data=req, **kwargs) as response:
File "C:\Users\Asus\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiohttp\client.py", line 1141, in __aenter__
self._resp = await self._coro
^^^^^^^^^^^^^^^^
File "C:\Users\Asus\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiohttp\client.py", line 467, in _request
with timer:
File "C:\Users\Asus\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiohttp\helpers.py", line 701, in __enter__
raise RuntimeError(
RuntimeError: Timeout context manager should be used inside a task
UPD: Added MRE
Without a minimal reporducible example it is hard to tell anything about a fix, but there is one thing you are doing wrong:
loop.create_task
was not designed to be called from another thread as you are doing, and it would eventually error out (can't be sure if your error is caused by this).
Anyway, the "feeder thread" that will create tasks to your existing event loop should call asynco.run_coroutine_threadsafe
instead.This will make your bot.update()
call as a regular call within your asyncio loop, and hopefully it is all you need to get going.