+
+

Pydis Core#

+

Useful utilities and tools for Discord bot development.

+
+
+class BotBase(*args, guild_id, allowed_roles, http_session, redis_session=None, api_client=None, statsd_url=None, **kwargs)[source]#
+

Bases: Bot

+

A sub-class that implements many common features that Python Discord bots use.

+
+
+guild_id[source]#
+

ID of the guild that the bot belongs to.

+
+
Type:
+

int

+
+
+
+ +
+
+http_session[source]#
+

The http session used for sending out HTTP requests.

+
+
Type:
+

aiohttp.ClientSession

+
+
+
+ +
+
+api_client[source]#
+

The API client used for communications with the site service.

+
+
Type:
+

pydis_core.site_api.APIClient

+
+
+
+ +
+
+statsd_url[source]#
+

The url that statsd sends metrics to.

+
+
Type:
+

str

+
+
+
+ +
+
+redis_session[source]#
+

The redis session used to communicate with the Redis instance.

+
+
Type:
+

async_rediscache.RedisSession

+
+
+
+ +
+
+stats[source]#
+

The statsd client that sends metrics.

+
+
Type:
+

pydis_core.async_stats.AsyncStatsClient

+
+
+
+ +
+
+all_extensions[source]#
+

All extensions that were found within the module passed to +self.load_extensions. Use self.extensions to get the loaded extensions.

+
+
Type:
+

frozenset[str]

+
+
+
+ +
+
+__init__(*args, guild_id, allowed_roles, http_session, redis_session=None, api_client=None, statsd_url=None, **kwargs)[source]#
+

Initialise the base bot instance.

+
+
Parameters:
+
+
+
+
+ +
+
+async add_cog(cog)[source]#
+

Add the given cog to the bot and log the operation.

+
+
Return type:
+

None

+
+
+
+ +
+
+add_command(command)[source]#
+

Add command as normal and then add its root aliases to the bot.

+
+
Return type:
+

None

+
+
+
+ +
+
+clear()[source]#
+

Not implemented! Re-instantiate the bot instead of attempting to re-use a closed one.

+
+
Return type:
+

None

+
+
+
+ +
+
+async close()[source]#
+

Close the Discord connection, and the aiohttp session, connector, statsd client, and resolver.

+
+
Return type:
+

None

+
+
+
+ +
+
+async load_extensions(module, *, sync_app_commands=True)[source]#
+

Load all the extensions within the given module and save them to self.all_extensions.

+
+
Parameters:
+

sync_app_commands (bool) โ€“ Whether to sync app commands after all extensions are loaded.

+
+
Return type:
+

None

+
+
+
+ +
+
+async log_to_dev_log(message)[source]#
+

Log the given message to #dev-log.

+
+
Return type:
+

None

+
+
+
+ +
+
+async on_guild_available(guild)[source]#
+

Set the internal guild available event when self.guild_id becomes available.

+

If the cache appears to still be empty (no members, no channels, or no roles), the event +will not be set and guild_available_but_cache_empty event will be emitted.

+
+
Return type:
+

None

+
+
+
+ +
+
+async on_guild_unavailable(guild)[source]#
+

Clear the internal guild available event when self.guild_id becomes unavailable.

+
+
Return type:
+

None

+
+
+
+ +
+
+async ping_services()[source]#
+

Ping all required services on setup to ensure they are up before starting.

+
+
Return type:
+

None

+
+
+
+ +
+
+async process_commands(message)[source]#
+

Overwrite default Discord.py behaviour to process commands only after ensuring extensions are loaded.

+

This extension check is only relevant for clients that make use of pydis_core.BotBase.load_extensions.

+
+
Return type:
+

None

+
+
+
+ +
+
+register_command_error_manager(manager)[source]#
+

Bind an instance of the command error manager to both the bot and the command tree.

+

The reason this doesnโ€™t happen in the constructor is because error handlers might need an instance of the bot. +So registration needs to happen once the bot instance has been created.

+
+
Return type:
+

None

+
+
+
+ +
+
+remove_command(name)[source]#
+

Remove a command/alias as normal and then remove its root aliases from the bot.

+

Individual root aliases cannot be removed by this function. +To remove them, either remove the entire command or manually edit bot.all_commands.

+
+
Return type:
+

Command | None

+
+
+
+ +
+
+async setup_hook()[source]#
+

An async init to startup generic services.

+

Connects to statsd, and calls +AsyncStatsClient.create_socket +and ping_services().

+
+
Return type:
+

None

+
+
+
+ +
+
+async wait_until_guild_available()[source]#
+

Wait until the guild that matches the guild_id given at init is available (and the cache is ready).

+

The on_ready event is inadequate because it only waits 2 seconds for a GUILD_CREATE +gateway event before giving up and thus not populating the cache for unavailable guilds.

+
+
Return type:
+

None

+
+
+
+ +
+ +
+
+exception EmptyPaginatorEmbedError[source]#
+

Bases: Exception

+

Raised when attempting to paginate with empty contents.

+
+ +
+
+class LinePaginator(prefix='```', suffix='```', max_size=4000, scale_to_size=4000, max_lines=None, linesep='\\n')[source]#
+

Bases: Paginator

+

A class that aids in paginating code blocks for Discord messages.

+
+
Parameters:
+
    +
  • pagination_emojis (PaginationEmojis) โ€“ The emojis used to navigate pages.

  • +
  • prefix (str) โ€“ The prefix inserted to every page. e.g. three backticks.

  • +
  • suffix (str) โ€“ The suffix appended at the end of every page. e.g. three backticks.

  • +
  • max_size (int) โ€“ The maximum amount of codepoints allowed in a page.

  • +
  • scale_to_size (int) โ€“ The maximum amount of characters a single line can scale up to.

  • +
  • max_lines (int) โ€“ The maximum amount of lines allowed in a page.

  • +
+
+
+
+
+__init__(prefix='```', suffix='```', max_size=4000, scale_to_size=4000, max_lines=None, linesep='\\n')[source]#
+

This function overrides the Paginator.__init__ from inside discord.ext.commands.

+

It overrides in order to allow us to configure the maximum number of lines per page.

+
+ +
+
+add_line(line='', *, empty=False)[source]#
+

Adds a line to the current page.

+

If a line on a page exceeds max_size characters, then max_size will go up to +scale_to_size for a single line before creating a new page for the overflow words. If it +is still exceeded, the excess characters are stored and placed on the next pages unti +there are none remaining (by word boundary). The line is truncated if scale_to_size is +still exceeded after attempting to continue onto the next page.

+

In the case that the page already contains one or more lines and the new lines would cause +max_size to be exceeded, a new page is created. This is done in order to make a best +effort to avoid breaking up single lines across pages, while keeping the total length of the +page at a reasonable size.

+

This function overrides the Paginator.add_line from inside discord.ext.commands.

+

It overrides in order to allow us to configure the maximum number of lines per page.

+
+
Parameters:
+
    +
  • line (str) โ€“ The line to add to the paginated content.

  • +
  • empty (bool) โ€“ Indicates whether an empty line should be added at the end.

  • +
+
+
Return type:
+

None

+
+
+
+ +
+
+async classmethod paginate(pagination_emojis, lines, ctx, embed, *, prefix='', suffix='', max_lines=None, max_size=500, scale_to_size=4000, empty=True, restrict_to_user=None, timeout=300, footer_text=None, url=None, exception_on_empty_embed=False, reply=False, allowed_roles=None)[source]#
+

Use a paginator and set of reactions to provide pagination over a set of lines.

+

The reactions are used to switch page, or to finish with pagination.

+

When used, this will send a message using ctx.send() and apply a set of reactions to it. These reactions may +be used to change page, or to remove pagination from the message.

+

Pagination will also be removed automatically if no reaction is added for five minutes (300 seconds).

+

The interaction will be limited to restrict_to_user (ctx.author by default) or +to any user with a moderation role.

+
+
Parameters:
+
    +
  • pagination_emojis (PaginationEmojis) โ€“ The emojis used to navigate pages.

  • +
  • lines (list[str]) โ€“ A list of lines to be added to the paginated content.

  • +
  • ctx (discord.ext.commands.Context) โ€“ The context in which the pagination is needed.

  • +
  • embed (discord.Embed) โ€“ The embed that holds the content, it serves as the page.

  • +
  • prefix (str) โ€“ The prefix inserted to every page. e.g. three backticks.

  • +
  • suffix (str) โ€“ The suffix appended at the end of every page. e.g. three backticks.

  • +
  • max_lines (int) โ€“ The maximum amount of lines allowed in a page.

  • +
  • max_size (int) โ€“ The maximum amount of codepoints allowed in a page.

  • +
  • scale_to_size (int) โ€“ The maximum amount of characters a single line can scale up to.

  • +
  • empty (bool) โ€“ Indicates whether an empty line should be added to each provided line.

  • +
  • restrict_to_user (discord.User) โ€“ The user to whom interaction with the pages should be restricted.

  • +
  • timeout (int) โ€“ The timeout after which users cannot change pages anymore.

  • +
  • footer_text (str) โ€“ Text to be added as a footer for each page.

  • +
  • url (str) โ€“ The url to be set for the pagination embed.

  • +
  • exception_on_empty_embed (bool) โ€“ Indicates whether to raise an exception when no lines are provided.

  • +
  • reply (bool) โ€“ Indicates whether to send the page as a reply to the contextโ€™s message.

  • +
  • allowed_roles (Sequence[int]) โ€“ A list of role ids that are allowed to change pages.

  • +
+
+
Return type:
+

Message | None

+
+
+

Example: +>>> embed = discord.Embed() +>>> embed.set_author(name=โ€Some Operationโ€, url=url, icon_url=icon) +>>> await LinePaginator.paginate(pagination_emojis, [line for line in lines], ctx, embed)

+
+ +
+ +
+
+class PaginationEmojis(**data)[source]#
+

Bases: BaseModel

+

The emojis that will be used for pagination.

+
+
+model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}#
+

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

+
+ +
+
+model_config: ClassVar[ConfigDict] = {}#
+

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

+
+ +
+
+model_fields: ClassVar[dict[str, FieldInfo]] = {'delete': FieldInfo(annotation=str, required=False, default='<:trashcan:637136429717389331>'), 'first': FieldInfo(annotation=str, required=False, default='โฎ'), 'last': FieldInfo(annotation=str, required=False, default='โญ'), 'left': FieldInfo(annotation=str, required=False, default='โฌ…'), 'right': FieldInfo(annotation=str, required=False, default='โžก')}#
+

Metadata about the fields defined on the model, +mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

+

This replaces Model.__fields__ from Pydantic V1.

+
+ +
+ +
+
+exception StartupError(base)[source]#
+

Bases: Exception

+

Exception class for startup errors.

+
+
+__init__(base)[source]#
+
+ +
+ +
+

Subpackages#

+ +
+
+

Submodules#

+ +
+
+ +