'Python Discord Bot await commands finishing too late
I am creating a discord bot. It is meant to receive files, and then run an executable. Right now I have the users send the files in a message, then type "done" to let it know they're finished. However, if the users type "done" in the same message they attached the files to, the function that saves them to disk runs after the main thread continues on. I thought that await would cause this to happen afterwards.
Here is the code:
async def download(msg):
for attachment in msg.attachments:
await attachment.save(attachment.filename)
shutil.move(attachment.filename, "./mons")
global numattach
numattach += 1
print(f"File added! Numattach = {numattach}")
async def delete(msg):
await msg.delete()
def check(msg):
if(limitChannel) and (msg.channel.id == channelId):
if msg.author.bot:
return False
if msg.author.id == ctx.author.id and "done" in msg.content:
asyncio.create_task(download(msg))
#thread = threading.Thread(target=asyncio.run, args=(download(msg),))
#thread.start()
#thread.join()
asyncio.create_task(delete(msg))
return True
elif msg.author.id == ctx.author.id:
asyncio.create_task(download(msg))
asyncio.create_task(delete(msg))
return False
else:
return False
async def trying(ctx):
try:
ctx = await client.wait_for("message", check=check, timeout=60)
except asyncio.TimeoutError:
await ctx.channel.send(content=f"YOU HATH WAITED TOO LONG, {user}!")
global readyforcommand
readyforcommand = True
return ctx
await ctx.channel.send(f"SEND ME YOUR FILES, {ctx.author.mention}! Type done when done!")
ctx = await trying(ctx)
global numattach
print(f"Number of files received: {numattach}")
if numattach < 2 or numattach > 4:
await ctx.channel.send("Error: You need to attach 2 - 4 files to find a valid seed.")
readyforcommand = True
await ctx.channel.send(f"I HATH FINISHED WITH {user}'s SEED. I SHALT NOW MOVE ON.")
return
await run_etumrepseed(ctx)
Does anyone know how I can fix this so that in that one case, it won't finish early? Every time I test, I see that numattach = 0 when it gets to that part of the code where it checks how many attachments there were, then I see the download(msg) function run, and set numattach to 2 - 4.
Solution 1:[1]
I think the problem there is that your check functions return True when the users type "done" in the same message they attached the files to. In this case the wait_for was fulfilled and it continues the main execution. The reason it happens is pretty much the following: you are using create_task which schedules it to run in the background in a non-blocking way. In order to ensure the completion you might want to await your tasks before returning True in the check function or by using asyncio.gather to which you can pass all the tasks and it'll suspect the function execution until all tasks are completed.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Oleksandr Motornyi |
