/restcord.py

An asynchronous Python client for Discord's REST API

Primary LanguagePythonMIT LicenseMIT

restcord.py

An asynchronous Python client for Discord's REST API.

You can aquire an application token from Discord's developer portal but please take care to read through Discord's developer terms of service and policy document as you agree to use this library in accordance with these terms.

Find Discord's REST API documentation here.

Codacy Badge PyPI version Python 3.6

Requirements

python>=3.6.0
asyncio
aiohttp
json

Install

pip3 install restcord.py

Import

from restcord import RestCord
from restcord.errors import (
    BadRequest,
    Forbidden,
    NotFound,
    RateLimited,
    InternalServerError,
    BadGateway
)

Initialise

You can initialise the RestCord client with an application token, but you may also provide your own asyncio event loop, aiohttp client session.

client = RestCord("Your Discord application token here")

Structure

RestCord is structured in the same way as Discord's REST API documentation. Once you have initialised RestCord you will have access to channel_client, emoji_client, guild_client, user_client and voice_client objects, which contain asynchronous methods to communicate with API end points.

Example: get a guild object

In this example, we use RestCord to perform a GET request to Discord's guild API end point, which will return a guild object. Printing this object will output some basic details about the guild such as id and name but the object contains fields as per the documentation.

try:
    async with client as rc:
        guild = await rc.guild_client.get_guild(guild_id=265561352683126786)
        print(guild)
except Forbidden as ex:
    print(ex)

AsyncContextManager

RestCord can be used with or without the AsyncContextManager. Using it will ensure that any open aiohttp client sessions are closed.

async with client as rc:
    voice_regions = await rc.voice_client.get_voice_regions()

Or more granularly:

async with client.guild_client as gc:
    channel = await gc.get_channel(265586371178135562)
    print(channel)

If you do not use the AsyncContextManager, you must call the close() function on RestCord to close any open aiohttp client sessions.

member = await client.guild_client.get_member(265561352683126786, 50527603626344448)
await client.close()

Errors

If Discord return error HTTP status codes, RestCord will throw a relevent exception for you to handle in your own way.

Example: add a reaction to a message

In this example we try to add a reaction to a message. There are several things to be aware of here:

  • Does our application have permission to add reactions to messages? If not, a Forbidden exception will be thrown.

  • Have we URL encoded the emoji as per specified by the documentation. If not, a BadRequest exception will be thrown.

  • This particular end point has strict rate limits. If we have already added a reaction to the message we may be rate limited. In this case a RateLimited exception will be thrown and you can get more information about that limit from the exception object.

try:
    async with client.channel_client as cc:
        await cc.add_reaction(331893934454472707, 736436235140333599, emoji="msq:285508293596807168")
except Forbidden as ex:
    print(ex)
except BadRequest as ex:
    print(ex)
except RateLimited as ex:
    if ex.is_global:
        print(f'Global rate limit has been hit. Retry in {ex.retry_after:.2f} seconds.')
    else:
        print(f'Rate limit hit. Retry in {ex.retry_after:.2f} seconds.')