Skip to content

Asset

attrs class Asset

Represents a discord asset.

Attributes:

Name Type Description
BASE str

The cdn address for assets

url str

The URL of this asset

hash Optional[str]

The hash of this asset

Attr attributes:

Name Type Description
Source code in naff/models/discord/asset.py
@define(kw_only=False)
class Asset:
    """
    Represents a discord asset.

    Attributes:
        BASE str: The `cdn` address for assets
        url str: The URL of this asset
        hash Optional[str]: The hash of this asset

    """

    BASE = "https://cdn.discordapp.com"

    _client: "Client" = field(metadata=no_export_meta)
    _url: str = field(repr=True)
    hash: Optional[str] = field(repr=True, default=None)

    @classmethod
    def from_path_hash(cls, client: "Client", path: str, asset_hash: str) -> "Asset":
        """
        Create an asset from a path and asset's hash.

        Args:
            client: The NAFF bot instance
            path: The CDN Endpoints for the type of asset.
            asset_hash: The hash representation of the target asset.

        Returns:
            A new Asset object

        """
        url = f"{cls.BASE}/{path.format(asset_hash)}"
        return cls(client=client, url=url, hash=asset_hash)

    @property
    def url(self) -> str:
        """The URL of this asset."""
        ext = ".gif" if self.animated else ".png"
        return f"{self._url}{ext}?size=4096"

    def as_url(self, *, extension: str | None = None, size: int = 4096) -> str:
        """
        Get the url of this asset.

        args:
            extension: The extension to override the assets default with
            size: The size of asset to return

        returns:
            A url for this asset with the given parameters
        """
        if not extension:
            extension = ".gif" if self.animated else ".png"
        elif not extension.startswith("."):
            extension = f".{extension}"

        return f"{self._url}{extension}?size={size}"

    @property
    def animated(self) -> bool:
        """True if this asset is animated."""
        return bool(self.hash) and self.hash.startswith("a_")

    async def fetch(self, extension: Optional[str] = None, size: Optional[int] = None) -> bytes:
        """
        Fetch the asset from the Discord CDN.

        Args:
            extension: File extension based on the target image format
            size: The image size, can be any power of two between 16 and 4096.

        Returns:
            Raw byte array of the file

        Raises:
            ValueError: Incorrect file size if not power of 2 between 16 and 4096

        """
        if not extension:
            extension = ".gif" if self.animated else ".png"

        url = self._url + extension

        if size:
            if not ((size != 0) and (size & (size - 1) == 0)):  # if not power of 2
                raise ValueError("Size should be a power of 2")
            if not 16 <= size <= 4096:
                raise ValueError("Size should be between 16 and 4096")

            url = f"{url}?size={size}"

        return await self._client.http.request_cdn(url, self)

    async def save(
        self, fd: Union[str, bytes, "PathLike", int], extension: Optional[str] = None, size: Optional[int] = None
    ) -> int:
        """
        Save the asset to a local file.

        Args:
            fd: Destination path to save the file to.
            extension: File extension based on the target image format.
            size: The image size, can be any power of two between 16 and 4096.

        Returns:
            Status code result of file write

        """
        content = await self.fetch(extension=extension, size=size)
        with open(fd, "wb") as f:
            return f.write(content)

classmethod method from_path_hash(client, path, asset_hash)

Create an asset from a path and asset's hash.

Parameters:

Name Type Description Default
client Client

The NAFF bot instance

required
path str

The CDN Endpoints for the type of asset.

required
asset_hash str

The hash representation of the target asset.

required

Returns:

Type Description
Asset

A new Asset object

Source code in naff/models/discord/asset.py
@classmethod
def from_path_hash(cls, client: "Client", path: str, asset_hash: str) -> "Asset":
    """
    Create an asset from a path and asset's hash.

    Args:
        client: The NAFF bot instance
        path: The CDN Endpoints for the type of asset.
        asset_hash: The hash representation of the target asset.

    Returns:
        A new Asset object

    """
    url = f"{cls.BASE}/{path.format(asset_hash)}"
    return cls(client=client, url=url, hash=asset_hash)

property readonly url: str

The URL of this asset.

method as_url(self, *, extension, size)

Get the url of this asset.

Parameters:

Name Type Description Default
extension str | None

The extension to override the assets default with

None
size int

The size of asset to return

4096

Returns:

Type Description
str

A url for this asset with the given parameters

Source code in naff/models/discord/asset.py
def as_url(self, *, extension: str | None = None, size: int = 4096) -> str:
    """
    Get the url of this asset.

    args:
        extension: The extension to override the assets default with
        size: The size of asset to return

    returns:
        A url for this asset with the given parameters
    """
    if not extension:
        extension = ".gif" if self.animated else ".png"
    elif not extension.startswith("."):
        extension = f".{extension}"

    return f"{self._url}{extension}?size={size}"

property readonly animated: bool

True if this asset is animated.

async method fetch(self, extension, size)

Fetch the asset from the Discord CDN.

Parameters:

Name Type Description Default
extension Optional[str]

File extension based on the target image format

None
size Optional[int]

The image size, can be any power of two between 16 and 4096.

None

Returns:

Type Description
bytes

Raw byte array of the file

Exceptions:

Type Description
ValueError

Incorrect file size if not power of 2 between 16 and 4096

Source code in naff/models/discord/asset.py
async def fetch(self, extension: Optional[str] = None, size: Optional[int] = None) -> bytes:
    """
    Fetch the asset from the Discord CDN.

    Args:
        extension: File extension based on the target image format
        size: The image size, can be any power of two between 16 and 4096.

    Returns:
        Raw byte array of the file

    Raises:
        ValueError: Incorrect file size if not power of 2 between 16 and 4096

    """
    if not extension:
        extension = ".gif" if self.animated else ".png"

    url = self._url + extension

    if size:
        if not ((size != 0) and (size & (size - 1) == 0)):  # if not power of 2
            raise ValueError("Size should be a power of 2")
        if not 16 <= size <= 4096:
            raise ValueError("Size should be between 16 and 4096")

        url = f"{url}?size={size}"

    return await self._client.http.request_cdn(url, self)

async method save(self, fd, extension, size)

Save the asset to a local file.

Parameters:

Name Type Description Default
fd Union[str, bytes, PathLike, int]

Destination path to save the file to.

required
extension Optional[str]

File extension based on the target image format.

None
size Optional[int]

The image size, can be any power of two between 16 and 4096.

None

Returns:

Type Description
int

Status code result of file write

Source code in naff/models/discord/asset.py
async def save(
    self, fd: Union[str, bytes, "PathLike", int], extension: Optional[str] = None, size: Optional[int] = None
) -> int:
    """
    Save the asset to a local file.

    Args:
        fd: Destination path to save the file to.
        extension: File extension based on the target image format.
        size: The image size, can be any power of two between 16 and 4096.

    Returns:
        Status code result of file write

    """
    content = await self.fetch(extension=extension, size=size)
    with open(fd, "wb") as f:
        return f.write(content)