diff --git a/aiogram/types/__init__.py b/aiogram/types/__init__.py index 3f63fac1..7b1e1e6a 100644 --- a/aiogram/types/__init__.py +++ b/aiogram/types/__init__.py @@ -3,6 +3,16 @@ import json import time +def deserialize(deserializable, data): + if data: + return deserializable.de_json(data) + + +def deserialize_array(deserializable, array): + if array: + return [deserialize(deserializable, item) for item in array] + + class Serializable: def to_json(self): """ @@ -42,7 +52,7 @@ class Deserializable: def bot(self, bot): setattr(self, '_bot', bot) for name, attr in self.__dict__.items(): - if isinstance(attr, Deserializable): + if hasattr(attr, 'de_json'): attr.bot = bot @classmethod @@ -76,3 +86,11 @@ class Deserializable: def __repr__(self): return str(self) + + @classmethod + def deserialize(cls, obj): + return deserialize(cls, obj) + + @classmethod + def deserialize_array(cls, objs): + return deserialize_array(cls, objs) diff --git a/aiogram/types/animation.py b/aiogram/types/animation.py new file mode 100644 index 00000000..f4021613 --- /dev/null +++ b/aiogram/types/animation.py @@ -0,0 +1,23 @@ +from aiogram.types.photo_size import PhotoSize +from . import Deserializable, deserialize + + +class Animation(Deserializable): + def __init__(self, file_id, thumb, file_name, mime_type, file_size): + self.file_id: str = file_id + self.thumb: PhotoSize = thumb + self.file_name: str = file_name + self.mime_type: str = mime_type + self.file_size: int = file_size + + @classmethod + def de_json(cls, raw_data): + raw_data = cls.check_json(raw_data) + + file_id = raw_data.get('file_id') + thumb = PhotoSize.deserialize(raw_data.get('thumb')) + file_name = raw_data.get('file_name') + mime_type = raw_data.get('mime_type') + file_size = raw_data.get('file_size') + + return Animation(file_id, thumb, file_name, mime_type, file_size) diff --git a/aiogram/types/audio.py b/aiogram/types/audio.py index 746cf5c5..2f1f7abf 100644 --- a/aiogram/types/audio.py +++ b/aiogram/types/audio.py @@ -3,12 +3,12 @@ from . import Deserializable class Audio(Deserializable): def __init__(self, file_id, duration, performer, title, mime_type, file_size): - self.file_id = file_id - self.duration = duration - self.performer = performer - self.title = title - self.mime_type = mime_type - self.file_size = file_size + self.file_id: str = file_id + self.duration: int = duration + self.performer: str = performer + self.title: str = title + self.mime_type: str = mime_type + self.file_size: int = file_size @classmethod def de_json(cls, raw_data): diff --git a/aiogram/types/callback_query.py b/aiogram/types/callback_query.py index 33d451da..e5efa496 100644 --- a/aiogram/types/callback_query.py +++ b/aiogram/types/callback_query.py @@ -1,24 +1,25 @@ -from . import Deserializable +from aiogram.types.message import Message +from aiogram.types.user import User +from . import Deserializable, deserialize class CallbackQuery(Deserializable): def __init__(self, id, from_user, message, inline_message_id, chat_instance, data, game_short_name): - self.data = data - self.id = id - self.from_user = from_user - self.message = message - self.inline_message_id = inline_message_id - self.chat_instance = chat_instance - self.data = data - self.game_short_name = game_short_name + self.id: int = id + self.from_user: User = from_user + self.message: Message = message + self.inline_message_id: int = inline_message_id + self.chat_instance: str = chat_instance + self.data: str = data + self.game_short_name: str = game_short_name @classmethod def de_json(cls, raw_data): raw_data = cls.check_json(raw_data) id = raw_data.get('id') - from_user = raw_data.get('from') - message = raw_data.get('message') + from_user = User.deserialize(raw_data.get('from')) + message = Message.deserialize(raw_data.get('message')) inline_message_id = raw_data.get('inline_message_id') chat_instance = raw_data.get('chat_instance') data = raw_data.get('data') diff --git a/aiogram/types/chat_member.py b/aiogram/types/chat_member.py index 0612e13c..be27163e 100644 --- a/aiogram/types/chat_member.py +++ b/aiogram/types/chat_member.py @@ -1,16 +1,17 @@ -from . import Deserializable +from aiogram.types.user import User +from . import Deserializable, deserialize class ChatMember(Deserializable): def __init__(self, user, status): - self.user = user - self.status = status + self.user: User = user + self.status: str = status @classmethod def de_json(cls, raw_data): raw_data = cls.check_json(raw_data) - user = raw_data.get('user') + user = User.deserialize(raw_data.get('user')) status = raw_data.get('status') return ChatMember(user, status) diff --git a/aiogram/types/chosen_inline_result.py b/aiogram/types/chosen_inline_result.py new file mode 100644 index 00000000..b72d8504 --- /dev/null +++ b/aiogram/types/chosen_inline_result.py @@ -0,0 +1,24 @@ +from aiogram.types.location import Location +from aiogram.types.user import User +from . import Deserializable + + +class ChosenInlineResult(Deserializable): + def __init__(self, result_id, from_user, location, inline_message_id, query): + self.result_id: str = result_id + self.from_user: User = from_user + self.location: Location = location + self.inline_message_id: str = inline_message_id + self.query: str = query + + @classmethod + def de_json(cls, raw_data): + raw_data = cls.check_json(raw_data) + + result_id = raw_data.get('result_id') + from_user = User.deserialize(raw_data.get('from')) + location = Location.deserialize(raw_data.get('location')) + inline_message_id = raw_data.get('inline_message_id') + query = raw_data.get('query') + + return ChosenInlineResult(result_id, from_user, location, inline_message_id, query) diff --git a/aiogram/types/contact.py b/aiogram/types/contact.py index 630ce02a..eec2a4fb 100644 --- a/aiogram/types/contact.py +++ b/aiogram/types/contact.py @@ -3,10 +3,10 @@ from . import Deserializable class Contact(Deserializable): def __init__(self, phone_number, first_name, last_name, user_id): - self.phone_number = phone_number - self.first_name = first_name - self.last_name = last_name - self.user_id = user_id + self.phone_number: str = phone_number + self.first_name: str = first_name + self.last_name: str = last_name + self.user_id: int = user_id @classmethod def de_json(cls, raw_data): diff --git a/aiogram/types/document.py b/aiogram/types/document.py index bef8eae7..5161455e 100644 --- a/aiogram/types/document.py +++ b/aiogram/types/document.py @@ -1,20 +1,21 @@ -from . import Deserializable +from aiogram.types.photo_size import PhotoSize +from . import Deserializable, deserialize class Document(Deserializable): def __init__(self, file_id, thumb, file_name, mime_type, file_size): - self.file_id = file_id - self.thumb = thumb - self.file_name = file_name - self.mime_type = mime_type - self.file_size = file_size + self.file_id: str = file_id + self.thumb: PhotoSize = thumb + self.file_name: str = file_name + self.mime_type: str = mime_type + self.file_size: int = file_size @classmethod def de_json(cls, raw_data): raw_data = cls.check_json(raw_data) file_id = raw_data.get('file_id') - thumb = raw_data.get('thumb') + thumb = PhotoSize.deserialize(raw_data.get('thumb')) file_name = raw_data.get('file_name') mime_type = raw_data.get('mime_type') file_size = raw_data.get('file_size') diff --git a/aiogram/types/file.py b/aiogram/types/file.py index 88234190..08b2768d 100644 --- a/aiogram/types/file.py +++ b/aiogram/types/file.py @@ -3,9 +3,9 @@ from . import Deserializable class File(Deserializable): def __init__(self, file_id, file_size, file_path): - self.file_id = file_id - self.file_size = file_size - self.file_path = file_path + self.file_id: str = file_id + self.file_size: int = file_size + self.file_path: str = file_path @classmethod def de_json(cls, raw_data): diff --git a/aiogram/types/game.py b/aiogram/types/game.py new file mode 100644 index 00000000..351e73b2 --- /dev/null +++ b/aiogram/types/game.py @@ -0,0 +1,27 @@ +from aiogram.types.animation import Animation +from aiogram.types.message_entity import MessageEntity +from aiogram.types.photo_size import PhotoSize +from . import Deserializable + + +class Game(Deserializable): + def __init__(self, title, description, photo, text, text_entities, animation): + self.title = title + self.description = description + self.photo = photo + self.text = text + self.text_entities = text_entities + self.animation = animation + + @classmethod + def de_json(cls, raw_data): + raw_data = cls.check_json(raw_data) + + title = raw_data.get('title') + description = raw_data.get('description') + photo = PhotoSize.deserialize_array(raw_data.get('photo')) + text = raw_data.get('text') + text_entities = MessageEntity.deserialize_array(raw_data.get('text_entities')) + animation = Animation.deserialize(raw_data.get('animation')) + + return Game(title, description, photo, text, text_entities, animation) diff --git a/aiogram/types/inline_query.py b/aiogram/types/inline_query.py new file mode 100644 index 00000000..b63e062c --- /dev/null +++ b/aiogram/types/inline_query.py @@ -0,0 +1,24 @@ +from aiogram.types.location import Location +from aiogram.types.user import User +from . import Deserializable + + +class InlineQuery(Deserializable): + def __init__(self, id, from_user, location, query, offset): + self.id: int = id + self.from_user: User = from_user + self.location: Location = location + self.query: str = query + self.offset: str = offset + + @classmethod + def de_json(cls, raw_data): + raw_data = cls.check_json(raw_data) + + id = raw_data.get('id') + from_user = User.deserialize(raw_data.get('from')) + location = Location.deserialize(raw_data.get('location')) + query = raw_data.get('query') + offset = raw_data.get('offset') + + return InlineQuery(id, from_user, location, query, offset) diff --git a/aiogram/types/invoice.py b/aiogram/types/invoice.py new file mode 100644 index 00000000..5c328ef0 --- /dev/null +++ b/aiogram/types/invoice.py @@ -0,0 +1,22 @@ +from . import Deserializable + + +class Invoice(Deserializable): + def __init__(self, title, description, start_parameter, currency, total_amount): + self.title: str = title + self.description: str = description + self.start_parameter: str = start_parameter + self.currency: str = currency + self.total_amount: int = total_amount + + @classmethod + def de_json(cls, raw_data): + raw_data = cls.check_json(raw_data) + + title = raw_data.get('title') + description = raw_data.get('description') + start_parameter = raw_data.get('start_parameter') + currency = raw_data.get('currency') + total_amount = raw_data.get('total_amount') + + return Invoice(title, description, start_parameter, currency, total_amount) diff --git a/aiogram/types/message.py b/aiogram/types/message.py index c5ef2f0f..abaa09c7 100644 --- a/aiogram/types/message.py +++ b/aiogram/types/message.py @@ -2,16 +2,29 @@ import datetime from aiogram.exceptions import TelegramAPIError from . import Deserializable +from .audio import Audio from .chat import Chat +from .contact import Contact +from .document import Document +from .game import Game +from .invoice import Invoice +from .location import Location from .message_entity import MessageEntity +from .photo_size import PhotoSize +from .sticker import Sticker +from .successful_payment import SuccessfulPayment from .user import User +from .venue import Venue +from .video import Video +from .video_note import VideoNote +from .voice import Voice class Message(Deserializable): def __init__(self, message_id, from_user, date, chat, forward_from, forward_from_chat, forward_from_message_id, forward_date, reply_to_message, edit_date, text, entities, audio, document, game, photo, sticker, video, voice, video_note, new_chat_members, caption, contact, location, venue, - new_chat_member, left_chat_member, new_chat_title, new_chat_photo, delete_chat_photo, + left_chat_member, new_chat_title, new_chat_photo, delete_chat_photo, group_chat_created, supergroup_chat_created, channel_chat_created, migrate_to_chat_id, migrate_from_chat_id, pinned_message, invoice, successful_payment, content_type): self.message_id: int = message_id @@ -26,7 +39,6 @@ class Message(Deserializable): self.edit_date: datetime.datetime = edit_date self.text: str = text self.entities = entities - self.audio = audio self.document = document self.game = game @@ -40,7 +52,6 @@ class Message(Deserializable): self.contact = contact self.location = location self.venue = venue - self.new_chat_member = new_chat_member self.left_chat_member = left_chat_member self.new_chat_title = new_chat_title self.new_chat_photo = new_chat_photo @@ -60,65 +71,47 @@ class Message(Deserializable): def _parse_date(cls, unix_time): return datetime.datetime.fromtimestamp(unix_time) - @classmethod - def _parse_user(cls, user): - return User.de_json(user) if user else None - - @classmethod - def _parse_chat(cls, chat): - return Chat.de_json(chat) if chat else None - - @classmethod - def _parse_message(cls, message): - return Message.de_json(message) if message else None - - @classmethod - def _parse_entities(cls, entities): - return [MessageEntity.de_json(entity) for entity in entities] if entities else None - @classmethod def de_json(cls, raw_data): raw_data = cls.check_json(raw_data) message_id = raw_data.get('message_id') - from_user = cls._parse_user(raw_data.get('from')) + from_user = User.deserialize(raw_data.get('from')) date = cls._parse_date(raw_data.get('date', 0)) - chat = cls._parse_chat(raw_data.get('chat', {})) - forward_from = cls._parse_user(raw_data.get('forward_from', {})) - forward_from_chat = cls._parse_chat(raw_data.get('forward_from_chat', {})) + chat = Chat.deserialize(raw_data.get('chat', {})) + forward_from = User.deserialize(raw_data.get('forward_from', {})) + forward_from_chat = Chat.deserialize(raw_data.get('forward_from_chat', {})) forward_from_message_id = raw_data.get('forward_from_message_id') forward_date = cls._parse_date(raw_data.get('forward_date', 0)) - reply_to_message = cls._parse_message(raw_data.get('reply_to_message', {})) + reply_to_message = Message.deserialize(raw_data.get('reply_to_message', {})) edit_date = cls._parse_date(raw_data.get('edit_date', 0)) text = raw_data.get('text') - entities = cls._parse_entities(raw_data.get('entities')) - - audio = raw_data.get('audio') - document = raw_data.get('document') - game = raw_data.get('game') - photo = raw_data.get('photo') - sticker = raw_data.get('sticker') - video = raw_data.get('video') - voice = raw_data.get('voice') - video_note = raw_data.get('video_note') - new_chat_members = raw_data.get('new_chat_members') + entities = MessageEntity.deserialize_array(raw_data.get('entities')) + audio = Audio.deserialize(raw_data.get('audio')) + document = Document.deserialize(raw_data.get('document')) + game = Game.deserialize(raw_data.get('game')) + photo = PhotoSize.deserialize(raw_data.get('photo')) + sticker = Sticker.deserialize(raw_data.get('sticker')) + video = Video.deserialize(raw_data.get('video')) + voice = Voice.deserialize(raw_data.get('voice')) + video_note = VideoNote.deserialize(raw_data.get('video_note')) + new_chat_members = User.deserialize_array(raw_data.get('new_chat_members')) caption = raw_data.get('caption') - contact = raw_data.get('contact') - location = raw_data.get('location') - venue = raw_data.get('venue') - new_chat_member = raw_data.get('new_chat_member') - left_chat_member = raw_data.get('left_chat_member') + contact = Contact.deserialize(raw_data.get('contact')) + location = Location.deserialize(raw_data.get('location')) + venue = Venue.deserialize(raw_data.get('venue')) + left_chat_member = User.deserialize(raw_data.get('left_chat_member')) new_chat_title = raw_data.get('new_chat_title') new_chat_photo = raw_data.get('new_chat_photo') - delete_chat_photo = raw_data.get('delete_chat_photo') + delete_chat_photo = PhotoSize.deserialize_array(raw_data.get('delete_chat_photo')) group_chat_created = raw_data.get('group_chat_created') supergroup_chat_created = raw_data.get('supergroup_chat_created') channel_chat_created = raw_data.get('channel_chat_created') migrate_to_chat_id = raw_data.get('migrate_to_chat_id') migrate_from_chat_id = raw_data.get('migrate_from_chat_id') - pinned_message = raw_data.get('pinned_message') - invoice = raw_data.get('invoice') - successful_payment = raw_data.get('successful_payment') + pinned_message = Message.deserialize(raw_data.get('pinned_message')) + invoice = Invoice.deserialize(raw_data.get('invoice')) + successful_payment = SuccessfulPayment.deserialize(raw_data.get('successful_payment')) if text: content_type = ContentType.TEXT @@ -136,7 +129,7 @@ class Message(Deserializable): content_type = ContentType.VIDEO elif voice: content_type = ContentType.VOICE - elif new_chat_member or new_chat_members: + elif new_chat_members: content_type = ContentType.NEW_CHAT_MEMBERS elif left_chat_member: content_type = ContentType.LEFT_CHAT_MEMBER @@ -150,7 +143,7 @@ class Message(Deserializable): return Message(message_id, from_user, date, chat, forward_from, forward_from_chat, forward_from_message_id, forward_date, reply_to_message, edit_date, text, entities, audio, document, game, photo, sticker, video, voice, video_note, new_chat_members, caption, contact, - location, venue, new_chat_member, left_chat_member, new_chat_title, new_chat_photo, + location, venue, left_chat_member, new_chat_title, new_chat_photo, delete_chat_photo, group_chat_created, supergroup_chat_created, channel_chat_created, migrate_to_chat_id, migrate_from_chat_id, pinned_message, invoice, successful_payment, content_type) diff --git a/aiogram/types/message_entity.py b/aiogram/types/message_entity.py index 7da9444e..29c6bba3 100644 --- a/aiogram/types/message_entity.py +++ b/aiogram/types/message_entity.py @@ -1,18 +1,14 @@ -from . import Deserializable +from . import Deserializable, deserialize from .user import User class MessageEntity(Deserializable): def __init__(self, type, offset, length, url, user): - self.type = type - self.offset = offset - self.length = length - self.url = url - self.user = user - - @classmethod - def _parse_user(cls, user): - return User.de_json(user) if user else None + self.type: str = type + self.offset: int = offset + self.length: int = length + self.url: str = url + self.user: User = user @classmethod def de_json(cls, raw_data): @@ -22,7 +18,7 @@ class MessageEntity(Deserializable): offset = raw_data.get('offset') length = raw_data.get('length') url = raw_data.get('url') - user = cls._parse_user(raw_data.get('user')) + user = User.deserialize(raw_data.get('user')) return MessageEntity(type, offset, length, url, user) diff --git a/aiogram/types/order_info.py b/aiogram/types/order_info.py new file mode 100644 index 00000000..a3df4886 --- /dev/null +++ b/aiogram/types/order_info.py @@ -0,0 +1,21 @@ +from aiogram.types.shipping_address import ShippingAddress +from . import Deserializable + + +class OrderInfo(Deserializable): + def __init__(self, name, phone_number, email, shipping_address): + self.name: str = name + self.phone_number: str = phone_number + self.email: str = email + self.shipping_address: ShippingAddress = shipping_address + + @classmethod + def de_json(cls, raw_data): + raw_data = cls.check_json(raw_data) + + name = raw_data.get('name') + phone_number = raw_data.get('phone_number') + email = raw_data.get('email') + shipping_address = ShippingAddress.deserialize(raw_data.get('shipping_address')) + + return OrderInfo(name, phone_number, email, shipping_address) diff --git a/aiogram/types/photo_size.py b/aiogram/types/photo_size.py index 9f9b111a..bc198a03 100644 --- a/aiogram/types/photo_size.py +++ b/aiogram/types/photo_size.py @@ -1,12 +1,12 @@ -from . import Deserializable +from . import Deserializable, deserialize class PhotoSize(Deserializable): def __init__(self, file_id, width, height, file_size): - self.file_id = file_id - self.width = width - self.height = height - self.file_size = file_size + self.file_id: str = file_id + self.width: int = width + self.height: int = height + self.file_size: int = file_size @classmethod def de_json(cls, raw_data): @@ -18,3 +18,7 @@ class PhotoSize(Deserializable): file_size = raw_data.get('file_size') return PhotoSize(file_id, width, height, file_size) + + @classmethod + def parse_array(cls, photos): + return [deserialize(PhotoSize, photo) for photo in photos] if photos else None diff --git a/aiogram/types/pre_checkout_query.py b/aiogram/types/pre_checkout_query.py new file mode 100644 index 00000000..e066325d --- /dev/null +++ b/aiogram/types/pre_checkout_query.py @@ -0,0 +1,28 @@ +from aiogram.types.order_info import OrderInfo +from aiogram.types.user import User +from . import Deserializable + + +class PreCheckoutQuery(Deserializable): + def __init__(self, id, from_user, currency, total_amount, invoice_payload, shipping_option_id, order_info): + self.id: str = id + self.from_user: User = from_user + self.currency: str = currency + self.total_amount: int = total_amount + self.invoice_payload: str = invoice_payload + self.shipping_option_id: str = shipping_option_id + self.order_info: OrderInfo = order_info + + @classmethod + def de_json(cls, raw_data): + raw_data = cls.check_json(raw_data) + + id = raw_data.get('id') + from_user = User.deserialize(raw_data.get('from')) + currency = raw_data.get('currency') + total_amount = raw_data.get('total_amount') + invoice_payload = raw_data.get('invoice_payload') + shipping_option_id = raw_data.get('shipping_option_id') + order_info = OrderInfo.deserialize(raw_data.get('order_info')) + + return PreCheckoutQuery(id, from_user, currency, total_amount, invoice_payload, shipping_option_id, order_info) diff --git a/aiogram/types/shipping_address.py b/aiogram/types/shipping_address.py new file mode 100644 index 00000000..6c5a194d --- /dev/null +++ b/aiogram/types/shipping_address.py @@ -0,0 +1,24 @@ +from . import Deserializable + + +class ShippingAddress(Deserializable): + def __init__(self, country_code, state, city, street_line1, street_line2, post_code): + self.country_code: str = country_code + self.state: str = state + self.city: str = city + self.street_line1: str = street_line1 + self.street_line2: str = street_line2 + self.post_code: str = post_code + + @classmethod + def de_json(cls, raw_data): + raw_data = cls.check_json(raw_data) + + country_code = raw_data.get('country_code') + state = raw_data.get('state') + city = raw_data.get('city') + street_line1 = raw_data.get('street_line1') + street_line2 = raw_data.get('street_line2') + post_code = raw_data.get('post_code') + + return ShippingAddress(country_code, state, city, street_line1, street_line2, post_code) diff --git a/aiogram/types/shipping_query.py b/aiogram/types/shipping_query.py new file mode 100644 index 00000000..858ed193 --- /dev/null +++ b/aiogram/types/shipping_query.py @@ -0,0 +1,22 @@ +from aiogram.types.shipping_address import ShippingAddress +from aiogram.types.user import User +from . import Deserializable + + +class ShippingQuery(Deserializable): + def __init__(self, id, from_user, invoice_payload, shipping_address): + self.id: str = id + self.from_user: User = from_user + self.invoice_payload: str = invoice_payload + self.shipping_address: ShippingAddress = shipping_address + + @classmethod + def de_json(cls, raw_data): + raw_data = cls.check_json(raw_data) + + id = raw_data.get('id') + from_user = User.deserialize(raw_data.get('from')) + invoice_payload = raw_data.get('invoice_payload') + shipping_address = ShippingAddress.deserialize(raw_data.get('shipping_address')) + + return ShippingQuery(id, from_user, invoice_payload, shipping_address) diff --git a/aiogram/types/sticker.py b/aiogram/types/sticker.py index 249b2aa9..7d602ff2 100644 --- a/aiogram/types/sticker.py +++ b/aiogram/types/sticker.py @@ -1,14 +1,15 @@ +from aiogram.types.photo_size import PhotoSize from . import Deserializable class Sticker(Deserializable): def __init__(self, file_id, width, height, thumb, emoji, file_size): - self.file_id = file_id - self.width = width - self.height = height - self.thumb = thumb - self.emoji = emoji - self.file_size = file_size + self.file_id: str = file_id + self.width: int = width + self.height: int = height + self.thumb: PhotoSize = thumb + self.emoji: str = emoji + self.file_size: int = file_size @classmethod def de_json(cls, raw_data): @@ -17,7 +18,7 @@ class Sticker(Deserializable): file_id = raw_data.get('file_id') width = raw_data.get('width') height = raw_data.get('height') - thumb = raw_data.get('thumb') + thumb = PhotoSize.deserialize(raw_data.get('thumb')) emoji = raw_data.get('emoji') file_size = raw_data.get('file_size') diff --git a/aiogram/types/successful_payment.py b/aiogram/types/successful_payment.py new file mode 100644 index 00000000..a8896a35 --- /dev/null +++ b/aiogram/types/successful_payment.py @@ -0,0 +1,29 @@ +from aiogram.types.order_info import OrderInfo +from . import Deserializable + + +class SuccessfulPayment(Deserializable): + def __init__(self, currency, total_amount, invoice_payload, shipping_option_id, order_info, + telegram_payment_charge_id, provider_payment_charge_id): + self.currency: str = currency + self.total_amount: int = total_amount + self.invoice_payload: str = invoice_payload + self.shipping_option_id: str = shipping_option_id + self.order_info: OrderInfo = order_info + self.telegram_payment_charge_id: str = telegram_payment_charge_id + self.provider_payment_charge_id: str = provider_payment_charge_id + + @classmethod + def de_json(cls, raw_data): + raw_data = cls.check_json(raw_data) + + currency = raw_data.get('currency') + total_amount = raw_data.get('total_amount') + invoice_payload = raw_data.get('invoice_payload') + shipping_option_id = raw_data.get('shipping_option_id') + order_info = OrderInfo.deserialize(raw_data.get('order_info')) + telegram_payment_charge_id = raw_data.get('telegram_payment_charge_id') + provider_payment_charge_id = raw_data.get('provider_payment_charge_id') + + return SuccessfulPayment(currency, total_amount, invoice_payload, shipping_option_id, order_info, + telegram_payment_charge_id, provider_payment_charge_id) diff --git a/aiogram/types/update.py b/aiogram/types/update.py index 17350120..c4622d1a 100644 --- a/aiogram/types/update.py +++ b/aiogram/types/update.py @@ -1,3 +1,8 @@ +from aiogram.types.callback_query import CallbackQuery +from aiogram.types.chosen_inline_result import ChosenInlineResult +from aiogram.types.inline_query import InlineQuery +from aiogram.types.pre_checkout_query import PreCheckoutQuery +from aiogram.types.shipping_query import ShippingQuery from . import Deserializable from .message import Message @@ -5,20 +10,16 @@ from .message import Message class Update(Deserializable): def __init__(self, update_id, message, edited_message, channel_post, edited_channel_post, inline_query, chosen_inline_result, callback_query, shipping_query, pre_checkout_query): - self.update_id = update_id + self.update_id: int = update_id self.message: Message = message self.edited_message: Message = edited_message self.channel_post: Message = channel_post self.edited_channel_post: Message = edited_channel_post - self.inline_query = inline_query - self.chosen_inline_result = chosen_inline_result - self.callback_query = callback_query - self.shipping_query = shipping_query - self.pre_checkout_query = pre_checkout_query - - @classmethod - def _parse_message(cls, message): - return Message.de_json(message) if message else None + self.inline_query: InlineQuery = inline_query + self.chosen_inline_result: ChosenInlineResult = chosen_inline_result + self.callback_query: CallbackQuery = callback_query + self.shipping_query: ShippingQuery = shipping_query + self.pre_checkout_query: PreCheckoutQuery = pre_checkout_query @classmethod def de_json(cls, raw_data): @@ -39,16 +40,16 @@ class Update(Deserializable): raw_data = cls.check_json(raw_data) update_id = raw_data.get('update_id') - message = cls._parse_message(raw_data.get('message')) - edited_message = cls._parse_message(raw_data.get('edited_message')) - channel_post = cls._parse_message(raw_data.get('channel_post')) - edited_channel_post = cls._parse_message(raw_data.get('edited_channel_post')) + message = Message.deserialize(raw_data.get('message')) + edited_message = Message.deserialize(raw_data.get('edited_message')) + channel_post = Message.deserialize(raw_data.get('channel_post')) + edited_channel_post = Message.deserialize(raw_data.get('edited_channel_post')) - inline_query = raw_data.get('inline_query') - chosen_inline_result = raw_data.get('chosen_inline_result') - callback_query = raw_data.get('callback_query') - shipping_query = raw_data.get('shipping_query') - pre_checkout_query = raw_data.get('pre_checkout_query') + inline_query = InlineQuery.deserialize(raw_data.get('inline_query')) + chosen_inline_result = ChosenInlineResult.deserialize(raw_data.get('chosen_inline_result')) + callback_query = CallbackQuery.deserialize(raw_data.get('callback_query')) + shipping_query = ShippingQuery.deserialize(raw_data.get('shipping_query')) + pre_checkout_query = PreCheckoutQuery.deserialize(raw_data.get('pre_checkout_query')) return Update(update_id, message, edited_message, channel_post, edited_channel_post, inline_query, chosen_inline_result, callback_query, shipping_query, pre_checkout_query) diff --git a/aiogram/types/user_profile_photos.py b/aiogram/types/user_profile_photos.py index 234350f4..c66d3f9d 100644 --- a/aiogram/types/user_profile_photos.py +++ b/aiogram/types/user_profile_photos.py @@ -1,16 +1,17 @@ +from aiogram.types.photo_size import PhotoSize from . import Deserializable class UserProfilePhotos(Deserializable): def __init__(self, total_count, photos): - self.total_count = total_count - self.photos = photos + self.total_count: int = total_count + self.photos: [PhotoSize] = photos @classmethod def de_json(cls, raw_data): raw_data = cls.check_json(raw_data) total_count = raw_data.get('total_count') - photos = raw_data.get('photos') + photos = PhotoSize.deserialize_array(raw_data.get('photos')) return UserProfilePhotos(total_count, photos) diff --git a/aiogram/types/venue.py b/aiogram/types/venue.py index 296f5d72..3fdcd2fd 100644 --- a/aiogram/types/venue.py +++ b/aiogram/types/venue.py @@ -1,18 +1,19 @@ +from aiogram.types.location import Location from . import Deserializable class Venue(Deserializable): def __init__(self, location, title, address, foursquare_id): - self.location = location - self.title = title - self.address = address - self.foursquare_id = foursquare_id + self.location: Location = location + self.title: str = title + self.address: str = address + self.foursquare_id: str = foursquare_id @classmethod def de_json(cls, raw_data): raw_data = cls.check_json(raw_data) - location = raw_data.get('location') + location = Location.deserialize(raw_data.get('location')) title = raw_data.get('title') address = raw_data.get('address') foursquare_id = raw_data.get('foursquare_id') diff --git a/aiogram/types/video.py b/aiogram/types/video.py index f160cee8..d7efdae7 100644 --- a/aiogram/types/video.py +++ b/aiogram/types/video.py @@ -1,15 +1,16 @@ +from aiogram.types.photo_size import PhotoSize from . import Deserializable class Video(Deserializable): def __init__(self, file_id, width, height, duration, thumb, mime_type, file_size): - self.file_id = file_id - self.width = width - self.height = height - self.duration = duration - self.thumb = thumb + self.file_id: str = file_id + self.width: int = width + self.height: int = height + self.duration: int = duration + self.thumb: PhotoSize = thumb self.mime_type = mime_type - self.file_size = file_size + self.file_size: int = file_size @classmethod def de_json(cls, raw_data): @@ -19,7 +20,7 @@ class Video(Deserializable): width = raw_data.get('width') height = raw_data.get('height') duration = raw_data.get('duration') - thumb = raw_data.get('thumb') + thumb = PhotoSize.deserialize(raw_data.get('thumb')) mime_type = raw_data.get('mime_type') file_size = raw_data.get('file_size') diff --git a/aiogram/types/video_note.py b/aiogram/types/video_note.py index 2318a08c..311e9217 100644 --- a/aiogram/types/video_note.py +++ b/aiogram/types/video_note.py @@ -1,13 +1,14 @@ +from .photo_size import PhotoSize from . import Deserializable class VideoNote(Deserializable): def __init__(self, file_id, length, duration, thumb, file_size): - self.file_id = file_id - self.length = length - self.duration = duration - self.thumb = thumb - self.file_size = file_size + self.file_id: str = file_id + self.length: int = length + self.duration: int = duration + self.thumb: PhotoSize = thumb + self.file_size: int = file_size @classmethod def de_json(cls, raw_data): @@ -16,7 +17,7 @@ class VideoNote(Deserializable): file_id = raw_data.get('file_id') length = raw_data.get('length') duration = raw_data.get('duration') - thumb = raw_data.get('thumb') + thumb = PhotoSize.deserialize(raw_data.get('thumb')) file_size = raw_data.get('file_size') return VideoNote(file_id, length, duration, thumb, file_size) diff --git a/aiogram/types/voice.py b/aiogram/types/voice.py index 68a5022f..bfb69a2a 100644 --- a/aiogram/types/voice.py +++ b/aiogram/types/voice.py @@ -3,10 +3,10 @@ from . import Deserializable class Voice(Deserializable): def __init__(self, file_id, duration, mime_type, file_size): - self.file_id = file_id - self.duration = duration - self.mime_type = mime_type - self.file_size = file_size + self.file_id: str = file_id + self.duration: int = duration + self.mime_type: str = mime_type + self.file_size: int = file_size @classmethod def de_json(cls, raw_data):