Search code examples
python-3.xdiscord.pypython-asyncio

coroutine needs to be awaited in asyncio.ensure_future() - asyncio


I need to run a coroutine in a loop.
So, I created a new loop, then I created a task with asyncio.ensure_future(awatable, loop), last, I ran the task through the loop thanks to loop.run_forever(task).
However, when I launch the script, I receive an error telling me that the coroutine was never awaited. How is that possible? The first argument of ensure_future() is an awaitable and does not need to be awaited, does it? Moreover, it tells me that I destroyed a pending task, but did I?

Code

async def initiate_bot():
    await bot.add_cog(my_commands.MusicBot(bot, prefix, float(volume), lyrics, bot_name, spotify_id, spotify_secret))
    await bot.start(token)


# create loop
loop = asyncio.new_event_loop()
# create a task
task = asyncio.ensure_future(initiate_bot(), loop=loop)
try:
    # task runs forever
    loop.run_forever(task)
except KeyboardInterrupt:
    pass
finally:
    # stop and close loop
    loop.stop()
    sys.exit(0)

Error:

Task was destroyed but it is pending! task: <Task pending name='Task-1' coro=<initiate_bot() running at /home/[user]/Scrivania/Coding/[project name]/main.py:45>> sys:1: RuntimeWarning: coroutine 'initiate_bot' was never awaited


Solution

  • The loop.run_forever() function does not take any arguments. When you use asyncio.ensure_future() you are already scheduling the task for execution.

    Python 3.7 introduced a new helper function asyncio.run() which automatically creates and destroys the asynchronous event loop. So, you can simply replace your code with:

    async def initiate_bot():
        await bot.add_cog(my_commands.MusicBot(bot, prefix, float(volume), lyrics, bot_name, spotify_id, spotify_secret))
        await bot.start(token)
    
    
    asyncio.run(initiate_bot())