Back to top

hikari.stickers

Application and entities that are used to describe stickers 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 stickers on Discord."""

from __future__ import annotations

__all__: typing.Sequence[str] = (
    "StickerType",
    "StickerFormatType",
    "PartialSticker",
    "GuildSticker",
    "StandardSticker",
    "StickerPack",
)

import typing

import attr

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:
    from hikari import files
    from hikari import users


@typing.final
class StickerType(int, enums.Enum):
    """The sticker type."""

    STANDARD = 1
    """An official sticker in a pack, part of Nitro or in a removed purchasable pack."""

    GUILD = 2
    """A sticker uploaded to a guild."""


@typing.final
class StickerFormatType(int, enums.Enum):
    """The formats types of a sticker's asset."""

    PNG = 1
    """A PNG sticker."""

    APNG = 2
    """A animated PNG sticker."""

    LOTTIE = 3
    """A lottie sticker.

    More information can be found here: <https://airbnb.io/lottie/>
    """


@attr.define(hash=True, kw_only=True, weakref_slot=False)
class StickerPack(snowflakes.Unique):
    """Represents a sticker pack on Discord."""

    id: snowflakes.Snowflake = attr.field(hash=True, repr=True)
    """The ID of this entity."""

    name: str = attr.field(eq=False, hash=False, repr=False)
    """The name of the pack."""

    description: str = attr.field(eq=False, hash=False, repr=False)
    """The description of the pack."""

    cover_sticker_id: typing.Optional[snowflakes.Snowflake] = attr.field(eq=False, hash=False, repr=False)
    """The ID of a sticker in the pack which is shown as the pack's icon"""

    stickers: typing.Sequence[StandardSticker] = attr.field(eq=False, hash=False, repr=False)
    """The stickers that belong to this pack."""

    sku_id: snowflakes.Snowflake = attr.field(eq=False, hash=False, repr=False)
    """The ID of the packs SKU."""

    # This is not exactly how Discord documents it, but we need to keep consistency
    banner_hash: str = attr.field(eq=False, hash=False, repr=False)
    """The hash for the pack's banner."""

    @property
    def banner_url(self) -> files.URL:
        """Banner URL for the pack."""
        return self.make_banner_url()

    def make_banner_url(self, *, ext: str = "png", size: int = 4096) -> files.URL:
        """Generate the pack's banner image URL.

        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
        -------
        hikari.files.URL
            The URL of the banner.

        Raises
        ------
        ValueError
            If `size` is not a power of two or not between 16 and 4096.
        """
        return routes.CDN_STICKER_PACK_BANNER.compile_to_file(
            urls.CDN_URL, hash=self.banner_hash, file_format=ext, size=size
        )


@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class PartialSticker(snowflakes.Unique):
    """Represents the partial stickers found attached to messages on Discord."""

    id: snowflakes.Snowflake = attr.field(hash=True, repr=True)
    """The ID of this entity."""

    name: str = attr.field(eq=False, hash=False, repr=False)
    """The name of the sticker."""

    format_type: typing.Union[StickerFormatType, int] = attr.field(eq=False, hash=False, repr=True)
    """The format of this sticker's asset."""

    @property
    def image_url(self) -> files.URL:
        """URL for the image.

        The extension will be based on `format_type`. If `format_type` is `StickerFormatType.LOTTIE`,
        then the extension will be `.json`. Otherwise, it will be `.png`.
        """
        ext = "json" if self.format_type is StickerFormatType.LOTTIE else "png"

        return routes.CDN_STICKER.compile_to_file(urls.CDN_URL, sticker_id=self.id, file_format=ext)


@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class StandardSticker(PartialSticker):
    """Represents a standard Discord sticker that belongs to a pack."""

    type: StickerType = attr.field(eq=False, hash=False, repr=False, init=False, default=StickerType.STANDARD)
    """The sticker type."""

    description: typing.Optional[str] = attr.field(eq=False, hash=False, repr=False)
    """The description of this sticker."""

    pack_id: snowflakes.Snowflake = attr.field(eq=False, hash=False, repr=True)
    """ID of the package this sticker belongs to."""

    sort_value: int = attr.field(eq=False, hash=False, repr=False)
    """The sort value for the sticker in its pack."""

    tags: typing.Sequence[str] = attr.field(eq=False, hash=False, repr=True)
    """A sequence of this sticker's tags."""


@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class GuildSticker(PartialSticker):
    """Represents a Discord sticker that belongs to a guild."""

    type: StickerType = attr.field(eq=False, hash=False, repr=False, init=False, default=StickerType.GUILD)
    """The sticker type."""

    description: typing.Optional[str] = attr.field(eq=False, hash=False, repr=False)
    """The description of this sticker."""

    guild_id: snowflakes.Snowflake = attr.field(eq=False, hash=False)
    """The guild this sticker belongs to"""

    is_available: bool = attr.field(eq=False, hash=False)
    """Whether the sticker can be used."""

    tag: str = attr.field(eq=False, hash=False)
    """This sticker's tag."""

    user: typing.Optional[users.User] = attr.field(eq=False, hash=False, repr=False)
    """The user that uploaded this sticker.

    This will only available if you have the `MANAGE_EMOJIS_AND_STICKERS` permission.
    """
#  
@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class GuildSticker(PartialSticker):
View Source
@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class GuildSticker(PartialSticker):
    """Represents a Discord sticker that belongs to a guild."""

    type: StickerType = attr.field(eq=False, hash=False, repr=False, init=False, default=StickerType.GUILD)
    """The sticker type."""

    description: typing.Optional[str] = attr.field(eq=False, hash=False, repr=False)
    """The description of this sticker."""

    guild_id: snowflakes.Snowflake = attr.field(eq=False, hash=False)
    """The guild this sticker belongs to"""

    is_available: bool = attr.field(eq=False, hash=False)
    """Whether the sticker can be used."""

    tag: str = attr.field(eq=False, hash=False)
    """This sticker's tag."""

    user: typing.Optional[users.User] = attr.field(eq=False, hash=False, repr=False)
    """The user that uploaded this sticker.

    This will only available if you have the `MANAGE_EMOJIS_AND_STICKERS` permission.
    """

Represents a Discord sticker that belongs to a guild.

Variables and properties
#  created_at: datetime.datetime

When the object was created.

#  description: Optional[str]

The description of this sticker.

The format of this sticker's asset.

The guild this sticker belongs to

The ID of this entity.

URL for the image.

The extension will be based on format_type. If format_type is StickerFormatType.LOTTIE, then the extension will be .json. Otherwise, it will be .png.

#  is_available: bool

Whether the sticker can be used.

#  name: str

The name of the sticker.

#  tag: str

This sticker's tag.

The sticker type.

#  user: Optional[hikari.users.User]

The user that uploaded this sticker.

This will only available if you have the MANAGE_EMOJIS_AND_STICKERS permission.

Methods
#  def __init__(
   self,
   *,
   id: hikari.snowflakes.Snowflake,
   name: str,
   format_type: Union[hikari.stickers.StickerFormatType, int],
   description: Optional[str],
   guild_id: hikari.snowflakes.Snowflake,
   is_available: bool,
   tag: str,
   user: Optional[hikari.users.User]
):
View Source
def __init__(self, *, id, name, format_type, description, guild_id, is_available, tag, user):
    self.id = id
    self.name = name
    self.format_type = format_type
    self.type = attr_dict['type'].default
    self.description = description
    self.guild_id = guild_id
    self.is_available = is_available
    self.tag = tag
    self.user = user

Method generated by attrs for class GuildSticker.

#  
@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class PartialSticker(hikari.snowflakes.Unique):
View Source
@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class PartialSticker(snowflakes.Unique):
    """Represents the partial stickers found attached to messages on Discord."""

    id: snowflakes.Snowflake = attr.field(hash=True, repr=True)
    """The ID of this entity."""

    name: str = attr.field(eq=False, hash=False, repr=False)
    """The name of the sticker."""

    format_type: typing.Union[StickerFormatType, int] = attr.field(eq=False, hash=False, repr=True)
    """The format of this sticker's asset."""

    @property
    def image_url(self) -> files.URL:
        """URL for the image.

        The extension will be based on `format_type`. If `format_type` is `StickerFormatType.LOTTIE`,
        then the extension will be `.json`. Otherwise, it will be `.png`.
        """
        ext = "json" if self.format_type is StickerFormatType.LOTTIE else "png"

        return routes.CDN_STICKER.compile_to_file(urls.CDN_URL, sticker_id=self.id, file_format=ext)

Represents the partial stickers found attached to messages on Discord.

Variables and properties
#  created_at: datetime.datetime

When the object was created.

The format of this sticker's asset.

The ID of this entity.

URL for the image.

The extension will be based on format_type. If format_type is StickerFormatType.LOTTIE, then the extension will be .json. Otherwise, it will be .png.

#  name: str

The name of the sticker.

Methods
#  def __init__(
   self,
   *,
   id: hikari.snowflakes.Snowflake,
   name: str,
   format_type: Union[hikari.stickers.StickerFormatType, int]
):
View Source
def __init__(self, *, id, name, format_type):
    self.id = id
    self.name = name
    self.format_type = format_type

Method generated by attrs for class PartialSticker.

#  
@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class StandardSticker(PartialSticker):
View Source
@attr_extensions.with_copy
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class StandardSticker(PartialSticker):
    """Represents a standard Discord sticker that belongs to a pack."""

    type: StickerType = attr.field(eq=False, hash=False, repr=False, init=False, default=StickerType.STANDARD)
    """The sticker type."""

    description: typing.Optional[str] = attr.field(eq=False, hash=False, repr=False)
    """The description of this sticker."""

    pack_id: snowflakes.Snowflake = attr.field(eq=False, hash=False, repr=True)
    """ID of the package this sticker belongs to."""

    sort_value: int = attr.field(eq=False, hash=False, repr=False)
    """The sort value for the sticker in its pack."""

    tags: typing.Sequence[str] = attr.field(eq=False, hash=False, repr=True)
    """A sequence of this sticker's tags."""

Represents a standard Discord sticker that belongs to a pack.

Variables and properties
#  created_at: datetime.datetime

When the object was created.

#  description: Optional[str]

The description of this sticker.

The format of this sticker's asset.

The ID of this entity.

URL for the image.

The extension will be based on format_type. If format_type is StickerFormatType.LOTTIE, then the extension will be .json. Otherwise, it will be .png.

#  name: str

The name of the sticker.

ID of the package this sticker belongs to.

#  sort_value: int

The sort value for the sticker in its pack.

#  tags: Sequence[str]

A sequence of this sticker's tags.

The sticker type.

Methods
#  def __init__(
   self,
   *,
   id: hikari.snowflakes.Snowflake,
   name: str,
   format_type: Union[hikari.stickers.StickerFormatType, int],
   description: Optional[str],
   pack_id: hikari.snowflakes.Snowflake,
   sort_value: int,
   tags: Sequence[str]
):
View Source
def __init__(self, *, id, name, format_type, description, pack_id, sort_value, tags):
    self.id = id
    self.name = name
    self.format_type = format_type
    self.type = attr_dict['type'].default
    self.description = description
    self.pack_id = pack_id
    self.sort_value = sort_value
    self.tags = tags

Method generated by attrs for class StandardSticker.

#  
@typing.final
class StickerFormatType(builtins.int, hikari.internal.enums.Enum):
View Source
@typing.final
class StickerFormatType(int, enums.Enum):
    """The formats types of a sticker's asset."""

    PNG = 1
    """A PNG sticker."""

    APNG = 2
    """A animated PNG sticker."""

    LOTTIE = 3
    """A lottie sticker.

    More information can be found here: <https://airbnb.io/lottie/>
    """

The formats types of a sticker's asset.

Variables and properties
#  APNG

A animated PNG sticker.

#  LOTTIE

A lottie sticker.

More information can be found here: https://airbnb.io/lottie/

A PNG sticker.

#  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.define(hash=True, kw_only=True, weakref_slot=False)
class StickerPack(hikari.snowflakes.Unique):
View Source
@attr.define(hash=True, kw_only=True, weakref_slot=False)
class StickerPack(snowflakes.Unique):
    """Represents a sticker pack on Discord."""

    id: snowflakes.Snowflake = attr.field(hash=True, repr=True)
    """The ID of this entity."""

    name: str = attr.field(eq=False, hash=False, repr=False)
    """The name of the pack."""

    description: str = attr.field(eq=False, hash=False, repr=False)
    """The description of the pack."""

    cover_sticker_id: typing.Optional[snowflakes.Snowflake] = attr.field(eq=False, hash=False, repr=False)
    """The ID of a sticker in the pack which is shown as the pack's icon"""

    stickers: typing.Sequence[StandardSticker] = attr.field(eq=False, hash=False, repr=False)
    """The stickers that belong to this pack."""

    sku_id: snowflakes.Snowflake = attr.field(eq=False, hash=False, repr=False)
    """The ID of the packs SKU."""

    # This is not exactly how Discord documents it, but we need to keep consistency
    banner_hash: str = attr.field(eq=False, hash=False, repr=False)
    """The hash for the pack's banner."""

    @property
    def banner_url(self) -> files.URL:
        """Banner URL for the pack."""
        return self.make_banner_url()

    def make_banner_url(self, *, ext: str = "png", size: int = 4096) -> files.URL:
        """Generate the pack's banner image URL.

        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
        -------
        hikari.files.URL
            The URL of the banner.

        Raises
        ------
        ValueError
            If `size` is not a power of two or not between 16 and 4096.
        """
        return routes.CDN_STICKER_PACK_BANNER.compile_to_file(
            urls.CDN_URL, hash=self.banner_hash, file_format=ext, size=size
        )

Represents a sticker pack on Discord.

Variables and properties
#  banner_hash: str

The hash for the pack's banner.

Banner URL for the pack.

#  cover_sticker_id: Optional[hikari.snowflakes.Snowflake]

The ID of a sticker in the pack which is shown as the pack's icon

#  created_at: datetime.datetime

When the object was created.

#  description: str

The description of the pack.

The ID of this entity.

#  name: str

The name of the pack.

The ID of the packs SKU.

The stickers that belong to this pack.

Methods
#  def __init__(
   self,
   *,
   id: hikari.snowflakes.Snowflake,
   name: str,
   description: str,
   cover_sticker_id: Optional[hikari.snowflakes.Snowflake],
   stickers: Sequence[hikari.stickers.StandardSticker],
   sku_id: hikari.snowflakes.Snowflake,
   banner_hash: str
):
View Source
def __init__(self, *, id, name, description, cover_sticker_id, stickers, sku_id, banner_hash):
    self.id = id
    self.name = name
    self.description = description
    self.cover_sticker_id = cover_sticker_id
    self.stickers = stickers
    self.sku_id = sku_id
    self.banner_hash = banner_hash

Method generated by attrs for class StickerPack.

#  def make_banner_url(self, *, ext: str = 'png', size: int = 4096) -> hikari.files.URL:
View Source
    def make_banner_url(self, *, ext: str = "png", size: int = 4096) -> files.URL:
        """Generate the pack's banner image URL.

        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
        -------
        hikari.files.URL
            The URL of the banner.

        Raises
        ------
        ValueError
            If `size` is not a power of two or not between 16 and 4096.
        """
        return routes.CDN_STICKER_PACK_BANNER.compile_to_file(
            urls.CDN_URL, hash=self.banner_hash, file_format=ext, size=size
        )

Generate the pack's banner image URL.

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 size is not a power of two or not between 16 and 4096.
#  
@typing.final
class StickerType(builtins.int, hikari.internal.enums.Enum):
View Source
@typing.final
class StickerType(int, enums.Enum):
    """The sticker type."""

    STANDARD = 1
    """An official sticker in a pack, part of Nitro or in a removed purchasable pack."""

    GUILD = 2
    """A sticker uploaded to a guild."""

The sticker type.

Variables and properties
#  GUILD

A sticker uploaded to a guild.

#  STANDARD

An official sticker in a pack, part of Nitro or in a removed purchasable pack.

#  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.