Home > OS >  accesing loop attribute in non-async contexts
accesing loop attribute in non-async contexts

Time:03-26

async def create_db_pool():
    database_url = ''
    client.pg_con = await asyncpg.create_pool(database_url, ssl="require")

so i have this function in my discord bot code but when i try to run this code using

client.loop.run_until_complete(create_db_pool())

i get the following error currently i am looking for a workaround for this or any way to solve it

AttributeError: loop attribute cannot be accessed in non-async contexts. Consider using either an asynchronous main function and passing it to asyncio.run or using asynchronous initialisation hooks such as Client.setup_hook

CodePudding user response:

Are you running your bot in a synchronous context? The code should look something like:

async def on_message(ctx): ...

Also please show some code. But I think learning the asyncio module will help. Anyway, try this:

import asyncio


async def create_db_pool() -> None: ... # Your code


loop = asyncio.get_event_loop()
loop.run_until_complete(function_async())
loop.close()

This will not run your function asynchronously, but it doesn't seem like you wish to do so. But it should actually successfully run the function.

CodePudding user response:

You must be using the master version of discord.py It recently introduced breaking changes with asyncio, with one of them being this. client.loop is no more accessible in a sync context. This gist explains what was the change and how to make a work around.

First way would be to introduce a setup_hook() function inside a commands.Bot subclass and use await create_db_pool() in there

class MyBot(commands.Bot):
     def __init__(self, **kwargs):
         super().__init__(**kwarg)
         self.pg_conn: = None

     async def create_db_pool(self): # making it a bound function in my example
         database_url = ''
         self.pg_con = await asyncpg.create_pool(database_url, ssl="require")

     async def setup_hook(self):
         await self.create_db_pool() # no need to use `loop.run_*` here, you are inside an async function

or you could also do this inside a main() function

async def main():
    await create_db_pool() # again, no need to run with AbstractLoopEvent if you can await
    await bot.start(TOKEN)

asyncio.run(main())
  • Related