Discord.py: fetch img url and send to discord

Created on 10 May 2018  路  1Comment  路  Source: Rapptz/discord.py

Hello, I want my bot to send a discord file via "client.send_file(message.channel, image)".
But I can't find a good solution, I've done this but it's not working.

def urlToImg(url):
    file = open('img.png', 'wb')
    file.write(requests.get(url).content)
    return file
question

Most helpful comment

You shouldn't use requests for this (it's a synchronous library) and you don't need a temporary file for this (it's slow and can introduce race conditions).

Use aiohttp (included with discord.py) and BytesIO (part of the Python standard library) to achieve this:

# near the top of your file with the rest of your imports
import aiohttp
from io import BytesIO
...

# in an async function, such as an on_message handler or command
async with aiohttp.ClientSession() as session:
    # note that it is often preferable to create a single session to use multiple times later - see below for this.
    async with session.get(url) as resp:
        buffer = BytesIO(await resp.read())

await client.send_file(message.channel, fp=buffer, filename="something.png")


# using a predefined ClientSession on the Client instance
client.session = aiohttp.ClientSession(loop=client.loop)  # then use client.session.get similar to above


# using a predefined ClientSession within a cog
def __init__(self, bot, ...):
    ...
    self.session = aiohttp.ClientSession(loop=bot.loop)
    ...
    # then use self.session.get similar to above


# 3.4 syntax
resp = yield from session.get(url)

try:
    content = yield from resp.read()
finally:
    resp.close()
buffer = BytesIO(content)

yield from client.send_file(message.channel, fp=buffer, filename="something.png")

Hope this helps.

>All comments

You shouldn't use requests for this (it's a synchronous library) and you don't need a temporary file for this (it's slow and can introduce race conditions).

Use aiohttp (included with discord.py) and BytesIO (part of the Python standard library) to achieve this:

# near the top of your file with the rest of your imports
import aiohttp
from io import BytesIO
...

# in an async function, such as an on_message handler or command
async with aiohttp.ClientSession() as session:
    # note that it is often preferable to create a single session to use multiple times later - see below for this.
    async with session.get(url) as resp:
        buffer = BytesIO(await resp.read())

await client.send_file(message.channel, fp=buffer, filename="something.png")


# using a predefined ClientSession on the Client instance
client.session = aiohttp.ClientSession(loop=client.loop)  # then use client.session.get similar to above


# using a predefined ClientSession within a cog
def __init__(self, bot, ...):
    ...
    self.session = aiohttp.ClientSession(loop=bot.loop)
    ...
    # then use self.session.get similar to above


# 3.4 syntax
resp = yield from session.get(url)

try:
    content = yield from resp.read()
finally:
    resp.close()
buffer = BytesIO(content)

yield from client.send_file(message.channel, fp=buffer, filename="something.png")

Hope this helps.

Was this page helpful?
0 / 5 - 0 ratings