Skip to content

Embed

Embed

Represents a Discord embed.

For your convenience, this class implicitly casts parameters that expect a string to str.

Attributes:

Name Type Description
title str

The title of the embed. Can be up to 256 characters.

type str

The type of embed. Usually "rich".

description str

The description of the embed. Can be up to 4096 characters.

url str

The URL of the embed.

timestamp Optional[datetime]

The timestamp of the embed content, an aware datetime. If a naive datetime is passed, it's converted to an aware datetime with the local timezone.

color Color

The color code of the embed.

Source code in dismake/models/embed/embed.py
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
class Embed:
    """Represents a Discord embed.

    For your convenience, this class implicitly casts parameters that expect a string to str.

    Attributes
    -----------
    title: str
        The title of the embed. Can be up to 256 characters.
    type: str
        The type of embed. Usually "rich".
    description: str
        The description of the embed. Can be up to 4096 characters.
    url: str
        The URL of the embed.
    timestamp: Optional[datetime]
        The timestamp of the embed content, an aware datetime.
        If a naive datetime is passed, it's converted to an aware datetime with the local timezone.
    color: Color
        The color code of the embed.
    """

    __slots__: Tuple[str, ...] = (
        "title",
        "description",
        "type",
        "url",
        "timestamp",
        "color",
        "_author",
        "_footer",
        "_fields",
        "_image",
        "_thumbnail",
        "_video",
        "_provider",
    )

    def __init__(
        self,
        *,
        title: Any = None,
        description: Any = None,
        type: EmbedType = "rich",
        url: Any = None,
        timestamp: Optional[datetime] = None,
        color: Optional[Color] = None,
    ) -> None:
        self.title = title
        self.description = description
        self.type = type
        self.url = url
        self.color = color
        self.timestamp: Optional[datetime]
        if isinstance(timestamp, datetime):
            if timestamp.tzinfo is None:
                self.timestamp = timestamp.astimezone()
        elif timestamp is None:
            self.timestamp = None
        else:
            raise TypeError(
                f"Expected datetime.datetime or None received {timestamp.__class__.__name__} instead"
            )

    @classmethod
    def from_dict(cls, data: EmbedData) -> Self:
        """Converts a dictionary into an Embed object, provided the data is in the
        format expected by Discord.

        Parameters
        -----------
        data: EmbedData
            The dictionary containing the data to convert into an Embed.

        Returns
        --------
        Embed
            An Embed object created from the provided dictionary.
        """
        embed = cls.__new__(cls)

        (embed.title, embed.description, embed.type, embed.url) = (
            data.get("title"),
            data.get("description"),
            data["type"],
            data.get("url"),
        )

        try:
            embed.timestamp = parse_time(data["timestamp"])
        except KeyError:
            pass

        try:
            embed.color = Color(data["color"])
        except KeyError:
            pass

        if (author_data := data.get("author")) is not None:
            setattr(embed, "_author", EmbedAuthor.from_dict(author_data))

        if (footer_data := data.get("footer")) is not None:
            setattr(embed, "_footer", EmbedFooter.from_dict(footer_data))

        if (image_data := data.get("image")) is not None:
            setattr(embed, "_image", EmbedAttachment.from_dict(image_data))

        if (thumbnail_data := data.get("thumbnail")) is not None:
            setattr(embed, "_thumbnail", EmbedAttachment.from_dict(thumbnail_data))

        if (video_data := data.get("video")) is not None:
            setattr(embed, "_video", EmbedAttachment.from_dict(video_data))

        if (provider_data := data.get("provider")) is not None:
            setattr(embed, "_provider", EmbedProvider.from_dict(provider_data))
        if (fields_data := data.get("fields")) is not None:
            temp_fields: List[EmbedField] = list()
            for field_data in fields_data:
                temp_fields.append(EmbedField.from_dict(field_data))

            embed._fields = temp_fields
        return embed

    def to_dict(self) -> EmbedData:
        """Converts this embed object into a dict."""

        # Create a base dictionary with the embed type
        base: EmbedData = {"type": self.type}

        # Loop through the slots to extract embed proxies
        for slot in self.__slots__:
            # Check if the slot represents an embed proxy (starts with '_')
            if slot.startswith("_"):
                # Get the value of the attribute
                attr_value = getattr(self, slot, None)
                # Check if the attribute is not None
                if attr_value is not None:
                    if slot == "_fields":
                        # Handle the "_fields" attribute differently by converting each field to a dictionary
                        temp_fields: List[EmbedFieldData] = list()
                        for field in attr_value:
                            temp_fields.append(field.to_dict())
                        base["fields"] = temp_fields
                    else:
                        # Remove the leading '_' from the slot name and set it as a key in the base dictionary
                        # Use the "to_dict()" method of the attribute to obtain a valid embed proxy dictionary
                        base[slot[1:]] = attr_value.to_dict()  # type: ignore  # Safe to ignore: Dynamically generated keys from __slots__

        # Check and add optional attributes if they are not None
        if self.title is not None:
            base["title"] = self.title

        if self.description is not None:
            base["description"] = self.description

        if self.color is not None:
            base["color"] = self.color.value

        if self.timestamp is not None:
            if self.timestamp.tzinfo:
                base["timestamp"] = self.timestamp.astimezone(
                    tz=timezone.utc
                ).isoformat()
            else:
                base["timestamp"] = self.timestamp.replace(
                    tzinfo=timezone.utc
                ).isoformat()

        if self.url is not None:
            base["url"] = self.url

        return base

    def __str__(self) -> str:
        """Returns a string representation of the Embed object."""
        return f"Embed(title='{self.title}', color='{self.color}', fields='{10}')"

    def copy(self) -> Self:
        """Returns a shallow copy of the embed."""
        return self.from_dict(self.to_dict())

    def __len__(self) -> int:
        attrs = (
            len(attr)
            for attr in (
                self.title,
                self.description,
                self.author.name,
                self.footer.text,
            )
            if attr is not None
        )
        fields = (
            (len(field.name) + len(field.value))
            for field in self.fields
            if field.name and field.value
        )
        return sum(attrs) + sum(fields)

    @property
    def author(self) -> EmbedAuthor:
        """Returns an ``EmbedAuthor`` representing the author of the embed.

        If the attribute has no value, an empty ``EmbedAuthor`` will be returned.
        """
        return getattr(self, "_author", EmbedAuthor())

    def set_author(
        self,
        name: Optional[str] = None,
        *,
        url: Optional[str] = None,
        icon_url: Optional[str] = None,
    ) -> Self:
        """Sets the author for the embed content.

        This method returns the class instance to allow for fluent-style chaining.

        Parameters
        -----------
        name: Optional[str]
            The name of the author. Can be up to 256 characters.
        url: Optional[str]
            The URL for the author.
        icon_url: Optional[str]
            The URL of the author's icon. Only HTTP(S) URLs are supported.
            Inline attachment URLs are also supported.

        Note
        ----
        If all parameters are set to ``None``, the author information in the embed
        will be cleared.
        """
        if name is None:
            self._author = None
        else:
            self._author = EmbedAuthor(name=name, url=url, icon_url=icon_url)
        return self

    @property
    def footer(self) -> EmbedFooter:
        """Returns an ``EmbedFooter`` denoting the footer contents.

        If the attribute has no value, an empty ``EmbedFooter`` will be returned.
        """
        return getattr(self, "_footer", EmbedFooter())

    def set_footer(
        self,
        text: Optional[str] = None,
        *,
        icon_url: Optional[str] = None,
    ) -> Self:
        """Sets the footer for the embed content.

        This method returns the class instance to allow for fluent-style chaining.

        Parameters
        -----------
        text: str
            The footer text. Can only be up to 2048 characters.
        icon_url: str
            The URL of the footer icon. Only HTTP(S) is supported.
            Inline attachment URLs are also supported.

        Note
        ----
        If all parameters are set to ``None``, the footer information in the embed
        will be cleared.
        """
        if text is None:
            self._footer = None

        else:
            self._footer = EmbedFooter(text=text, icon_url=icon_url)
        return self

    @property
    def fields(self) -> List[EmbedField]:
        """List[``EmbedField``]: Returns a `list` of ``EmbedProxy`` denoting the field contents.

        If the attribute has no value, an empty list will be returned.
        """
        return getattr(self, "_fields", [])

    def add_field(self, name: str, value: str, inline: Optional[bool] = None) -> Self:
        """Adds a field to the embed object.

        This function returns the class instance to allow for fluent-style
        chaining. Can only be up to 25 fields.

        Parameters
        -----------
        name: str
            The name of the field. Can only be up to 256 characters.
        value: str
            The value of the field. Can only be up to 1024 characters.
        inline: Optional[bool]
            Whether the field should be displayed inline.
        """
        if not getattr(self, "_fields", None):
            self._fields: List[EmbedField] = []

        self.fields.append(EmbedField(name=name, value=value, inline=inline))
        return self

    @property
    def image(self) -> EmbedAttachment:
        """Returns an ``EmbedAttachment`` representing the image of the embed.

        If the attribute has no value, an empty ``EmbedAttachment`` will be returned.
        """
        return getattr(self, "_image", EmbedAttachment())

    def set_image(
        self,
        url: Optional[str] = None,
    ) -> Self:
        """Sets the image for the embed content.

        This method returns the class instance to allow for fluent-style chaining.

        Parameters
        -----------
        url: Optional[str]
            The URL of the image.

        Note
        ----
        If all parameters are set to ``None``, the image information in the embed
        will be cleared.
        """
        if url is None:
            self._image = None

        self._image = EmbedAttachment(url=url)
        return self

    @property
    def thumbnail(self) -> EmbedAttachment:
        """Returns an ``EmbedAttachment`` representing the thumbnail image of the embed.

        If the attribute has no value, an empty ``EmbedAttachment`` will be returned.
        """
        return getattr(self, "_thumbnail", EmbedAttachment())

    def set_thumbnail(self, url: Optional[str] = None) -> Self:
        """Sets the thumbnail image for the embed content.

        This method returns the class instance to allow for fluent-style chaining.

        Parameters
        -----------
        url: Optional[str]
            The URL of the thumbnail image.

        Note
        ----
        If all parameters are set to ``None``, the thumbnail image information in the embed
        will be cleared.
        """
        if url is None:
            self._thumbnail = None

        self._thumbnail = EmbedAttachment(url=url)
        return self

    @property
    def video(self) -> EmbedAttachment:
        """Returns an ``EmbedVideo`` representing the video attachment of the embed.

        If the attribute has no value, an empty ``EmbedVideo`` will be returned.
        """
        return getattr(self, "_video", EmbedAttachment())

    @property
    def provider(self) -> EmbedProvider:
        """Returns an ``EmbedProvider`` representing the provider of the embed.

        If the attribute has no value, an empty ``EmbedProvider`` will be returned.
        """
        return getattr(self, "_provider", EmbedProvider())

author property

author: EmbedAuthor

Returns an EmbedAuthor representing the author of the embed.

If the attribute has no value, an empty EmbedAuthor will be returned.

fields property

fields: List[EmbedField]

List[EmbedField]: Returns a list of EmbedProxy denoting the field contents.

If the attribute has no value, an empty list will be returned.

footer property

footer: EmbedFooter

Returns an EmbedFooter denoting the footer contents.

If the attribute has no value, an empty EmbedFooter will be returned.

image property

image: EmbedAttachment

Returns an EmbedAttachment representing the image of the embed.

If the attribute has no value, an empty EmbedAttachment will be returned.

provider property

provider: EmbedProvider

Returns an EmbedProvider representing the provider of the embed.

If the attribute has no value, an empty EmbedProvider will be returned.

thumbnail property

thumbnail: EmbedAttachment

Returns an EmbedAttachment representing the thumbnail image of the embed.

If the attribute has no value, an empty EmbedAttachment will be returned.

video property

video: EmbedAttachment

Returns an EmbedVideo representing the video attachment of the embed.

If the attribute has no value, an empty EmbedVideo will be returned.

__str__

__str__() -> str

Returns a string representation of the Embed object.

Source code in dismake/models/embed/embed.py
199
200
201
def __str__(self) -> str:
    """Returns a string representation of the Embed object."""
    return f"Embed(title='{self.title}', color='{self.color}', fields='{10}')"

add_field

add_field(
    name: str, value: str, inline: Optional[bool] = None
) -> Self

Adds a field to the embed object.

This function returns the class instance to allow for fluent-style chaining. Can only be up to 25 fields.

Parameters:

Name Type Description Default
name str

The name of the field. Can only be up to 256 characters.

required
value str

The value of the field. Can only be up to 1024 characters.

required
inline Optional[bool]

Whether the field should be displayed inline.

None
Source code in dismake/models/embed/embed.py
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
def add_field(self, name: str, value: str, inline: Optional[bool] = None) -> Self:
    """Adds a field to the embed object.

    This function returns the class instance to allow for fluent-style
    chaining. Can only be up to 25 fields.

    Parameters
    -----------
    name: str
        The name of the field. Can only be up to 256 characters.
    value: str
        The value of the field. Can only be up to 1024 characters.
    inline: Optional[bool]
        Whether the field should be displayed inline.
    """
    if not getattr(self, "_fields", None):
        self._fields: List[EmbedField] = []

    self.fields.append(EmbedField(name=name, value=value, inline=inline))
    return self

copy

copy() -> Self

Returns a shallow copy of the embed.

Source code in dismake/models/embed/embed.py
203
204
205
def copy(self) -> Self:
    """Returns a shallow copy of the embed."""
    return self.from_dict(self.to_dict())

from_dict classmethod

from_dict(data: EmbedData) -> Self

Converts a dictionary into an Embed object, provided the data is in the format expected by Discord.

Parameters:

Name Type Description Default
data EmbedData

The dictionary containing the data to convert into an Embed.

required

Returns:

Type Description
Embed

An Embed object created from the provided dictionary.

Source code in dismake/models/embed/embed.py
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
@classmethod
def from_dict(cls, data: EmbedData) -> Self:
    """Converts a dictionary into an Embed object, provided the data is in the
    format expected by Discord.

    Parameters
    -----------
    data: EmbedData
        The dictionary containing the data to convert into an Embed.

    Returns
    --------
    Embed
        An Embed object created from the provided dictionary.
    """
    embed = cls.__new__(cls)

    (embed.title, embed.description, embed.type, embed.url) = (
        data.get("title"),
        data.get("description"),
        data["type"],
        data.get("url"),
    )

    try:
        embed.timestamp = parse_time(data["timestamp"])
    except KeyError:
        pass

    try:
        embed.color = Color(data["color"])
    except KeyError:
        pass

    if (author_data := data.get("author")) is not None:
        setattr(embed, "_author", EmbedAuthor.from_dict(author_data))

    if (footer_data := data.get("footer")) is not None:
        setattr(embed, "_footer", EmbedFooter.from_dict(footer_data))

    if (image_data := data.get("image")) is not None:
        setattr(embed, "_image", EmbedAttachment.from_dict(image_data))

    if (thumbnail_data := data.get("thumbnail")) is not None:
        setattr(embed, "_thumbnail", EmbedAttachment.from_dict(thumbnail_data))

    if (video_data := data.get("video")) is not None:
        setattr(embed, "_video", EmbedAttachment.from_dict(video_data))

    if (provider_data := data.get("provider")) is not None:
        setattr(embed, "_provider", EmbedProvider.from_dict(provider_data))
    if (fields_data := data.get("fields")) is not None:
        temp_fields: List[EmbedField] = list()
        for field_data in fields_data:
            temp_fields.append(EmbedField.from_dict(field_data))

        embed._fields = temp_fields
    return embed

set_author

set_author(
    name: Optional[str] = None,
    *,
    url: Optional[str] = None,
    icon_url: Optional[str] = None
) -> Self

Sets the author for the embed content.

This method returns the class instance to allow for fluent-style chaining.

Parameters:

Name Type Description Default
name Optional[str]

The name of the author. Can be up to 256 characters.

None
url Optional[str]

The URL for the author.

None
icon_url Optional[str]

The URL of the author's icon. Only HTTP(S) URLs are supported. Inline attachment URLs are also supported.

None
Note

If all parameters are set to None, the author information in the embed will be cleared.

Source code in dismake/models/embed/embed.py
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
def set_author(
    self,
    name: Optional[str] = None,
    *,
    url: Optional[str] = None,
    icon_url: Optional[str] = None,
) -> Self:
    """Sets the author for the embed content.

    This method returns the class instance to allow for fluent-style chaining.

    Parameters
    -----------
    name: Optional[str]
        The name of the author. Can be up to 256 characters.
    url: Optional[str]
        The URL for the author.
    icon_url: Optional[str]
        The URL of the author's icon. Only HTTP(S) URLs are supported.
        Inline attachment URLs are also supported.

    Note
    ----
    If all parameters are set to ``None``, the author information in the embed
    will be cleared.
    """
    if name is None:
        self._author = None
    else:
        self._author = EmbedAuthor(name=name, url=url, icon_url=icon_url)
    return self
set_footer(
    text: Optional[str] = None,
    *,
    icon_url: Optional[str] = None
) -> Self

Sets the footer for the embed content.

This method returns the class instance to allow for fluent-style chaining.

Parameters:

Name Type Description Default
text Optional[str]

The footer text. Can only be up to 2048 characters.

None
icon_url Optional[str]

The URL of the footer icon. Only HTTP(S) is supported. Inline attachment URLs are also supported.

None

If all parameters are set to None, the footer information in the embed will be cleared.

Source code in dismake/models/embed/embed.py
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
def set_footer(
    self,
    text: Optional[str] = None,
    *,
    icon_url: Optional[str] = None,
) -> Self:
    """Sets the footer for the embed content.

    This method returns the class instance to allow for fluent-style chaining.

    Parameters
    -----------
    text: str
        The footer text. Can only be up to 2048 characters.
    icon_url: str
        The URL of the footer icon. Only HTTP(S) is supported.
        Inline attachment URLs are also supported.

    Note
    ----
    If all parameters are set to ``None``, the footer information in the embed
    will be cleared.
    """
    if text is None:
        self._footer = None

    else:
        self._footer = EmbedFooter(text=text, icon_url=icon_url)
    return self

set_image

set_image(url: Optional[str] = None) -> Self

Sets the image for the embed content.

This method returns the class instance to allow for fluent-style chaining.

Parameters:

Name Type Description Default
url Optional[str]

The URL of the image.

None
Note

If all parameters are set to None, the image information in the embed will be cleared.

Source code in dismake/models/embed/embed.py
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
def set_image(
    self,
    url: Optional[str] = None,
) -> Self:
    """Sets the image for the embed content.

    This method returns the class instance to allow for fluent-style chaining.

    Parameters
    -----------
    url: Optional[str]
        The URL of the image.

    Note
    ----
    If all parameters are set to ``None``, the image information in the embed
    will be cleared.
    """
    if url is None:
        self._image = None

    self._image = EmbedAttachment(url=url)
    return self

set_thumbnail

set_thumbnail(url: Optional[str] = None) -> Self

Sets the thumbnail image for the embed content.

This method returns the class instance to allow for fluent-style chaining.

Parameters:

Name Type Description Default
url Optional[str]

The URL of the thumbnail image.

None
Note

If all parameters are set to None, the thumbnail image information in the embed will be cleared.

Source code in dismake/models/embed/embed.py
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
def set_thumbnail(self, url: Optional[str] = None) -> Self:
    """Sets the thumbnail image for the embed content.

    This method returns the class instance to allow for fluent-style chaining.

    Parameters
    -----------
    url: Optional[str]
        The URL of the thumbnail image.

    Note
    ----
    If all parameters are set to ``None``, the thumbnail image information in the embed
    will be cleared.
    """
    if url is None:
        self._thumbnail = None

    self._thumbnail = EmbedAttachment(url=url)
    return self

to_dict

to_dict() -> EmbedData

Converts this embed object into a dict.

Source code in dismake/models/embed/embed.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
def to_dict(self) -> EmbedData:
    """Converts this embed object into a dict."""

    # Create a base dictionary with the embed type
    base: EmbedData = {"type": self.type}

    # Loop through the slots to extract embed proxies
    for slot in self.__slots__:
        # Check if the slot represents an embed proxy (starts with '_')
        if slot.startswith("_"):
            # Get the value of the attribute
            attr_value = getattr(self, slot, None)
            # Check if the attribute is not None
            if attr_value is not None:
                if slot == "_fields":
                    # Handle the "_fields" attribute differently by converting each field to a dictionary
                    temp_fields: List[EmbedFieldData] = list()
                    for field in attr_value:
                        temp_fields.append(field.to_dict())
                    base["fields"] = temp_fields
                else:
                    # Remove the leading '_' from the slot name and set it as a key in the base dictionary
                    # Use the "to_dict()" method of the attribute to obtain a valid embed proxy dictionary
                    base[slot[1:]] = attr_value.to_dict()  # type: ignore  # Safe to ignore: Dynamically generated keys from __slots__

    # Check and add optional attributes if they are not None
    if self.title is not None:
        base["title"] = self.title

    if self.description is not None:
        base["description"] = self.description

    if self.color is not None:
        base["color"] = self.color.value

    if self.timestamp is not None:
        if self.timestamp.tzinfo:
            base["timestamp"] = self.timestamp.astimezone(
                tz=timezone.utc
            ).isoformat()
        else:
            base["timestamp"] = self.timestamp.replace(
                tzinfo=timezone.utc
            ).isoformat()

    if self.url is not None:
        base["url"] = self.url

    return base