Back to top

hikari.presences

Application and entities that are used to describe guilds on Discord.

View Source
# -*- coding: utf-8 -*-
# cython: language_level=3
# Copyright (c) 2020 Nekokatt
# Copyright (c) 2021-present davfsa
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Application and entities that are used to describe guilds on Discord."""

from __future__ import annotations

__all__: typing.Sequence[str] = (
    "Activity",
    "ActivityAssets",
    "ActivityFlag",
    "ActivitySecret",
    "ActivityTimestamps",
    "ActivityType",
    "ActivityParty",
    "ClientStatus",
    "MemberPresence",
    "RichActivity",
    "Status",
)

import typing

import attr

from hikari import files
from hikari import snowflakes
from hikari import urls
from hikari.internal import attr_extensions
from hikari.internal import enums
from hikari.internal import routes

if typing.TYPE_CHECKING:
    import datetime

    from hikari import emojis as emojis_
    from hikari import guilds
    from hikari import traits
    from hikari import users


@typing.final
class ActivityType(int, enums.Enum):
    """The activity type."""

    PLAYING = 0
    """Shows up as `Playing <name>`"""

    STREAMING = 1
    """Shows up as `Streaming` and links to a Twitch or YouTube stream/video.

    .. warning::
        You **MUST** provide a valid Twitch or YouTube stream URL to the
        activity you create in order for this to be valid. If you fail to
        do this, then the activity **WILL NOT** update.
    """

    LISTENING = 2
    """Shows up as `Listening to <name>`."""

    WATCHING = 3
    """Shows up as `Watching <name>`."""

    CUSTOM = 4
    """A custom status.

    To set an emoji with the status, place a unicode emoji or Discord emoji
    (`:smiley:`) as the first part of the status activity name.

    .. warning::
        Bots **DO NOT** support setting custom statuses.
    """

    COMPETING = 5
    """Shows up as `Competing in <name>`."""


@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ActivityTimestamps:
    """The datetimes for the start and/or end of an activity session."""

    start: typing.Optional[datetime.datetime] = attr.field(repr=True)
    """When this activity's session was started, if applicable."""

    end: typing.Optional[datetime.datetime] = attr.field(repr=True)
    """When this activity's session will end, if applicable."""


@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class ActivityParty:
    """Used to represent activity groups of users."""

    id: typing.Optional[str] = attr.field(hash=True, repr=True)
    """The string id of this party instance, if set."""

    current_size: typing.Optional[int] = attr.field(eq=False, hash=False, repr=False)
    """Current size of this party, if applicable."""

    max_size: typing.Optional[int] = attr.field(eq=False, hash=False, repr=False)
    """Maximum size of this party, if applicable."""


_DYNAMIC_URLS = {"mp": urls.MEDIA_PROXY_URL + "/{}"}


@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ActivityAssets:
    """Used to represent possible assets for an activity."""

    _application_id: typing.Optional[snowflakes.Snowflake] = attr.field(repr=False)

    large_image: typing.Optional[str] = attr.field(repr=False)
    """The ID of the asset's large image, if set."""

    large_text: typing.Optional[str] = attr.field(repr=True)
    """The text that'll appear when hovering over the large image, if set."""

    small_image: typing.Optional[str] = attr.field(repr=False)
    """The ID of the asset's small image, if set."""

    small_text: typing.Optional[str] = attr.field(repr=True)
    """The text that'll appear when hovering over the small image, if set."""

    def _make_asset_url(self, asset: typing.Optional[str], ext: str, size: int) -> typing.Optional[files.URL]:
        if asset is None:
            return None

        try:
            resource, identifier = asset.split(":", 1)
            return files.URL(url=_DYNAMIC_URLS[resource].format(identifier))

        except KeyError:
            raise RuntimeError("Unknown asset type") from None

        except ValueError:
            assert self._application_id is not None
            return routes.CDN_APPLICATION_ASSET.compile_to_file(
                urls.CDN_URL,
                application_id=self._application_id,
                hash=asset,
                size=size,
                file_format=ext,
            )

    @property
    def large_image_url(self) -> typing.Optional[files.URL]:
        """Large image asset URL.

        .. note::
            This will be `None` if no large image asset exists or if the
            asset's dynamic URL (indicated by a `{name}:` prefix) is not known.
        """
        try:
            return self.make_large_image_url()

        except RuntimeError:
            return None

    def make_large_image_url(self, *, ext: str = "png", size: int = 4096) -> typing.Optional[files.URL]:
        """Generate the large image asset URL for this application.

        .. note::
            `ext` and `size` are ignored for images hosted outside of Discord
            or on Discord's media proxy.

        Parameters
        ----------
        ext : str
            The extension to use for this URL, defaults to `png`.
            Supports `png`, `jpeg`, `jpg` and `webp`.
        size : int
            The size to set for the URL, defaults to `4096`.
            Can be any power of two between 16 and 4096.

        Returns
        -------
        typing.Optional[hikari.files.URL]
            The URL, or `None` if no icon exists.

        Raises
        ------
        ValueError
            If the size is not an integer power of 2 between 16 and 4096
            (inclusive).
        RuntimeError
            If `ActivityAssets.large_image` points towards an unknown asset type.
        """
        return self._make_asset_url(self.large_image, ext, size)

    @property
    def small_image_url(self) -> typing.Optional[files.URL]:
        """Small image asset URL.

        .. note::
            This will be `None` if no large image asset exists or if the
            asset's dynamic URL (indicated by a `{name}:` prefix) is not known.
        """
        try:
            return self.make_small_image_url()

        except RuntimeError:
            return None

    def make_small_image_url(self, *, ext: str = "png", size: int = 4096) -> typing.Optional[files.URL]:
        """Generate the small image asset URL for this application.

        Parameters
        ----------
        ext : str
            The extension to use for this URL, defaults to `png`.
            Supports `png`, `jpeg`, `jpg` and `webp`.
        size : int
            The size to set for the URL, defaults to `4096`.
            Can be any power of two between 16 and 4096.

        Returns
        -------
        typing.Optional[hikari.files.URL]
            The URL, or `None` if no icon exists.

        Raises
        ------
        ValueError
            If the size is not an integer power of 2 between 16 and 4096
            (inclusive).
        RuntimeError
            If `ActivityAssets.small_image` points towards an unknown asset type.
        """
        return self._make_asset_url(self.small_image, ext, size)


@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ActivitySecret:
    """The secrets used for interacting with an activity party."""

    join: typing.Optional[str] = attr.field(repr=False)
    """The secret used for joining a party, if applicable."""

    spectate: typing.Optional[str] = attr.field(repr=False)
    """The secret used for spectating a party, if applicable."""

    match: typing.Optional[str] = attr.field(repr=False)
    """The secret used for matching a party, if applicable."""


@typing.final
class ActivityFlag(enums.Flag):
    """Flags that describe what an activity includes.

    This can be more than one using bitwise-combinations.
    """

    INSTANCE = 1 << 0
    """Instance"""

    JOIN = 1 << 1
    """Join"""

    SPECTATE = 1 << 2
    """Spectate"""

    JOIN_REQUEST = 1 << 3
    """Join Request"""

    SYNC = 1 << 4
    """Sync"""

    PLAY = 1 << 5
    """Play"""

    PARTY_PRIVACY_FRIENDS = 1 << 6
    """Party privacy: friends only."""

    PARTY_PRIVACY_VOICE_CHANNEL = 1 << 7
    """Party privacy: voice channel only."""

    EMBEDDED = 1 << 8
    """An activity that's embedded into a voice channel."""


# TODO: add strict type checking to gateway for this type in an invariant way.
@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class Activity:
    """Represents a regular activity that can be associated with a presence."""

    name: str = attr.field()
    """The activity name."""

    url: typing.Optional[str] = attr.field(default=None, repr=False)
    """The activity URL. Only valid for `STREAMING` activities."""

    type: typing.Union[ActivityType, int] = attr.field(converter=ActivityType, default=ActivityType.PLAYING)
    """The activity type."""

    def __str__(self) -> str:
        return self.name


@attr.define(hash=False, kw_only=True, weakref_slot=False)
class RichActivity(Activity):
    """Represents a rich activity that can be associated with a presence."""

    created_at: datetime.datetime = attr.field(repr=False)
    """When this activity was added to the user's session."""

    timestamps: typing.Optional[ActivityTimestamps] = attr.field(repr=False)
    """The timestamps for when this activity's current state will start and
    end, if applicable.
    """

    application_id: typing.Optional[snowflakes.Snowflake] = attr.field(repr=False)
    """The ID of the application this activity is for, if applicable."""

    details: typing.Optional[str] = attr.field(repr=False)
    """The text that describes what the activity's target is doing, if set."""

    state: typing.Optional[str] = attr.field(repr=False)
    """The current status of this activity's target, if set."""

    emoji: typing.Optional[emojis_.Emoji] = attr.field(repr=False)
    """The emoji of this activity, if it is a custom status and set."""

    party: typing.Optional[ActivityParty] = attr.field(repr=False)
    """Information about the party associated with this activity, if set."""

    assets: typing.Optional[ActivityAssets] = attr.field(repr=False)
    """Images and their hover over text for the activity."""

    secrets: typing.Optional[ActivitySecret] = attr.field(repr=False)
    """Secrets for Rich Presence joining and spectating."""

    is_instance: typing.Optional[bool] = attr.field(repr=False)
    """Whether this activity is an instanced game session."""

    flags: typing.Optional[ActivityFlag] = attr.field(repr=False)
    """Flags that describe what the activity includes, if present."""

    buttons: typing.Sequence[str] = attr.field(repr=False)
    """A sequence of up to 2 of the button labels shown in this rich presence."""


@typing.final
class Status(str, enums.Enum):
    """The status of a member."""

    ONLINE = "online"
    """Online/green."""

    IDLE = "idle"
    """Idle/yellow."""

    DO_NOT_DISTURB = "dnd"
    """Do not disturb/red."""

    OFFLINE = "offline"
    """Offline or invisible/grey."""


@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ClientStatus:
    """The client statuses for this member."""

    desktop: typing.Union[Status, str] = attr.field(repr=True)
    """The status of the target user's desktop session."""

    mobile: typing.Union[Status, str] = attr.field(repr=True)
    """The status of the target user's mobile session."""

    web: typing.Union[Status, str] = attr.field(repr=True)
    """The status of the target user's web session."""


@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class MemberPresence:
    """Used to represent a guild member's presence."""

    app: traits.RESTAware = attr.field(
        repr=False, eq=False, hash=False, metadata={attr_extensions.SKIP_DEEP_COPY: True}
    )
    """The client application that models may use for procedures."""

    user_id: snowflakes.Snowflake = attr.field(repr=True, hash=True)
    """The ID of the user this presence belongs to."""

    guild_id: snowflakes.Snowflake = attr.field(hash=True, repr=True)
    """The ID of the guild this presence belongs to."""

    visible_status: typing.Union[Status, str] = attr.field(eq=False, hash=False, repr=True)
    """This user's current status being displayed by the client."""

    activities: typing.Sequence[RichActivity] = attr.field(eq=False, hash=False, repr=False)
    """All active user activities.

    You can assume the first activity is the one that the GUI Discord client
    will show.
    """

    client_status: ClientStatus = attr.field(eq=False, hash=False, repr=False)
    """Platform-specific user-statuses."""

    async def fetch_user(self) -> users.User:
        """Fetch the user this presence is for.

        Returns
        -------
        hikari.users.User
            The requested user.

        Raises
        ------
        hikari.errors.UnauthorizedError
            If you are unauthorized to make the request (invalid/missing token).
        hikari.errors.NotFoundError
            If the user is not found.
        hikari.errors.RateLimitTooLongError
            Raised in the event that a rate limit occurs that is
            longer than `max_rate_limit` when making a request.
        hikari.errors.RateLimitedError
            Usually, Hikari will handle and retry on hitting
            rate-limits automatically. This includes most bucket-specific
            rate-limits and global rate-limits. In some rare edge cases,
            however, Discord implements other undocumented rules for
            rate-limiting, such as limits per attribute. These cannot be
            detected or handled normally by Hikari due to their undocumented
            nature, and will trigger this exception if they occur.
        hikari.errors.InternalServerError
            If an internal error occurs on Discord while handling the request.
        """
        return await self.app.rest.fetch_user(self.user_id)

    async def fetch_member(self) -> guilds.Member:
        """Fetch the member this presence is for.

        Returns
        -------
        hikari.guilds.Member
            The requested member.

        Raises
        ------
        hikari.errors.UnauthorizedError
            If you are unauthorized to make the request (invalid/missing token).
        hikari.errors.NotFoundError
            If the user is not found.
        hikari.errors.RateLimitTooLongError
            Raised in the event that a rate limit occurs that is
            longer than `max_rate_limit` when making a request.
        hikari.errors.RateLimitedError
            Usually, Hikari will handle and retry on hitting
            rate-limits automatically. This includes most bucket-specific
            rate-limits and global rate-limits. In some rare edge cases,
            however, Discord implements other undocumented rules for
            rate-limiting, such as limits per attribute. These cannot be
            detected or handled normally by Hikari due to their undocumented
            nature, and will trigger this exception if they occur.
        hikari.errors.InternalServerError
            If an internal error occurs on Discord while handling the request.
        """
        return await self.app.rest.fetch_member(self.guild_id, self.user_id)
#  
@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class Activity:
View Source
@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class Activity:
    """Represents a regular activity that can be associated with a presence."""

    name: str = attr.field()
    """The activity name."""

    url: typing.Optional[str] = attr.field(default=None, repr=False)
    """The activity URL. Only valid for `STREAMING` activities."""

    type: typing.Union[ActivityType, int] = attr.field(converter=ActivityType, default=ActivityType.PLAYING)
    """The activity type."""

    def __str__(self) -> str:
        return self.name

Represents a regular activity that can be associated with a presence.

Variables and properties
#  name: str

The activity name.

The activity type.

#  url: Optional[str]

The activity URL. Only valid for STREAMING activities.

Methods
#  def __init__(
   self,
   *,
   name: str,
   url: Optional[str] = None,
   type: Any = <ActivityType.PLAYING: 0>
):
View Source
def __init__(self, *, name, url=attr_dict['url'].default, type=attr_dict['type'].default):
    _setattr = _cached_setattr.__get__(self, self.__class__)
    _setattr('name', name)
    _setattr('url', url)
    _setattr('type', __attr_converter_type(type))

Method generated by attrs for class Activity.

#  
@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ActivityAssets:
View Source
@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ActivityAssets:
    """Used to represent possible assets for an activity."""

    _application_id: typing.Optional[snowflakes.Snowflake] = attr.field(repr=False)

    large_image: typing.Optional[str] = attr.field(repr=False)
    """The ID of the asset's large image, if set."""

    large_text: typing.Optional[str] = attr.field(repr=True)
    """The text that'll appear when hovering over the large image, if set."""

    small_image: typing.Optional[str] = attr.field(repr=False)
    """The ID of the asset's small image, if set."""

    small_text: typing.Optional[str] = attr.field(repr=True)
    """The text that'll appear when hovering over the small image, if set."""

    def _make_asset_url(self, asset: typing.Optional[str], ext: str, size: int) -> typing.Optional[files.URL]:
        if asset is None:
            return None

        try:
            resource, identifier = asset.split(":", 1)
            return files.URL(url=_DYNAMIC_URLS[resource].format(identifier))

        except KeyError:
            raise RuntimeError("Unknown asset type") from None

        except ValueError:
            assert self._application_id is not None
            return routes.CDN_APPLICATION_ASSET.compile_to_file(
                urls.CDN_URL,
                application_id=self._application_id,
                hash=asset,
                size=size,
                file_format=ext,
            )

    @property
    def large_image_url(self) -> typing.Optional[files.URL]:
        """Large image asset URL.

        .. note::
            This will be `None` if no large image asset exists or if the
            asset's dynamic URL (indicated by a `{name}:` prefix) is not known.
        """
        try:
            return self.make_large_image_url()

        except RuntimeError:
            return None

    def make_large_image_url(self, *, ext: str = "png", size: int = 4096) -> typing.Optional[files.URL]:
        """Generate the large image asset URL for this application.

        .. note::
            `ext` and `size` are ignored for images hosted outside of Discord
            or on Discord's media proxy.

        Parameters
        ----------
        ext : str
            The extension to use for this URL, defaults to `png`.
            Supports `png`, `jpeg`, `jpg` and `webp`.
        size : int
            The size to set for the URL, defaults to `4096`.
            Can be any power of two between 16 and 4096.

        Returns
        -------
        typing.Optional[hikari.files.URL]
            The URL, or `None` if no icon exists.

        Raises
        ------
        ValueError
            If the size is not an integer power of 2 between 16 and 4096
            (inclusive).
        RuntimeError
            If `ActivityAssets.large_image` points towards an unknown asset type.
        """
        return self._make_asset_url(self.large_image, ext, size)

    @property
    def small_image_url(self) -> typing.Optional[files.URL]:
        """Small image asset URL.

        .. note::
            This will be `None` if no large image asset exists or if the
            asset's dynamic URL (indicated by a `{name}:` prefix) is not known.
        """
        try:
            return self.make_small_image_url()

        except RuntimeError:
            return None

    def make_small_image_url(self, *, ext: str = "png", size: int = 4096) -> typing.Optional[files.URL]:
        """Generate the small image asset URL for this application.

        Parameters
        ----------
        ext : str
            The extension to use for this URL, defaults to `png`.
            Supports `png`, `jpeg`, `jpg` and `webp`.
        size : int
            The size to set for the URL, defaults to `4096`.
            Can be any power of two between 16 and 4096.

        Returns
        -------
        typing.Optional[hikari.files.URL]
            The URL, or `None` if no icon exists.

        Raises
        ------
        ValueError
            If the size is not an integer power of 2 between 16 and 4096
            (inclusive).
        RuntimeError
            If `ActivityAssets.small_image` points towards an unknown asset type.
        """
        return self._make_asset_url(self.small_image, ext, size)

Used to represent possible assets for an activity.

Variables and properties
#  large_image: Optional[str]

The ID of the asset's large image, if set.

#  large_image_url: Optional[hikari.files.URL]

Large image asset URL.

Note: This will be None if no large image asset exists or if the asset's dynamic URL (indicated by a {name}: prefix) is not known.

#  large_text: Optional[str]

The text that'll appear when hovering over the large image, if set.

#  small_image: Optional[str]

The ID of the asset's small image, if set.

#  small_image_url: Optional[hikari.files.URL]

Small image asset URL.

Note: This will be None if no large image asset exists or if the asset's dynamic URL (indicated by a {name}: prefix) is not known.

#  small_text: Optional[str]

The text that'll appear when hovering over the small image, if set.

Methods
#  def __init__(
   self,
   *,
   application_id: Optional[hikari.snowflakes.Snowflake],
   large_image: Optional[str],
   large_text: Optional[str],
   small_image: Optional[str],
   small_text: Optional[str]
):
View Source
def __init__(self, *, application_id, large_image, large_text, small_image, small_text):
    self._application_id = application_id
    self.large_image = large_image
    self.large_text = large_text
    self.small_image = small_image
    self.small_text = small_text

Method generated by attrs for class ActivityAssets.

#  def make_large_image_url(
   self,
   *,
   ext: str = 'png',
   size: int = 4096
) -> Optional[hikari.files.URL]:
View Source
    def make_large_image_url(self, *, ext: str = "png", size: int = 4096) -> typing.Optional[files.URL]:
        """Generate the large image asset URL for this application.

        .. note::
            `ext` and `size` are ignored for images hosted outside of Discord
            or on Discord's media proxy.

        Parameters
        ----------
        ext : str
            The extension to use for this URL, defaults to `png`.
            Supports `png`, `jpeg`, `jpg` and `webp`.
        size : int
            The size to set for the URL, defaults to `4096`.
            Can be any power of two between 16 and 4096.

        Returns
        -------
        typing.Optional[hikari.files.URL]
            The URL, or `None` if no icon exists.

        Raises
        ------
        ValueError
            If the size is not an integer power of 2 between 16 and 4096
            (inclusive).
        RuntimeError
            If `ActivityAssets.large_image` points towards an unknown asset type.
        """
        return self._make_asset_url(self.large_image, ext, size)

Generate the large image asset URL for this application.

Note: ext and size are ignored for images hosted outside of Discord or on Discord's media proxy.

Parameters
  • ext (str): The extension to use for this URL, defaults to png. Supports png, jpeg, jpg and webp.
  • size (int): The size to set for the URL, defaults to 4096. Can be any power of two between 16 and 4096.
Returns
Raises
  • ValueError: If the size is not an integer power of 2 between 16 and 4096 (inclusive).
  • RuntimeError: If ActivityAssets.large_image points towards an unknown asset type.
#  def make_small_image_url(
   self,
   *,
   ext: str = 'png',
   size: int = 4096
) -> Optional[hikari.files.URL]:
View Source
    def make_small_image_url(self, *, ext: str = "png", size: int = 4096) -> typing.Optional[files.URL]:
        """Generate the small image asset URL for this application.

        Parameters
        ----------
        ext : str
            The extension to use for this URL, defaults to `png`.
            Supports `png`, `jpeg`, `jpg` and `webp`.
        size : int
            The size to set for the URL, defaults to `4096`.
            Can be any power of two between 16 and 4096.

        Returns
        -------
        typing.Optional[hikari.files.URL]
            The URL, or `None` if no icon exists.

        Raises
        ------
        ValueError
            If the size is not an integer power of 2 between 16 and 4096
            (inclusive).
        RuntimeError
            If `ActivityAssets.small_image` points towards an unknown asset type.
        """
        return self._make_asset_url(self.small_image, ext, size)

Generate the small image asset URL for this application.

Parameters
  • ext (str): The extension to use for this URL, defaults to png. Supports png, jpeg, jpg and webp.
  • size (int): The size to set for the URL, defaults to 4096. Can be any power of two between 16 and 4096.
Returns
Raises
  • ValueError: If the size is not an integer power of 2 between 16 and 4096 (inclusive).
  • RuntimeError: If ActivityAssets.small_image points towards an unknown asset type.
#  
@typing.final
class ActivityFlag(builtins.int, hikari.internal.enums.Flag):
View Source
@typing.final
class ActivityFlag(enums.Flag):
    """Flags that describe what an activity includes.

    This can be more than one using bitwise-combinations.
    """

    INSTANCE = 1 << 0
    """Instance"""

    JOIN = 1 << 1
    """Join"""

    SPECTATE = 1 << 2
    """Spectate"""

    JOIN_REQUEST = 1 << 3
    """Join Request"""

    SYNC = 1 << 4
    """Sync"""

    PLAY = 1 << 5
    """Play"""

    PARTY_PRIVACY_FRIENDS = 1 << 6
    """Party privacy: friends only."""

    PARTY_PRIVACY_VOICE_CHANNEL = 1 << 7
    """Party privacy: voice channel only."""

    EMBEDDED = 1 << 8
    """An activity that's embedded into a voice channel."""

Flags that describe what an activity includes.

This can be more than one using bitwise-combinations.

Variables and properties
#  EMBEDDED

An activity that's embedded into a voice channel.

#  INSTANCE

Instance

#  JOIN

Join

#  JOIN_REQUEST

Join Request

#  PARTY_PRIVACY_FRIENDS

Party privacy: friends only.

#  PARTY_PRIVACY_VOICE_CHANNEL

Party privacy: voice channel only.

#  PLAY

Play

#  SPECTATE

Spectate

#  SYNC

Sync

#  denominator

the denominator of a rational number in lowest terms

#  imag

the imaginary part of a complex number

#  name: str

Return the name of the flag combination as a str.

#  numerator

the numerator of a rational number in lowest terms

#  real

the real part of a complex number

#  value: int

Return the int value of the flag.

Methods
#  def __init__(cls, value: int = 0):
View Source
    def __call__(cls, value: int = 0) -> typing.Any:
        """Cast a value to the flag enum, returning the raw value that was passed if values not found."""
        # We want to handle value invariantly to avoid issues brought in by different behaviours from sub-classed ints
        # and floats. This also ensures that .__int__ only returns an invariant int.
        value = int(value)
        try:
            return cls._value_to_member_map_[value]
        except KeyError:
            # We only need this ability here usually, so overloading operators
            # is an overkill and would add more overhead.

            if value < 0:
                # Convert to a positive value instead.
                return cls.__everything__ - ~value

            temp_members = cls._temp_members_
            # For huge enums, don't ever cache anything. We could consume masses of memory otherwise
            # (e.g. Permissions)
            try:
                # Try to get a cached value.
                return temp_members[value]
            except KeyError:
                # If we can't find the value, just return what got casted in by generating a pseudomember
                # and caching it. We can't use weakref because int is not weak referenceable, annoyingly.
                pseudomember = cls.__new__(cls, value)
                pseudomember._name_ = None
                pseudomember._value_ = value
                temp_members[value] = pseudomember
                if len(temp_members) > _MAX_CACHED_MEMBERS:
                    temp_members.popitem()

                return pseudomember

Cast a value to the flag enum, returning the raw value that was passed if values not found.

#  def all(self: ~_T, *flags: ~_T) -> bool:
View Source
    def all(self: _T, *flags: _T) -> bool:
        """Check if all of the given flags are part of this value.

        Returns
        -------
        bool
            `True` if any of the given flags are part of this value.
            Otherwise, return `False`.
        """
        return all((flag & self) == flag for flag in flags)

Check if all of the given flags are part of this value.

Returns
  • bool: True if any of the given flags are part of this value. Otherwise, return False.
#  def any(self: ~_T, *flags: ~_T) -> bool:
View Source
    def any(self: _T, *flags: _T) -> bool:
        """Check if any of the given flags are part of this value.

        Returns
        -------
        bool
            `True` if any of the given flags are part of this value.
            Otherwise, return `False`.
        """
        return any((flag & self) == flag for flag in flags)

Check if any of the given flags are part of this value.

Returns
  • bool: True if any of the given flags are part of this value. Otherwise, return False.
#  def as_integer_ratio(self, /):

Return integer ratio.

Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.

>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
#  def bit_length(self, /):

Number of bits necessary to represent self in binary.

>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
#  def conjugate(unknown):

Returns self, the complex conjugate of any int.

#  def difference(self: ~_T, other: Union[~_T, int]) -> ~_T:
View Source
    def difference(self: _T, other: typing.Union[_T, int]) -> _T:
        """Perform a set difference with the other set.

        This will return all flags in this set that are not in the other value.

        Equivalent to using the subtraction `-` operator.
        """
        return self.__class__(self & ~int(other))

Perform a set difference with the other set.

This will return all flags in this set that are not in the other value.

Equivalent to using the subtraction - operator.

#  def from_bytes(type, /, bytes, byteorder, *, signed=False):

Return the integer represented by the given array of bytes.

bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Indicates whether two's complement is used to represent the integer.

#  def intersection(self: ~_T, other: Union[~_T, int]) -> ~_T:
View Source
    def intersection(self: _T, other: typing.Union[_T, int]) -> _T:
        """Return a combination of flags that are set for both given values.

        Equivalent to using the "AND" `&` operator.
        """
        return self.__class__(self._value_ & int(other))

Return a combination of flags that are set for both given values.

Equivalent to using the "AND" & operator.

#  def invert(self: ~_T) -> ~_T:
View Source
    def invert(self: _T) -> _T:
        """Return a set of all flags not in the current set."""
        return self.__class__(self.__class__.__everything__._value_ & ~self._value_)

Return a set of all flags not in the current set.

#  def is_disjoint(self: ~_T, other: Union[~_T, int]) -> bool:
View Source
    def is_disjoint(self: _T, other: typing.Union[_T, int]) -> bool:
        """Return whether two sets have a intersection or not.

        If the two sets have an intersection, then this returns
        `False`. If no common flag values exist between them, then
        this returns `True`.
        """
        return not (self & other)

Return whether two sets have a intersection or not.

If the two sets have an intersection, then this returns False. If no common flag values exist between them, then this returns True.

#  def is_subset(self: ~_T, other: Union[~_T, int]) -> bool:
View Source
    def is_subset(self: _T, other: typing.Union[_T, int]) -> bool:
        """Return whether another set contains this set or not.

        Equivalent to using the "in" operator.
        """
        return (self & other) == other

Return whether another set contains this set or not.

Equivalent to using the "in" operator.

#  def is_superset(self: ~_T, other: Union[~_T, int]) -> bool:
View Source
    def is_superset(self: _T, other: typing.Union[_T, int]) -> bool:
        """Return whether this set contains another set or not."""
        return (self & other) == self

Return whether this set contains another set or not.

#  def isdisjoint(self: ~_T, other: Union[~_T, int]) -> bool:
View Source
    def is_disjoint(self: _T, other: typing.Union[_T, int]) -> bool:
        """Return whether two sets have a intersection or not.

        If the two sets have an intersection, then this returns
        `False`. If no common flag values exist between them, then
        this returns `True`.
        """
        return not (self & other)

Return whether two sets have a intersection or not.

If the two sets have an intersection, then this returns False. If no common flag values exist between them, then this returns True.

#  def issubset(self: ~_T, other: Union[~_T, int]) -> bool:
View Source
    def is_subset(self: _T, other: typing.Union[_T, int]) -> bool:
        """Return whether another set contains this set or not.

        Equivalent to using the "in" operator.
        """
        return (self & other) == other

Return whether another set contains this set or not.

Equivalent to using the "in" operator.

#  def issuperset(self: ~_T, other: Union[~_T, int]) -> bool:
View Source
    def is_superset(self: _T, other: typing.Union[_T, int]) -> bool:
        """Return whether this set contains another set or not."""
        return (self & other) == self

Return whether this set contains another set or not.

#  def none(self: ~_T, *flags: ~_T) -> bool:
View Source
    def none(self: _T, *flags: _T) -> bool:
        """Check if none of the given flags are part of this value.

        .. note::
            This is essentially the opposite of `Flag.any`.

        Returns
        -------
        bool
            `True` if none of the given flags are part of this value.
            Otherwise, return `False`.
        """
        return not self.any(*flags)

Check if none of the given flags are part of this value.

Note: This is essentially the opposite of Flag.any.

Returns
  • bool: True if none of the given flags are part of this value. Otherwise, return False.
#  def split(self: ~_T) -> Sequence[~_T]:
View Source
    def split(self: _T) -> typing.Sequence[_T]:
        """Return a list of all defined atomic values for this flag.

        Any unrecognised bits will be omitted for brevity.

        The result will be a name-sorted `typing.Sequence` of each member
        """
        return sorted(
            (member for member in self.__class__._powers_of_2_to_member_map_.values() if member.value & self),
            # Assumption: powers of 2 already have a cached value.
            key=lambda m: m._name_,
        )

Return a list of all defined atomic values for this flag.

Any unrecognised bits will be omitted for brevity.

The result will be a name-sorted typing.Sequence of each member

#  def symmetric_difference(self: ~_T, other: Union[~_T, int]) -> ~_T:
View Source
    def symmetric_difference(self: _T, other: typing.Union[_T, int]) -> _T:
        """Return a set with the symmetric differences of two flag sets.

        Equivalent to using the "XOR" `^` operator.

        For `a ^ b`, this can be considered the same as `(a - b) | (b - a)`.
        """
        return self.__class__(self._value_ ^ int(other))

Return a set with the symmetric differences of two flag sets.

Equivalent to using the "XOR" ^ operator.

For a ^ b, this can be considered the same as (a - b) | (b - a).

#  def symmetricdifference(self: ~_T, other: Union[~_T, int]) -> ~_T:
View Source
    def symmetric_difference(self: _T, other: typing.Union[_T, int]) -> _T:
        """Return a set with the symmetric differences of two flag sets.

        Equivalent to using the "XOR" `^` operator.

        For `a ^ b`, this can be considered the same as `(a - b) | (b - a)`.
        """
        return self.__class__(self._value_ ^ int(other))

Return a set with the symmetric differences of two flag sets.

Equivalent to using the "XOR" ^ operator.

For a ^ b, this can be considered the same as (a - b) | (b - a).

#  def to_bytes(self, /, length, byteorder, *, signed=False):

Return an array of bytes representing an integer.

length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.

#  def union(self: ~_T, other: Union[~_T, int]) -> ~_T:
View Source
    def union(self: _T, other: typing.Union[_T, int]) -> _T:
        """Return a combination of all flags in this set and the other set.

        Equivalent to using the "OR" `~` operator.
        """
        return self.__class__(self._value_ | int(other))

Return a combination of all flags in this set and the other set.

Equivalent to using the "OR" ~ operator.

#  
@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class ActivityParty:
View Source
@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class ActivityParty:
    """Used to represent activity groups of users."""

    id: typing.Optional[str] = attr.field(hash=True, repr=True)
    """The string id of this party instance, if set."""

    current_size: typing.Optional[int] = attr.field(eq=False, hash=False, repr=False)
    """Current size of this party, if applicable."""

    max_size: typing.Optional[int] = attr.field(eq=False, hash=False, repr=False)
    """Maximum size of this party, if applicable."""

Used to represent activity groups of users.

Variables and properties
#  current_size: Optional[int]

Current size of this party, if applicable.

#  id: Optional[str]

The string id of this party instance, if set.

#  max_size: Optional[int]

Maximum size of this party, if applicable.

Methods
#  def __init__(
   self,
   *,
   id: Optional[str],
   current_size: Optional[int],
   max_size: Optional[int]
):
View Source
def __init__(self, *, id, current_size, max_size):
    self.id = id
    self.current_size = current_size
    self.max_size = max_size

Method generated by attrs for class ActivityParty.

#  
@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ActivitySecret:
View Source
@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ActivitySecret:
    """The secrets used for interacting with an activity party."""

    join: typing.Optional[str] = attr.field(repr=False)
    """The secret used for joining a party, if applicable."""

    spectate: typing.Optional[str] = attr.field(repr=False)
    """The secret used for spectating a party, if applicable."""

    match: typing.Optional[str] = attr.field(repr=False)
    """The secret used for matching a party, if applicable."""

The secrets used for interacting with an activity party.

Variables and properties
#  join: Optional[str]

The secret used for joining a party, if applicable.

#  match: Optional[str]

The secret used for matching a party, if applicable.

#  spectate: Optional[str]

The secret used for spectating a party, if applicable.

Methods
#  def __init__(
   self,
   *,
   join: Optional[str],
   spectate: Optional[str],
   match: Optional[str]
):
View Source
def __init__(self, *, join, spectate, match):
    self.join = join
    self.spectate = spectate
    self.match = match

Method generated by attrs for class ActivitySecret.

#  
@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ActivityTimestamps:
View Source
@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ActivityTimestamps:
    """The datetimes for the start and/or end of an activity session."""

    start: typing.Optional[datetime.datetime] = attr.field(repr=True)
    """When this activity's session was started, if applicable."""

    end: typing.Optional[datetime.datetime] = attr.field(repr=True)
    """When this activity's session will end, if applicable."""

The datetimes for the start and/or end of an activity session.

Variables and properties
#  end: Optional[datetime.datetime]

When this activity's session will end, if applicable.

#  start: Optional[datetime.datetime]

When this activity's session was started, if applicable.

Methods
#  def __init__(
   self,
   *,
   start: Optional[datetime.datetime],
   end: Optional[datetime.datetime]
):
View Source
def __init__(self, *, start, end):
    self.start = start
    self.end = end

Method generated by attrs for class ActivityTimestamps.

#  
@typing.final
class ActivityType(builtins.int, hikari.internal.enums.Enum):
View Source
@typing.final
class ActivityType(int, enums.Enum):
    """The activity type."""

    PLAYING = 0
    """Shows up as `Playing <name>`"""

    STREAMING = 1
    """Shows up as `Streaming` and links to a Twitch or YouTube stream/video.

    .. warning::
        You **MUST** provide a valid Twitch or YouTube stream URL to the
        activity you create in order for this to be valid. If you fail to
        do this, then the activity **WILL NOT** update.
    """

    LISTENING = 2
    """Shows up as `Listening to <name>`."""

    WATCHING = 3
    """Shows up as `Watching <name>`."""

    CUSTOM = 4
    """A custom status.

    To set an emoji with the status, place a unicode emoji or Discord emoji
    (`:smiley:`) as the first part of the status activity name.

    .. warning::
        Bots **DO NOT** support setting custom statuses.
    """

    COMPETING = 5
    """Shows up as `Competing in <name>`."""

The activity type.

Variables and properties
#  COMPETING

Shows up as Competing in <name>.

#  CUSTOM

A custom status.

To set an emoji with the status, place a unicode emoji or Discord emoji (:smiley:) as the first part of the status activity name.

Warning: Bots DO NOT support setting custom statuses.

#  LISTENING

Shows up as Listening to <name>.

#  PLAYING

Shows up as Playing <name>

#  STREAMING

Shows up as Streaming and links to a Twitch or YouTube stream/video.

Warning: You MUST provide a valid Twitch or YouTube stream URL to the activity you create in order for this to be valid. If you fail to do this, then the activity WILL NOT update.

#  WATCHING

Shows up as Watching <name>.

#  denominator

the denominator of a rational number in lowest terms

#  imag

the imaginary part of a complex number

#  name: str

Return the name of the enum member as a str.

#  numerator

the numerator of a rational number in lowest terms

#  real

the real part of a complex number

#  value

Return the value of the enum member.

Methods
#  def __init__(cls, value: Any):
View Source
    def __call__(cls, value: typing.Any) -> typing.Any:
        """Cast a value to the enum, returning the raw value that was passed if value not found."""
        try:
            return cls._value_to_member_map_[value]
        except KeyError:
            # If we can't find the value, just return what got casted in
            return value

Cast a value to the enum, returning the raw value that was passed if value not found.

#  def as_integer_ratio(self, /):

Return integer ratio.

Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.

>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
#  def bit_length(self, /):

Number of bits necessary to represent self in binary.

>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
#  def conjugate(unknown):

Returns self, the complex conjugate of any int.

#  def from_bytes(type, /, bytes, byteorder, *, signed=False):

Return the integer represented by the given array of bytes.

bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Indicates whether two's complement is used to represent the integer.

#  def to_bytes(self, /, length, byteorder, *, signed=False):

Return an array of bytes representing an integer.

length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.

#  
@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ClientStatus:
View Source
@attr_extensions.with_copy
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class ClientStatus:
    """The client statuses for this member."""

    desktop: typing.Union[Status, str] = attr.field(repr=True)
    """The status of the target user's desktop session."""

    mobile: typing.Union[Status, str] = attr.field(repr=True)
    """The status of the target user's mobile session."""

    web: typing.Union[Status, str] = attr.field(repr=True)
    """The status of the target user's web session."""

The client statuses for this member.

Variables and properties
#  desktop: Union[hikari.presences.Status, str]

The status of the target user's desktop session.

#  mobile: Union[hikari.presences.Status, str]

The status of the target user's mobile session.

The status of the target user's web session.

Methods
#  def __init__(
   self,
   *,
   desktop: Union[hikari.presences.Status, str],
   mobile: Union[hikari.presences.Status, str],
   web: Union[hikari.presences.Status, str]
):
View Source
def __init__(self, *, desktop, mobile, web):
    self.desktop = desktop
    self.mobile = mobile
    self.web = web

Method generated by attrs for class ClientStatus.

#  
@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class MemberPresence:
View Source
@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class MemberPresence:
    """Used to represent a guild member's presence."""

    app: traits.RESTAware = attr.field(
        repr=False, eq=False, hash=False, metadata={attr_extensions.SKIP_DEEP_COPY: True}
    )
    """The client application that models may use for procedures."""

    user_id: snowflakes.Snowflake = attr.field(repr=True, hash=True)
    """The ID of the user this presence belongs to."""

    guild_id: snowflakes.Snowflake = attr.field(hash=True, repr=True)
    """The ID of the guild this presence belongs to."""

    visible_status: typing.Union[Status, str] = attr.field(eq=False, hash=False, repr=True)
    """This user's current status being displayed by the client."""

    activities: typing.Sequence[RichActivity] = attr.field(eq=False, hash=False, repr=False)
    """All active user activities.

    You can assume the first activity is the one that the GUI Discord client
    will show.
    """

    client_status: ClientStatus = attr.field(eq=False, hash=False, repr=False)
    """Platform-specific user-statuses."""

    async def fetch_user(self) -> users.User:
        """Fetch the user this presence is for.

        Returns
        -------
        hikari.users.User
            The requested user.

        Raises
        ------
        hikari.errors.UnauthorizedError
            If you are unauthorized to make the request (invalid/missing token).
        hikari.errors.NotFoundError
            If the user is not found.
        hikari.errors.RateLimitTooLongError
            Raised in the event that a rate limit occurs that is
            longer than `max_rate_limit` when making a request.
        hikari.errors.RateLimitedError
            Usually, Hikari will handle and retry on hitting
            rate-limits automatically. This includes most bucket-specific
            rate-limits and global rate-limits. In some rare edge cases,
            however, Discord implements other undocumented rules for
            rate-limiting, such as limits per attribute. These cannot be
            detected or handled normally by Hikari due to their undocumented
            nature, and will trigger this exception if they occur.
        hikari.errors.InternalServerError
            If an internal error occurs on Discord while handling the request.
        """
        return await self.app.rest.fetch_user(self.user_id)

    async def fetch_member(self) -> guilds.Member:
        """Fetch the member this presence is for.

        Returns
        -------
        hikari.guilds.Member
            The requested member.

        Raises
        ------
        hikari.errors.UnauthorizedError
            If you are unauthorized to make the request (invalid/missing token).
        hikari.errors.NotFoundError
            If the user is not found.
        hikari.errors.RateLimitTooLongError
            Raised in the event that a rate limit occurs that is
            longer than `max_rate_limit` when making a request.
        hikari.errors.RateLimitedError
            Usually, Hikari will handle and retry on hitting
            rate-limits automatically. This includes most bucket-specific
            rate-limits and global rate-limits. In some rare edge cases,
            however, Discord implements other undocumented rules for
            rate-limiting, such as limits per attribute. These cannot be
            detected or handled normally by Hikari due to their undocumented
            nature, and will trigger this exception if they occur.
        hikari.errors.InternalServerError
            If an internal error occurs on Discord while handling the request.
        """
        return await self.app.rest.fetch_member(self.guild_id, self.user_id)

Used to represent a guild member's presence.

Variables and properties

All active user activities.

You can assume the first activity is the one that the GUI Discord client will show.

The client application that models may use for procedures.

Platform-specific user-statuses.

The ID of the guild this presence belongs to.

The ID of the user this presence belongs to.

#  visible_status: Union[hikari.presences.Status, str]

This user's current status being displayed by the client.

Methods
#  def __init__(
   self,
   *,
   app: hikari.traits.RESTAware,
   user_id: hikari.snowflakes.Snowflake,
   guild_id: hikari.snowflakes.Snowflake,
   visible_status: Union[hikari.presences.Status, str],
   activities: Sequence[hikari.presences.RichActivity],
   client_status: hikari.presences.ClientStatus
):
View Source
def __init__(self, *, app, user_id, guild_id, visible_status, activities, client_status):
    self.app = app
    self.user_id = user_id
    self.guild_id = guild_id
    self.visible_status = visible_status
    self.activities = activities
    self.client_status = client_status

Method generated by attrs for class MemberPresence.

#  async def fetch_member(self) -> hikari.guilds.Member:
View Source
    async def fetch_member(self) -> guilds.Member:
        """Fetch the member this presence is for.

        Returns
        -------
        hikari.guilds.Member
            The requested member.

        Raises
        ------
        hikari.errors.UnauthorizedError
            If you are unauthorized to make the request (invalid/missing token).
        hikari.errors.NotFoundError
            If the user is not found.
        hikari.errors.RateLimitTooLongError
            Raised in the event that a rate limit occurs that is
            longer than `max_rate_limit` when making a request.
        hikari.errors.RateLimitedError
            Usually, Hikari will handle and retry on hitting
            rate-limits automatically. This includes most bucket-specific
            rate-limits and global rate-limits. In some rare edge cases,
            however, Discord implements other undocumented rules for
            rate-limiting, such as limits per attribute. These cannot be
            detected or handled normally by Hikari due to their undocumented
            nature, and will trigger this exception if they occur.
        hikari.errors.InternalServerError
            If an internal error occurs on Discord while handling the request.
        """
        return await self.app.rest.fetch_member(self.guild_id, self.user_id)

Fetch the member this presence is for.

Returns
Raises
  • hikari.errors.UnauthorizedError: If you are unauthorized to make the request (invalid/missing token).
  • hikari.errors.NotFoundError: If the user is not found.
  • hikari.errors.RateLimitTooLongError: Raised in the event that a rate limit occurs that is longer than max_rate_limit when making a request.
  • hikari.errors.RateLimitedError: Usually, Hikari will handle and retry on hitting rate-limits automatically. This includes most bucket-specific rate-limits and global rate-limits. In some rare edge cases, however, Discord implements other undocumented rules for rate-limiting, such as limits per attribute. These cannot be detected or handled normally by Hikari due to their undocumented nature, and will trigger this exception if they occur.
  • hikari.errors.InternalServerError: If an internal error occurs on Discord while handling the request.
#  async def fetch_user(self) -> hikari.users.User:
View Source
    async def fetch_user(self) -> users.User:
        """Fetch the user this presence is for.

        Returns
        -------
        hikari.users.User
            The requested user.

        Raises
        ------
        hikari.errors.UnauthorizedError
            If you are unauthorized to make the request (invalid/missing token).
        hikari.errors.NotFoundError
            If the user is not found.
        hikari.errors.RateLimitTooLongError
            Raised in the event that a rate limit occurs that is
            longer than `max_rate_limit` when making a request.
        hikari.errors.RateLimitedError
            Usually, Hikari will handle and retry on hitting
            rate-limits automatically. This includes most bucket-specific
            rate-limits and global rate-limits. In some rare edge cases,
            however, Discord implements other undocumented rules for
            rate-limiting, such as limits per attribute. These cannot be
            detected or handled normally by Hikari due to their undocumented
            nature, and will trigger this exception if they occur.
        hikari.errors.InternalServerError
            If an internal error occurs on Discord while handling the request.
        """
        return await self.app.rest.fetch_user(self.user_id)

Fetch the user this presence is for.

Returns
Raises
  • hikari.errors.UnauthorizedError: If you are unauthorized to make the request (invalid/missing token).
  • hikari.errors.NotFoundError: If the user is not found.
  • hikari.errors.RateLimitTooLongError: Raised in the event that a rate limit occurs that is longer than max_rate_limit when making a request.
  • hikari.errors.RateLimitedError: Usually, Hikari will handle and retry on hitting rate-limits automatically. This includes most bucket-specific rate-limits and global rate-limits. In some rare edge cases, however, Discord implements other undocumented rules for rate-limiting, such as limits per attribute. These cannot be detected or handled normally by Hikari due to their undocumented nature, and will trigger this exception if they occur.
  • hikari.errors.InternalServerError: If an internal error occurs on Discord while handling the request.
#  
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class RichActivity(Activity):
View Source
@attr.define(hash=False, kw_only=True, weakref_slot=False)
class RichActivity(Activity):
    """Represents a rich activity that can be associated with a presence."""

    created_at: datetime.datetime = attr.field(repr=False)
    """When this activity was added to the user's session."""

    timestamps: typing.Optional[ActivityTimestamps] = attr.field(repr=False)
    """The timestamps for when this activity's current state will start and
    end, if applicable.
    """

    application_id: typing.Optional[snowflakes.Snowflake] = attr.field(repr=False)
    """The ID of the application this activity is for, if applicable."""

    details: typing.Optional[str] = attr.field(repr=False)
    """The text that describes what the activity's target is doing, if set."""

    state: typing.Optional[str] = attr.field(repr=False)
    """The current status of this activity's target, if set."""

    emoji: typing.Optional[emojis_.Emoji] = attr.field(repr=False)
    """The emoji of this activity, if it is a custom status and set."""

    party: typing.Optional[ActivityParty] = attr.field(repr=False)
    """Information about the party associated with this activity, if set."""

    assets: typing.Optional[ActivityAssets] = attr.field(repr=False)
    """Images and their hover over text for the activity."""

    secrets: typing.Optional[ActivitySecret] = attr.field(repr=False)
    """Secrets for Rich Presence joining and spectating."""

    is_instance: typing.Optional[bool] = attr.field(repr=False)
    """Whether this activity is an instanced game session."""

    flags: typing.Optional[ActivityFlag] = attr.field(repr=False)
    """Flags that describe what the activity includes, if present."""

    buttons: typing.Sequence[str] = attr.field(repr=False)
    """A sequence of up to 2 of the button labels shown in this rich presence."""

Represents a rich activity that can be associated with a presence.

Variables and properties
#  application_id: Optional[hikari.snowflakes.Snowflake]

The ID of the application this activity is for, if applicable.

Images and their hover over text for the activity.

#  buttons: Sequence[str]

A sequence of up to 2 of the button labels shown in this rich presence.

#  created_at: datetime.datetime

When this activity was added to the user's session.

#  details: Optional[str]

The text that describes what the activity's target is doing, if set.

#  emoji: Optional[hikari.emojis.Emoji]

The emoji of this activity, if it is a custom status and set.

Flags that describe what the activity includes, if present.

#  is_instance: Optional[bool]

Whether this activity is an instanced game session.

#  name: str

The activity name.

Information about the party associated with this activity, if set.

Secrets for Rich Presence joining and spectating.

#  state: Optional[str]

The current status of this activity's target, if set.

The timestamps for when this activity's current state will start and end, if applicable.

The activity type.

#  url: Optional[str]

The activity URL. Only valid for STREAMING activities.

Methods
#  def __init__(
   self,
   *,
   name: str,
   url: Optional[str] = None,
   type: Any = <ActivityType.PLAYING: 0>,
   created_at: datetime.datetime,
   timestamps: Optional[hikari.presences.ActivityTimestamps],
   application_id: Optional[hikari.snowflakes.Snowflake],
   details: Optional[str],
   state: Optional[str],
   emoji: Optional[hikari.emojis.Emoji],
   party: Optional[hikari.presences.ActivityParty],
   assets: Optional[hikari.presences.ActivityAssets],
   secrets: Optional[hikari.presences.ActivitySecret],
   is_instance: Optional[bool],
   flags: Optional[hikari.presences.ActivityFlag],
   buttons: Sequence[str]
):
View Source
def __init__(self, *, name, url=attr_dict['url'].default, type=attr_dict['type'].default, created_at, timestamps, application_id, details, state, emoji, party, assets, secrets, is_instance, flags, buttons):
    _setattr = _cached_setattr.__get__(self, self.__class__)
    _setattr('name', name)
    _setattr('url', url)
    _setattr('type', __attr_converter_type(type))
    _setattr('created_at', created_at)
    _setattr('timestamps', timestamps)
    _setattr('application_id', application_id)
    _setattr('details', details)
    _setattr('state', state)
    _setattr('emoji', emoji)
    _setattr('party', party)
    _setattr('assets', assets)
    _setattr('secrets', secrets)
    _setattr('is_instance', is_instance)
    _setattr('flags', flags)
    _setattr('buttons', buttons)

Method generated by attrs for class RichActivity.

#  
@typing.final
class Status(builtins.str, hikari.internal.enums.Enum):
View Source
@typing.final
class Status(str, enums.Enum):
    """The status of a member."""

    ONLINE = "online"
    """Online/green."""

    IDLE = "idle"
    """Idle/yellow."""

    DO_NOT_DISTURB = "dnd"
    """Do not disturb/red."""

    OFFLINE = "offline"
    """Offline or invisible/grey."""

The status of a member.

Variables and properties
#  DO_NOT_DISTURB

Do not disturb/red.

#  IDLE

Idle/yellow.

#  OFFLINE

Offline or invisible/grey.

#  ONLINE

Online/green.

#  name: str

Return the name of the enum member as a str.

#  value

Return the value of the enum member.

Methods
#  def __init__(cls, value: Any):
View Source
    def __call__(cls, value: typing.Any) -> typing.Any:
        """Cast a value to the enum, returning the raw value that was passed if value not found."""
        try:
            return cls._value_to_member_map_[value]
        except KeyError:
            # If we can't find the value, just return what got casted in
            return value

Cast a value to the enum, returning the raw value that was passed if value not found.

#  def capitalize(self, /):

Return a capitalized version of the string.

More specifically, make the first character have upper case and the rest lower case.

#  def casefold(self, /):

Return a version of the string suitable for caseless comparisons.

#  def center(self, width, fillchar=' ', /):

Return a centered string of length width.

Padding is done using the specified fill character (default is a space).

#  def count(unknown):

S.count(sub[, start[, end]]) -> int

Return the number of non-overlapping occurrences of substring sub in string S[start:end]. Optional arguments start and end are interpreted as in slice notation.

#  def encode(self, /, encoding='utf-8', errors='strict'):

Encode the string using the codec registered for encoding.

encoding The encoding in which to encode the string. errors The error handling scheme to use for encoding errors. The default is 'strict' meaning that encoding errors raise a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name registered with codecs.register_error that can handle UnicodeEncodeErrors.

#  def endswith(unknown):

S.endswith(suffix[, start[, end]]) -> bool

Return True if S ends with the specified suffix, False otherwise. With optional start, test S beginning at that position. With optional end, stop comparing S at that position. suffix can also be a tuple of strings to try.

#  def expandtabs(self, /, tabsize=8):

Return a copy where all tab characters are expanded using spaces.

If tabsize is not given, a tab size of 8 characters is assumed.

#  def find(unknown):

S.find(sub[, start[, end]]) -> int

Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end]. Optional arguments start and end are interpreted as in slice notation.

Return -1 on failure.

#  def format(unknown):

S.format(args, *kwargs) -> str

Return a formatted version of S, using substitutions from args and kwargs. The substitutions are identified by braces ('{' and '}').

#  def format_map(unknown):

S.format_map(mapping) -> str

Return a formatted version of S, using substitutions from mapping. The substitutions are identified by braces ('{' and '}').

#  def index(unknown):

S.index(sub[, start[, end]]) -> int

Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end]. Optional arguments start and end are interpreted as in slice notation.

Raises ValueError when the substring is not found.

#  def isalnum(self, /):

Return True if the string is an alpha-numeric string, False otherwise.

A string is alpha-numeric if all characters in the string are alpha-numeric and there is at least one character in the string.

#  def isalpha(self, /):

Return True if the string is an alphabetic string, False otherwise.

A string is alphabetic if all characters in the string are alphabetic and there is at least one character in the string.

#  def isascii(self, /):

Return True if all characters in the string are ASCII, False otherwise.

ASCII characters have code points in the range U+0000-U+007F. Empty string is ASCII too.

#  def isdecimal(self, /):

Return True if the string is a decimal string, False otherwise.

A string is a decimal string if all characters in the string are decimal and there is at least one character in the string.

#  def isdigit(self, /):

Return True if the string is a digit string, False otherwise.

A string is a digit string if all characters in the string are digits and there is at least one character in the string.

#  def isidentifier(self, /):

Return True if the string is a valid Python identifier, False otherwise.

Call keyword.iskeyword(s) to test whether string s is a reserved identifier, such as "def" or "class".

#  def islower(self, /):

Return True if the string is a lowercase string, False otherwise.

A string is lowercase if all cased characters in the string are lowercase and there is at least one cased character in the string.

#  def isnumeric(self, /):

Return True if the string is a numeric string, False otherwise.

A string is numeric if all characters in the string are numeric and there is at least one character in the string.

#  def isprintable(self, /):

Return True if the string is printable, False otherwise.

A string is printable if all of its characters are considered printable in repr() or if it is empty.

#  def isspace(self, /):

Return True if the string is a whitespace string, False otherwise.

A string is whitespace if all characters in the string are whitespace and there is at least one character in the string.

#  def istitle(self, /):

Return True if the string is a title-cased string, False otherwise.

In a title-cased string, upper- and title-case characters may only follow uncased characters and lowercase characters only cased ones.

#  def isupper(self, /):

Return True if the string is an uppercase string, False otherwise.

A string is uppercase if all cased characters in the string are uppercase and there is at least one cased character in the string.

#  def join(self, iterable, /):

Concatenate any number of strings.

The string whose method is called is inserted in between each given string. The result is returned as a new string.

Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'

#  def ljust(self, width, fillchar=' ', /):

Return a left-justified string of length width.

Padding is done using the specified fill character (default is a space).

#  def lower(self, /):

Return a copy of the string converted to lowercase.

#  def lstrip(self, chars=None, /):

Return a copy of the string with leading whitespace removed.

If chars is given and not None, remove characters in chars instead.

#  def maketrans(unknown):

Return a translation table usable for str.translate().

If there is only one argument, it must be a dictionary mapping Unicode ordinals (integers) or characters to Unicode ordinals, strings or None. Character keys will be then converted to ordinals. If there are two arguments, they must be strings of equal length, and in the resulting dictionary, each character in x will be mapped to the character at the same position in y. If there is a third argument, it must be a string, whose characters will be mapped to None in the result.

#  def partition(self, sep, /):

Partition the string into three parts using the given separator.

This will search for the separator in the string. If the separator is found, returns a 3-tuple containing the part before the separator, the separator itself, and the part after it.

If the separator is not found, returns a 3-tuple containing the original string and two empty strings.

#  def removeprefix(self, prefix, /):

Return a str with the given prefix string removed if present.

If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string.

#  def removesuffix(self, suffix, /):

Return a str with the given suffix string removed if present.

If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string.

#  def replace(self, old, new, count=-1, /):

Return a copy with all occurrences of substring old replaced by new.

count Maximum number of occurrences to replace. -1 (the default value) means replace all occurrences.

If the optional argument count is given, only the first count occurrences are replaced.

#  def rfind(unknown):

S.rfind(sub[, start[, end]]) -> int

Return the highest index in S where substring sub is found, such that sub is contained within S[start:end]. Optional arguments start and end are interpreted as in slice notation.

Return -1 on failure.

#  def rindex(unknown):

S.rindex(sub[, start[, end]]) -> int

Return the highest index in S where substring sub is found, such that sub is contained within S[start:end]. Optional arguments start and end are interpreted as in slice notation.

Raises ValueError when the substring is not found.

#  def rjust(self, width, fillchar=' ', /):

Return a right-justified string of length width.

Padding is done using the specified fill character (default is a space).

#  def rpartition(self, sep, /):

Partition the string into three parts using the given separator.

This will search for the separator in the string, starting at the end. If the separator is found, returns a 3-tuple containing the part before the separator, the separator itself, and the part after it.

If the separator is not found, returns a 3-tuple containing two empty strings and the original string.

#  def rsplit(self, /, sep=None, maxsplit=-1):

Return a list of the words in the string, using sep as the delimiter string.

sep The delimiter according which to split the string. None (the default value) means split according to any whitespace, and discard empty strings from the result. maxsplit Maximum number of splits to do. -1 (the default value) means no limit.

Splits are done starting at the end of the string and working to the front.

#  def rstrip(self, chars=None, /):

Return a copy of the string with trailing whitespace removed.

If chars is given and not None, remove characters in chars instead.

#  def split(self, /, sep=None, maxsplit=-1):

Return a list of the words in the string, using sep as the delimiter string.

sep The delimiter according which to split the string. None (the default value) means split according to any whitespace, and discard empty strings from the result. maxsplit Maximum number of splits to do. -1 (the default value) means no limit.

#  def splitlines(self, /, keepends=False):

Return a list of the lines in the string, breaking at line boundaries.

Line breaks are not included in the resulting list unless keepends is given and true.

#  def startswith(unknown):

S.startswith(prefix[, start[, end]]) -> bool

Return True if S starts with the specified prefix, False otherwise. With optional start, test S beginning at that position. With optional end, stop comparing S at that position. prefix can also be a tuple of strings to try.

#  def strip(self, chars=None, /):

Return a copy of the string with leading and trailing whitespace removed.

If chars is given and not None, remove characters in chars instead.

#  def swapcase(self, /):

Convert uppercase characters to lowercase and lowercase characters to uppercase.

#  def title(self, /):

Return a version of the string where each word is titlecased.

More specifically, words start with uppercased characters and all remaining cased characters have lower case.

#  def translate(self, table, /):

Replace each character in the string using the given translation table.

table Translation table, which must be a mapping of Unicode ordinals to Unicode ordinals, strings, or None.

The table must implement lookup/indexing via __getitem__, for instance a dictionary or list. If this operation raises LookupError, the character is left untouched. Characters mapped to None are deleted.

#  def upper(self, /):

Return a copy of the string converted to uppercase.

#  def zfill(self, width, /):

Pad a numeric string with zeros on the left, to fill a field of the given width.

The string is never truncated.