0

I'm creating a bot via DiscordPy where when a user writes !unemployment, the bot makes a server call to U.S. Bureau of Labor Statistics website, and collects a JSON file of the latest unemployment numbers.

@commands.command(name="unemployment")
async def unemployment(self, context):
    headers = {'Content-type': 'application/json'}
    data = json.dumps({"seriesid": ['LNS14000000']})
    url = "https://api.bls.gov/publicAPI/v2/timeseries/data/"
    # Async HTTP request
    async with aiohttp.ClientSession() as session:
        raw_response = await session.post(url, data=data, headers=headers)
        response = await raw_response.text()
        r = json.loads(response)

The data shows month-over-month data for the past 24 months. I use Pandas to format the information to my liking and then feed the information to Matplotlib to generate a graph.

# Initialize IO
data_stream = io.BytesIO()

# Plot graph
plt.figure(figsize=(1,1))
ax = df.plot(x="period",y="value")
plt.gca().invert_xaxis()
ax.yaxis.set_major_formatter(mtick.PercentFormatter(1))
ax.get_legend().remove()

# Save content into the data stream
plt.savefig(data_stream, format='png', bbox_inches="tight", dpi = 80)
plt.close()

I followed the instructions here: Matplotlib graphic image to base64 to transform my graph into base64 image since I didn't want to save the image on the server, and instead wanted to have a base64 string I can use to build the image on the fly and have little impact on memory. But unfortunately Discordpy's embed.set_image() values in the format of data:image/png;base64,<BASE64 code>.

1 Answer 1

5

To address this, I did the following:

  1. After saving the image, I created a file using DiscordPy's File class, and assign it an easy name. The name is essential!
## Create file
# Reset point back to beginning of stream
data_stream.seek(0)
chart = discord.File(data_stream,filename="unemployment_chart.png")
  1. Using set_image, use the attachment:// protocol to add the file
embed.set_image(
   url="attachment://unemployment_chart.png"
)
  1. When sending the file with Discordpy, make sure you send both the embed AND the file together in the send call.
await context.send(embed=embed, file=chart)

The result will be something like this: Albert's List Bot with Unemployment Rate data

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.