Search code examples
pythonasynchronousdiscord.pyasyncpraw

How to loop an async function with parameters in discord.py?


I have an async function that I want to loop infinitely.

@client.command()
async def cat(ctx):
    tempurl = "b"       
    subreddit = await reddit.subreddit("cats")
    allSubmissions = []

    new = subreddit.new(limit = 1)

    async for submission in new:
        allSubmissions.append(submission)

    randomSub = random.choice(allSubmissions)

    url = randomSub.url
    if tempurl != url:
        if url.endswith('.jpg') or url.endswith('.jpeg') or url.endswith('.png'):
            tempurl = url
            print("\n"+url)
            await ctx.send(url)

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

However, using loop.run_until_complete(cat()) gives me the output:

TypeError: cat() missing 1 required positional argument: 'ctx'

I tried to look for a way to loop async functions with parameters but cannot find one.


Solution

Instead of doing what I was doing, I used discord.ext.task (as suggested by Łukasz Kwieciński) to create a background loop then called that background loop function from a command function.

Thanks to Łukasz Kwieciński for helping me again

@tasks.loop(seconds=30)
async def catSend(ctx):
    tempurl = "bbbb"
    subreddit = await reddit.subreddit("cats")
    allSubmissions = []

    new = subreddit.new(limit = 1)
    async for submission in new:
        allSubmissions.append(submission)

    randomSub = random.choice(allSubmissions)

    url = randomSub.url
    if tempurl != url:
        if url.endswith('.jpg') or url.endswith('.jpeg') or url.endswith('.png'):
            tempurl = url
            print(url)
            await ctx.send(url)
        else:
            tempurl = url
        

@client.command()
async def cat(ctx):
    catSend.start(ctx)

Solution

  • Instead of doing what I was doing, I used discord.ext.task (as suggested by Łukasz Kwieciński) to create a background loop then called that background loop function from a command function.

    Thanks to Łukasz Kwieciński for helping me again

    tempurl = "bbbb"
    
    @tasks.loop(seconds=30)
    async def catSend(ctx):
        global tempurl
        subreddit = await reddit.subreddit("cats")
        allSubmissions = []
    
        new = subreddit.new(limit = 1)
        async for submission in new:
            allSubmissions.append(submission)
    
        randomSub = random.choice(allSubmissions)
    
        url = randomSub.url
        if tempurl != url:
            if url.endswith('.jpg') or url.endswith('.jpeg') or url.endswith('.png'):
                tempurl = url
                print(url)
                await ctx.send(url)
            else:
                tempurl = url
            
    
    @client.command()
    async def cat(ctx):
        catSend.start(ctx)