0

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)
Łukasz Kwieciński
  • 14,992
  • 4
  • 21
  • 39
Xanthis
  • 1
  • 1
  • 4
  • 3
    You simply have to pass `ctx` to the function... `loop.run_until_complete(cat(ctx))`, though you gotta get `ctx` from somewhere, generally is a bad idea to run commands like that. If you want background tasks take a look at https://discordpy.readthedocs.io/en/latest/ext/tasks/index.html – Łukasz Kwieciński May 16 '21 at 11:35
  • Tasks are not meant to be used that way, remove the while loop and in the `cat` command simply do `catSend.start(ctx)`, and it will start running in the background. @Xanthis – Łukasz Kwieciński May 16 '21 at 14:32
  • Thank you VERY much!!@ŁukaszKwieciński – Xanthis May 16 '21 at 16:00
  • Instead of editing your question and adding the answer, you should answer your own question and accept that. – 12944qwerty May 16 '21 at 18:21
  • Sorry, I did not know I could do that. I am new to this website. – Xanthis May 17 '21 at 04:51

1 Answers1

0

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)
Xanthis
  • 1
  • 1
  • 4