Source code for aiogram.types.input_media
import io
import secrets
import typing
from . import base
from . import fields
from .input_file import InputFile
from .message_entity import MessageEntity
ATTACHMENT_PREFIX = 'attach://'
[docs]class InputMedia(base.TelegramObject):
"""
This object represents the content of a media message to be sent. It should be one of
- InputMediaAnimation
- InputMediaDocument
- InputMediaAudio
- InputMediaPhoto
- InputMediaVideo
That is only base class.
https://core.telegram.org/bots/api#inputmedia
"""
type: base.String = fields.Field(default='photo')
media: base.String = fields.Field(alias='media', on_change='_media_changed')
thumb: typing.Union[base.InputFile, base.String] = fields.Field(alias='thumb', on_change='_thumb_changed')
caption: base.String = fields.Field()
parse_mode: base.String = fields.Field()
caption_entities: typing.List[MessageEntity] = fields.ListField(base=MessageEntity)
def __init__(self, *args, **kwargs):
self._thumb_file = None
self._media_file = None
media = kwargs.pop('media', None)
if isinstance(media, (io.IOBase, InputFile)):
self.file = media
elif media is not None:
self.media = media
thumb = kwargs.pop('thumb', None)
if isinstance(thumb, (io.IOBase, InputFile)):
self.thumb_file = thumb
elif thumb is not None:
self.thumb = thumb
super(InputMedia, self).__init__(*args, **kwargs)
try:
if self.parse_mode is None and self.bot and self.bot.parse_mode:
self.parse_mode = self.bot.parse_mode
except RuntimeError:
pass
@property
def file(self):
return self._media_file
@file.setter
def file(self, file: io.IOBase):
self.media = 'attach://' + secrets.token_urlsafe(16)
self._media_file = file
@file.deleter
def file(self):
self.media = None
self._media_file = None
def _media_changed(self, value):
if value is None or isinstance(value, str) and not value.startswith('attach://'):
self._media_file = None
@property
def thumb_file(self):
return self._thumb_file
@thumb_file.setter
def thumb_file(self, file: io.IOBase):
self.thumb = 'attach://' + secrets.token_urlsafe(16)
self._thumb_file = file
@thumb_file.deleter
def thumb_file(self):
self.thumb = None
self._thumb_file = None
def _thumb_changed(self, value):
if value is None or isinstance(value, str) and not value.startswith('attach://'):
self._thumb_file = None
def get_files(self):
if self._media_file:
yield self.media[9:], self._media_file
if self._thumb_file:
yield self.thumb[9:], self._thumb_file
[docs]class InputMediaAnimation(InputMedia):
"""
Represents an animation file (GIF or H.264/MPEG-4 AVC video without sound) to be sent.
https://core.telegram.org/bots/api#inputmediaanimation
"""
width: base.Integer = fields.Field()
height: base.Integer = fields.Field()
duration: base.Integer = fields.Field()
has_spoiler: typing.Optional[base.Boolean] = fields.Field()
def __init__(
self,
media: base.InputFile,
thumb: typing.Union[base.InputFile, base.String] = None,
caption: base.String = None,
width: base.Integer = None,
height: base.Integer = None,
duration: base.Integer = None,
parse_mode: base.String = None,
caption_entities: typing.Optional[typing.List[MessageEntity]] = None,
has_spoiler: typing.Optional[base.Boolean] = None,
**kwargs,
):
super().__init__(
type='animation', media=media, thumb=thumb, caption=caption, width=width,
height=height, duration=duration, parse_mode=parse_mode,
caption_entities=caption_entities, has_spoiler=has_spoiler, conf=kwargs,
)
[docs]class InputMediaDocument(InputMedia):
"""
Represents a general file to be sent.
https://core.telegram.org/bots/api#inputmediadocument
"""
def __init__(
self,
media: base.InputFile,
thumb: typing.Union[base.InputFile, base.String, None] = None,
caption: base.String = None,
parse_mode: base.String = None,
caption_entities: typing.Optional[typing.List[MessageEntity]] = None,
disable_content_type_detection: typing.Optional[base.Boolean] = None,
**kwargs,
):
super().__init__(
type='document', media=media, thumb=thumb, caption=caption,
parse_mode=parse_mode, caption_entities=caption_entities,
disable_content_type_detection=disable_content_type_detection,
conf=kwargs,
)
[docs]class InputMediaAudio(InputMedia):
"""
Represents an audio file to be treated as music to be sent.
https://core.telegram.org/bots/api#inputmediaaudio
"""
duration: base.Integer = fields.Field()
performer: base.String = fields.Field()
title: base.String = fields.Field()
def __init__(
self,
media: base.InputFile,
thumb: typing.Union[base.InputFile, base.String] = None,
caption: base.String = None,
duration: base.Integer = None,
performer: base.String = None,
title: base.String = None,
parse_mode: base.String = None,
caption_entities: typing.Optional[typing.List[MessageEntity]] = None,
**kwargs,
):
super().__init__(
type='audio', media=media, thumb=thumb, caption=caption,
duration=duration, performer=performer, title=title,
parse_mode=parse_mode, caption_entities=caption_entities, conf=kwargs,
)
[docs]class InputMediaPhoto(InputMedia):
"""
Represents a photo to be sent.
https://core.telegram.org/bots/api#inputmediaphoto
"""
has_spoiler: typing.Optional[base.Boolean] = fields.Field()
def __init__(
self,
media: base.InputFile,
caption: base.String = None,
parse_mode: base.String = None,
caption_entities: typing.Optional[typing.List[MessageEntity]] = None,
has_spoiler: typing.Optional[base.Boolean] = None,
**kwargs,
):
super().__init__(
type='photo', media=media, caption=caption, parse_mode=parse_mode,
caption_entities=caption_entities, has_spoiler=has_spoiler, conf=kwargs,
)
[docs]class InputMediaVideo(InputMedia):
"""
Represents a video to be sent.
https://core.telegram.org/bots/api#inputmediavideo
"""
width: base.Integer = fields.Field()
height: base.Integer = fields.Field()
duration: base.Integer = fields.Field()
supports_streaming: base.Boolean = fields.Field()
has_spoiler: typing.Optional[base.Boolean] = fields.Field()
def __init__(
self,
media: base.InputFile,
thumb: typing.Union[base.InputFile, base.String] = None,
caption: base.String = None,
width: base.Integer = None,
height: base.Integer = None,
duration: base.Integer = None,
parse_mode: base.String = None,
caption_entities: typing.Optional[typing.List[MessageEntity]] = None,
supports_streaming: base.Boolean = None,
has_spoiler: typing.Optional[base.Boolean] = None,
**kwargs,
):
super().__init__(
type='video', media=media, thumb=thumb, caption=caption,
width=width, height=height, duration=duration,
parse_mode=parse_mode, caption_entities=caption_entities,
supports_streaming=supports_streaming, has_spoiler=has_spoiler, conf=kwargs
)
[docs]class MediaGroup(base.TelegramObject):
"""
Helper for sending media group
"""
def __init__(self, medias: typing.Optional[typing.List[typing.Union[InputMedia, typing.Dict]]] = None):
super(MediaGroup, self).__init__()
self.media = []
if medias:
self.attach_many(*medias)
[docs] def attach_many(self, *medias: typing.Union[InputMedia, typing.Dict]):
"""
Attach list of media
:param medias:
"""
for media in medias:
self.attach(media)
[docs] def attach(self, media: typing.Union[InputMedia, typing.Dict]):
"""
Attach media
:param media:
"""
if isinstance(media, dict):
if 'type' not in media:
raise ValueError(f"Invalid media!")
media_type = media['type']
if media_type == 'photo':
media = InputMediaPhoto(**media)
elif media_type == 'video':
media = InputMediaVideo(**media)
elif media_type == 'document':
media = InputMediaDocument(**media)
elif media_type == 'audio':
media = InputMediaAudio(**media)
# elif media_type == 'animation':
# media = InputMediaAnimation(**media)
else:
raise TypeError(f"Invalid media type '{media_type}'!")
elif not isinstance(media, InputMedia):
raise TypeError(f"Media must be an instance of InputMedia or dict, not {type(media).__name__}")
elif media.type == 'animation':
raise ValueError("This type of media is not supported by media groups!")
self.media.append(media)
'''
def attach_animation(self, animation: base.InputFile,
thumb: typing.Union[base.InputFile, base.String] = None,
caption: base.String = None,
width: base.Integer = None, height: base.Integer = None, duration: base.Integer = None,
parse_mode: base.Boolean = None):
"""
Attach animation
:param animation:
:param thumb:
:param caption:
:param width:
:param height:
:param duration:
:param parse_mode:
"""
if not isinstance(animation, InputMedia):
animation = InputMediaAnimation(media=animation, thumb=thumb, caption=caption,
width=width, height=height, duration=duration,
parse_mode=parse_mode)
self.attach(animation)
'''
[docs] def attach_audio(self, audio: typing.Union[InputMediaAudio, base.InputFile],
thumb: typing.Union[base.InputFile, base.String] = None,
caption: base.String = None,
duration: base.Integer = None,
performer: base.String = None,
title: base.String = None,
parse_mode: base.String = None,
caption_entities: typing.Optional[typing.List[MessageEntity]] = None):
"""
Attach audio
:param audio:
:param thumb:
:param caption:
:param duration:
:param performer:
:param title:
:param parse_mode:
:param caption_entities:
"""
if not isinstance(audio, InputMedia):
audio = InputMediaAudio(media=audio, thumb=thumb, caption=caption,
duration=duration,
performer=performer, title=title,
parse_mode=parse_mode,
caption_entities=caption_entities)
self.attach(audio)
[docs] def attach_document(self, document: typing.Union[InputMediaDocument, base.InputFile],
thumb: typing.Union[base.InputFile, base.String] = None,
caption: base.String = None, parse_mode: base.String = None,
caption_entities: typing.Optional[typing.List[MessageEntity]] = None,
disable_content_type_detection: typing.Optional[base.Boolean] = None):
"""
Attach document
:param document:
:param caption:
:param thumb:
:param parse_mode:
:param caption_entities:
:param disable_content_type_detection:
"""
if not isinstance(document, InputMedia):
document = InputMediaDocument(media=document, thumb=thumb, caption=caption,
parse_mode=parse_mode, caption_entities=caption_entities,
disable_content_type_detection=disable_content_type_detection)
self.attach(document)
[docs] def attach_photo(self, photo: typing.Union[InputMediaPhoto, base.InputFile],
caption: base.String = None, parse_mode: base.String = None,
caption_entities: typing.Optional[typing.List[MessageEntity]] = None):
"""
Attach photo
:param photo:
:param caption:
:param parse_mode:
:param caption_entities:
"""
if not isinstance(photo, InputMedia):
photo = InputMediaPhoto(media=photo, caption=caption, parse_mode=parse_mode,
caption_entities=caption_entities)
self.attach(photo)
[docs] def attach_video(self, video: typing.Union[InputMediaVideo, base.InputFile],
thumb: typing.Union[base.InputFile, base.String] = None,
caption: base.String = None,
width: base.Integer = None, height: base.Integer = None,
duration: base.Integer = None, parse_mode: base.String = None,
caption_entities: typing.Optional[typing.List[MessageEntity]] = None,
supports_streaming: base.Boolean = None):
"""
Attach video
:param video:
:param thumb:
:param caption:
:param width:
:param height:
:param duration:
:param parse_mode:
:param caption_entities:
:param supports_streaming:
"""
if not isinstance(video, InputMedia):
video = InputMediaVideo(media=video, thumb=thumb, caption=caption,
width=width, height=height, duration=duration,
parse_mode=parse_mode, caption_entities=caption_entities,
supports_streaming=supports_streaming)
self.attach(video)
[docs] def to_python(self) -> typing.List:
"""
Get object as JSON serializable
:return:
"""
# self.clean()
result = []
for obj in self.media:
if isinstance(obj, base.TelegramObject):
obj = obj.to_python()
result.append(obj)
return result
def get_files(self):
for inputmedia in self.media:
if not isinstance(inputmedia, InputMedia) or not inputmedia.file:
continue
yield from inputmedia.get_files()