-1

there's a part of my code, which im having problems

@client.command()
async def trap(ctx):
    imgid = str(time.time())
   
    url = nyanbase2 + 'nyazi/?token=' + nyantoken
    r = requests.get(url, allow_redirects=True)
  
    open(imgid + '.jpg', 'wb').write(r.content)
   
    await ctx.send(file=discord.File(imgid + '.jpg'))
    
    os.remove(imgid + '.jpg')

well, the code works awesome without any problems but the problem is about the url, it responds about 10-20 secs and job gets done about 30-90 secs. thats too much but there's no way to decrease it. theres 2 'nyanbase' api, first one is fast other one is slow.

and, if this code get triggered, everything, literally everything stops, other commands which are work instantly aren't responding too, until the first request complete

is it possible to run those codes without stopping the whole code? because, it stops everything, even bot goes offline

norahCii
  • 123
  • 1
  • 12

1 Answers1

1

The problem is that requests.get is a blocking function, so no other code in the same thread can be run until it completes. Blocking code and asyncio should not be mixed (unless it's really necessary in which case it should be done like this: https://stackoverflow.com/a/28492261/6744133).

In your case, you are doing an HTTP request, and the normal way of doing this inside an async function is by using the aiohttp module, which you may need to install.

Here is an example of your code modified to use aiohttp instead of requests:

import aiohttp

@client.command()
async def trap(ctx):
    imgid = str(time.time())
   
    url = nyanbase2 + 'nyazi/?token=' + nyantoken
    async with aiohttp.ClientSession() as session:
        async with session.get(url, allow_redirects=True) as resp:
            r = await resp.read()
  
    open(imgid + '.jpg', 'wb').write(r)
   
    await ctx.send(file=discord.File(imgid + '.jpg'))
    
    os.remove(imgid + '.jpg')

If you want to be thorough, you really should use https://pypi.org/project/aiofile/ for writing to files, but this doesn't really matter much if it's only small amounts of data.

As a side note, you don't need to save the file to send it on Discord - you can just use io.BytesIO:

import io

...

async with aiohttp.ClientSession() as session:
    async with session.get(url, allow_redirects=True) as resp:
        r = await resp.read()
img_io = io.BytesIO(r)
   
await ctx.send(file=discord.File(img_io, filename='thingy.jpg'))
Oli
  • 2,507
  • 1
  • 11
  • 23