mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-03-28 01:11:01 +01:00
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
This commit is contained in:
parent
df8aae0a38
commit
146ec54a00
28 changed files with 1489 additions and 46 deletions
README.rst
docs
source
inclusions
telegram.at-tree.rsttelegram.revenuewithdrawalstate.rsttelegram.revenuewithdrawalstatefailed.rsttelegram.revenuewithdrawalstatepending.rsttelegram.revenuewithdrawalstatesucceeded.rsttelegram.startransaction.rsttelegram.startransactions.rsttelegram.transactionpartner.rsttelegram.transactionpartnerfragment.rsttelegram.transactionpartnerother.rsttelegram.transactionpartneruser.rstsubstitutions
telegram
tests
|
@ -11,7 +11,7 @@
|
|||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.4-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.5-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API version
|
||||
|
||||
|
@ -79,7 +79,7 @@ make the development of bots easy and straightforward. These classes are contain
|
|||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **7.4** are supported.
|
||||
All types and methods of the Telegram Bot API **7.5** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
|
|
@ -369,6 +369,8 @@
|
|||
- Used for getting basic info about a file
|
||||
* - :meth:`~telegram.Bot.get_me`
|
||||
- Used for getting basic information about the bot
|
||||
* - :meth:`~telegram.Bot.get_star_transactions`
|
||||
- Used for obtaining the bot's Telegram Stars transactions
|
||||
* - :meth:`~telegram.Bot.refund_star_payment`
|
||||
- Used for refunding a payment in Telegram Stars
|
||||
|
||||
|
|
|
@ -125,12 +125,22 @@ Available Types
|
|||
telegram.replykeyboardmarkup
|
||||
telegram.replykeyboardremove
|
||||
telegram.replyparameters
|
||||
telegram.revenuewithdrawalstate
|
||||
telegram.revenuewithdrawalstatefailed
|
||||
telegram.revenuewithdrawalstatepending
|
||||
telegram.revenuewithdrawalstatesucceeded
|
||||
telegram.sentwebappmessage
|
||||
telegram.shareduser
|
||||
telegram.startransaction
|
||||
telegram.startransactions
|
||||
telegram.story
|
||||
telegram.switchinlinequerychosenchat
|
||||
telegram.telegramobject
|
||||
telegram.textquote
|
||||
telegram.transactionpartner
|
||||
telegram.transactionpartnerfragment
|
||||
telegram.transactionpartnerother
|
||||
telegram.transactionpartneruser
|
||||
telegram.update
|
||||
telegram.user
|
||||
telegram.userchatboosts
|
||||
|
|
7
docs/source/telegram.revenuewithdrawalstate.rst
Normal file
7
docs/source/telegram.revenuewithdrawalstate.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
RevenueWithdrawalState
|
||||
======================
|
||||
|
||||
.. autoclass:: telegram.RevenueWithdrawalState
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
7
docs/source/telegram.revenuewithdrawalstatefailed.rst
Normal file
7
docs/source/telegram.revenuewithdrawalstatefailed.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
RevenueWithdrawalStateFailed
|
||||
=============================
|
||||
|
||||
.. autoclass:: telegram.RevenueWithdrawalStateFailed
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
7
docs/source/telegram.revenuewithdrawalstatepending.rst
Normal file
7
docs/source/telegram.revenuewithdrawalstatepending.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
RevenueWithdrawalStatePending
|
||||
=============================
|
||||
|
||||
.. autoclass:: telegram.RevenueWithdrawalStatePending
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
7
docs/source/telegram.revenuewithdrawalstatesucceeded.rst
Normal file
7
docs/source/telegram.revenuewithdrawalstatesucceeded.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
RevenueWithdrawalStateSucceeded
|
||||
===============================
|
||||
|
||||
.. autoclass:: telegram.RevenueWithdrawalStateSucceeded
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
7
docs/source/telegram.startransaction.rst
Normal file
7
docs/source/telegram.startransaction.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
StarTransaction
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.StarTransaction
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
8
docs/source/telegram.startransactions.rst
Normal file
8
docs/source/telegram.startransactions.rst
Normal file
|
@ -0,0 +1,8 @@
|
|||
StarTransactions
|
||||
================
|
||||
|
||||
.. autoclass:: telegram.StarTransactions
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
|
7
docs/source/telegram.transactionpartner.rst
Normal file
7
docs/source/telegram.transactionpartner.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
TransactionPartner
|
||||
==================
|
||||
|
||||
.. autoclass:: telegram.TransactionPartner
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
7
docs/source/telegram.transactionpartnerfragment.rst
Normal file
7
docs/source/telegram.transactionpartnerfragment.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
TransactionPartnerFragment
|
||||
==========================
|
||||
|
||||
.. autoclass:: telegram.TransactionPartnerFragment
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
7
docs/source/telegram.transactionpartnerother.rst
Normal file
7
docs/source/telegram.transactionpartnerother.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
TransactionPartnerOther
|
||||
=======================
|
||||
|
||||
.. autoclass:: telegram.TransactionPartnerOther
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
7
docs/source/telegram.transactionpartneruser.rst
Normal file
7
docs/source/telegram.transactionpartneruser.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
TransactionPartnerUser
|
||||
======================
|
||||
|
||||
.. autoclass:: telegram.TransactionPartnerUser
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
.. |editreplymarkup| replace:: It is currently only possible to edit messages without :attr:`telegram.Message.reply_markup` or with inline keyboards.
|
||||
|
||||
.. |bcid_edit_time| replace:: Note that business messages that were not sent by the bot and do not contain an inline keyboard can only be edited within *48 hours* from the time they were sent.
|
||||
|
||||
.. |toapikwargsbase| replace:: These arguments are also considered by :meth:`~telegram.TelegramObject.to_dict` and :meth:`~telegram.TelegramObject.to_json`, i.e. when passing objects to Telegram. Passing them to Telegram is however not guaranteed to work for all kinds of objects, e.g. this will fail for objects that can not directly be JSON serialized.
|
||||
|
||||
.. |toapikwargsarg| replace:: Arbitrary keyword arguments. Can be used to store data for which there are no dedicated attributes. |toapikwargsbase|
|
||||
|
@ -82,6 +84,8 @@
|
|||
|
||||
.. |business_id_str| replace:: Unique identifier of the business connection on behalf of which the message will be sent.
|
||||
|
||||
.. |business_id_str_edit| replace:: Unique identifier of the business connection on behalf of which the message to be edited was sent
|
||||
|
||||
.. |message_effect_id| replace:: Unique identifier of the message effect to be added to the message; for private chats only.
|
||||
|
||||
.. |show_cap_above_med| replace:: :obj:`True`, if the caption must be shown above the message media.
|
||||
|
|
|
@ -200,6 +200,10 @@ __all__ = (
|
|||
"ReplyKeyboardRemove",
|
||||
"ReplyParameters",
|
||||
"ResidentialAddress",
|
||||
"RevenueWithdrawalState",
|
||||
"RevenueWithdrawalStateFailed",
|
||||
"RevenueWithdrawalStatePending",
|
||||
"RevenueWithdrawalStateSucceeded",
|
||||
"SecureData",
|
||||
"SecureValue",
|
||||
"SentWebAppMessage",
|
||||
|
@ -207,6 +211,8 @@ __all__ = (
|
|||
"ShippingAddress",
|
||||
"ShippingOption",
|
||||
"ShippingQuery",
|
||||
"StarTransaction",
|
||||
"StarTransactions",
|
||||
"Sticker",
|
||||
"StickerSet",
|
||||
"Story",
|
||||
|
@ -214,6 +220,10 @@ __all__ = (
|
|||
"SwitchInlineQueryChosenChat",
|
||||
"TelegramObject",
|
||||
"TextQuote",
|
||||
"TransactionPartner",
|
||||
"TransactionPartnerFragment",
|
||||
"TransactionPartnerOther",
|
||||
"TransactionPartnerUser",
|
||||
"Update",
|
||||
"User",
|
||||
"UserChatBoosts",
|
||||
|
@ -435,6 +445,18 @@ from ._replykeyboardmarkup import ReplyKeyboardMarkup
|
|||
from ._replykeyboardremove import ReplyKeyboardRemove
|
||||
from ._sentwebappmessage import SentWebAppMessage
|
||||
from ._shared import ChatShared, SharedUser, UsersShared
|
||||
from ._stars import (
|
||||
RevenueWithdrawalState,
|
||||
RevenueWithdrawalStateFailed,
|
||||
RevenueWithdrawalStatePending,
|
||||
RevenueWithdrawalStateSucceeded,
|
||||
StarTransaction,
|
||||
StarTransactions,
|
||||
TransactionPartner,
|
||||
TransactionPartnerFragment,
|
||||
TransactionPartnerOther,
|
||||
TransactionPartnerUser,
|
||||
)
|
||||
from ._story import Story
|
||||
from ._switchinlinequerychosenchat import SwitchInlineQueryChosenChat
|
||||
from ._telegramobject import TelegramObject
|
||||
|
|
|
@ -88,6 +88,7 @@ from telegram._poll import InputPollOption, Poll
|
|||
from telegram._reaction import ReactionType, ReactionTypeCustomEmoji, ReactionTypeEmoji
|
||||
from telegram._reply import ReplyParameters
|
||||
from telegram._sentwebappmessage import SentWebAppMessage
|
||||
from telegram._stars import StarTransactions
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._update import Update
|
||||
from telegram._user import User
|
||||
|
@ -2802,6 +2803,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
heading: Optional[int] = None,
|
||||
proximity_alert_radius: Optional[int] = None,
|
||||
live_period: Optional[int] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
location: Optional[Location] = None,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -2849,6 +2851,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
remains unchanged
|
||||
|
||||
.. versionadded:: 21.2.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Keyword Args:
|
||||
location (:class:`telegram.Location`, optional): The location to send.
|
||||
|
@ -2888,6 +2893,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
"editMessageLiveLocation",
|
||||
data,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -2901,6 +2907,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
message_id: Optional[int] = None,
|
||||
inline_message_id: Optional[str] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -2920,6 +2927,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
:paramref:`message_id` are not specified. Identifier of the inline message.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for a new
|
||||
inline keyboard.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
|
@ -2935,6 +2945,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
"stopMessageLiveLocation",
|
||||
data,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -3945,6 +3956,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
disable_web_page_preview: Optional[bool] = None,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -3957,7 +3969,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
Use this method to edit text and game messages.
|
||||
|
||||
Note:
|
||||
|editreplymarkup|.
|
||||
* |editreplymarkup|.
|
||||
* |bcid_edit_time|
|
||||
|
||||
.. seealso:: :attr:`telegram.Game.text`
|
||||
|
||||
|
@ -3988,6 +4001,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for an
|
||||
inline keyboard.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Keyword Args:
|
||||
disable_web_page_preview (:obj:`bool`, optional): Disables link previews for links in
|
||||
|
@ -4029,6 +4045,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
reply_markup=reply_markup,
|
||||
parse_mode=parse_mode,
|
||||
link_preview_options=link_preview_options,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -4046,6 +4063,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -4057,7 +4075,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
Use this method to edit captions of messages.
|
||||
|
||||
Note:
|
||||
|editreplymarkup|
|
||||
* |editreplymarkup|
|
||||
* |bcid_edit_time|
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`, optional): Required if inline_message_id is not
|
||||
|
@ -4080,6 +4099,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
|
@ -4103,6 +4125,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
caption=caption,
|
||||
parse_mode=parse_mode,
|
||||
caption_entities=caption_entities,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -4117,6 +4140,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
message_id: Optional[int] = None,
|
||||
inline_message_id: Optional[str] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -4132,7 +4156,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
:attr:`~telegram.File.file_id` or specify a URL.
|
||||
|
||||
Note:
|
||||
|editreplymarkup|
|
||||
* |editreplymarkup|
|
||||
* |bcid_edit_time|
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
|
@ -4147,6 +4172,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
specified. Identifier of the inline message.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for an
|
||||
inline keyboard.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
|
@ -4166,6 +4194,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
"editMessageMedia",
|
||||
data,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -4179,6 +4208,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
message_id: Optional[int] = None,
|
||||
inline_message_id: Optional[str] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -4191,7 +4221,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
(for inline bots).
|
||||
|
||||
Note:
|
||||
|editreplymarkup|
|
||||
* |editreplymarkup|
|
||||
* |bcid_edit_time|
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`, optional): Required if inline_message_id is not
|
||||
|
@ -4202,6 +4233,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
specified. Identifier of the inline message.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for an
|
||||
inline keyboard.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
|
@ -4221,6 +4255,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
"editMessageReplyMarkup",
|
||||
data,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -7119,6 +7154,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
chat_id: Union[int, str],
|
||||
message_id: int,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -7134,6 +7170,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
message_id (:obj:`int`): Identifier of the original message with the poll.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for a new
|
||||
message inline keyboard.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Poll`: On success, the stopped Poll is returned.
|
||||
|
@ -7146,6 +7185,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
"chat_id": chat_id,
|
||||
"message_id": message_id,
|
||||
"reply_markup": reply_markup,
|
||||
"business_connection_id": business_connection_id,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
|
@ -9070,6 +9110,50 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def get_star_transactions(
|
||||
self,
|
||||
offset: Optional[int] = None,
|
||||
limit: Optional[int] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> StarTransactions:
|
||||
"""Returns the bot's Telegram Star transactions in chronological order.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
offset (:obj:`int`, optional): Number of transactions to skip in the response.
|
||||
limit (:obj:`int`, optional): The maximum number of transactions to be retrieved.
|
||||
Values between :tg-const:`telegram.constants.StarTransactionsLimit.MIN_LIMIT`-
|
||||
:tg-const:`telegram.constants.StarTransactionsLimit.MAX_LIMIT` are accepted.
|
||||
Defaults to :tg-const:`telegram.constants.StarTransactionsLimit.MAX_LIMIT`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.StarTransactions`: On success.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
|
||||
data: JSONDict = {"offset": offset, "limit": limit}
|
||||
|
||||
return StarTransactions.de_json( # type: ignore[return-value]
|
||||
await self._post(
|
||||
"getStarTransactions",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
),
|
||||
bot=self,
|
||||
)
|
||||
|
||||
def to_dict(self, recursive: bool = True) -> JSONDict: # noqa: ARG002
|
||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
||||
data: JSONDict = {"id": self.id, "username": self.username, "first_name": self.first_name}
|
||||
|
@ -9322,3 +9406,5 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
"""Alias for :meth:`replace_sticker_in_set`"""
|
||||
refundStarPayment = refund_star_payment
|
||||
"""Alias for :meth:`refund_star_payment`"""
|
||||
getStarTransactions = get_star_transactions
|
||||
"""Alias for :meth:`get_star_transactions`"""
|
||||
|
|
|
@ -262,6 +262,8 @@ class CallbackQuery(TelegramObject):
|
|||
entities=entities,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().edit_text(
|
||||
text=text,
|
||||
|
@ -330,6 +332,8 @@ class CallbackQuery(TelegramObject):
|
|||
chat_id=None,
|
||||
message_id=None,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().edit_caption(
|
||||
caption=caption,
|
||||
|
@ -390,6 +394,8 @@ class CallbackQuery(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().edit_reply_markup(
|
||||
reply_markup=reply_markup,
|
||||
|
@ -447,6 +453,8 @@ class CallbackQuery(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().edit_media(
|
||||
media=media,
|
||||
|
@ -518,6 +526,8 @@ class CallbackQuery(TelegramObject):
|
|||
live_period=live_period,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().edit_live_location(
|
||||
latitude=latitude,
|
||||
|
@ -581,6 +591,8 @@ class CallbackQuery(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().stop_live_location(
|
||||
reply_markup=reply_markup,
|
||||
|
|
|
@ -121,7 +121,8 @@ class ChatFullInfo(_ChatBase):
|
|||
|
||||
.. versionadded:: 20.0
|
||||
emoji_status_expiration_date (:class:`datetime.datetime`, optional): Expiration date of
|
||||
emoji status of the chat or the other party in a private chat, in seconds.
|
||||
emoji status of the chat or the other party in a private chat, as a datetime object,
|
||||
if any.
|
||||
|
||||
|datetime_localization|
|
||||
|
||||
|
@ -270,7 +271,8 @@ class ChatFullInfo(_ChatBase):
|
|||
|
||||
.. versionadded:: 20.0
|
||||
emoji_status_expiration_date (:class:`datetime.datetime`): Optional. Expiration date of
|
||||
emoji status of the chat or the other party in a private chat, in seconds.
|
||||
emoji status of the chat or the other party in a private chat, as a datetime object,
|
||||
if any.
|
||||
|
||||
|datetime_localization|
|
||||
|
||||
|
|
|
@ -89,10 +89,9 @@ class InlineKeyboardButton(TelegramObject):
|
|||
Caution:
|
||||
Only ``HTTPS`` links are allowed after Bot API 6.1.
|
||||
callback_data (:obj:`str` | :obj:`object`, optional): Data to be sent in a callback query
|
||||
to the bot when button is pressed, UTF-8
|
||||
to the bot when the button is pressed, UTF-8
|
||||
:tg-const:`telegram.InlineKeyboardButton.MIN_CALLBACK_DATA`-
|
||||
:tg-const:`telegram.InlineKeyboardButton.MAX_CALLBACK_DATA` bytes.
|
||||
Not supported for messages sent on behalf of a Telegram Business account.
|
||||
If the bot instance allows arbitrary callback data, anything can be passed.
|
||||
|
||||
Tip:
|
||||
|
@ -165,10 +164,9 @@ class InlineKeyboardButton(TelegramObject):
|
|||
Caution:
|
||||
Only ``HTTPS`` links are allowed after Bot API 6.1.
|
||||
callback_data (:obj:`str` | :obj:`object`): Optional. Data to be sent in a callback query
|
||||
to the bot when button is pressed, UTF-8
|
||||
to the bot when the button is pressed, UTF-8
|
||||
:tg-const:`telegram.InlineKeyboardButton.MIN_CALLBACK_DATA`-
|
||||
:tg-const:`telegram.InlineKeyboardButton.MAX_CALLBACK_DATA` bytes.
|
||||
Not supported for messages sent on behalf of a Telegram Business account.
|
||||
web_app (:obj:`telegram.WebAppInfo`): Optional. Description of the `Web App
|
||||
<https://core.telegram.org/bots/webapps>`_ that will be launched when the user presses
|
||||
the button. The Web App will be able to send an arbitrary message on behalf of the user
|
||||
|
|
|
@ -3581,7 +3581,10 @@ class Message(MaybeInaccessibleMessage):
|
|||
"""Shortcut for::
|
||||
|
||||
await bot.edit_message_text(
|
||||
chat_id=message.chat_id, message_id=message.message_id, *args, **kwargs
|
||||
chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
business_connection_id=message.business_connection_id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.edit_message_text`.
|
||||
|
@ -3591,6 +3594,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
of methods) or channel posts, if the bot is an admin in that channel. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
Now also passes :attr:`business_connection_id`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise ``True`` is returned.
|
||||
|
@ -3611,6 +3617,7 @@ class Message(MaybeInaccessibleMessage):
|
|||
api_kwargs=api_kwargs,
|
||||
entities=entities,
|
||||
inline_message_id=None,
|
||||
business_connection_id=self.business_connection_id,
|
||||
)
|
||||
|
||||
async def edit_caption(
|
||||
|
@ -3630,7 +3637,10 @@ class Message(MaybeInaccessibleMessage):
|
|||
"""Shortcut for::
|
||||
|
||||
await bot.edit_message_caption(
|
||||
chat_id=message.chat_id, message_id=message.message_id, *args, **kwargs
|
||||
chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
business_connection_id=message.business_connection_id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
|
@ -3641,6 +3651,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
of methods) or channel posts, if the bot is an admin in that channel. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
Now also passes :attr:`business_connection_id`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise ``True`` is returned.
|
||||
|
@ -3660,6 +3673,7 @@ class Message(MaybeInaccessibleMessage):
|
|||
caption_entities=caption_entities,
|
||||
inline_message_id=None,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
business_connection_id=self.business_connection_id,
|
||||
)
|
||||
|
||||
async def edit_media(
|
||||
|
@ -3676,7 +3690,10 @@ class Message(MaybeInaccessibleMessage):
|
|||
"""Shortcut for::
|
||||
|
||||
await bot.edit_message_media(
|
||||
chat_id=message.chat_id, message_id=message.message_id, *args, **kwargs
|
||||
chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
business_connection_id=message.business_connection_id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
|
@ -3687,6 +3704,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
of methods) or channel posts, if the bot is an admin in that channel. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
Now also passes :attr:`business_connection_id`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
edited Message is returned, otherwise ``True`` is returned.
|
||||
|
@ -3703,6 +3723,7 @@ class Message(MaybeInaccessibleMessage):
|
|||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
inline_message_id=None,
|
||||
business_connection_id=self.business_connection_id,
|
||||
)
|
||||
|
||||
async def edit_reply_markup(
|
||||
|
@ -3718,7 +3739,10 @@ class Message(MaybeInaccessibleMessage):
|
|||
"""Shortcut for::
|
||||
|
||||
await bot.edit_message_reply_markup(
|
||||
chat_id=message.chat_id, message_id=message.message_id, *args, **kwargs
|
||||
chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
business_connection_id=message.business_connection_id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
|
@ -3729,6 +3753,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
of methods) or channel posts, if the bot is an admin in that channel. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
Now also passes :attr:`business_connection_id`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise ``True`` is returned.
|
||||
|
@ -3743,6 +3770,7 @@ class Message(MaybeInaccessibleMessage):
|
|||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
inline_message_id=None,
|
||||
business_connection_id=self.business_connection_id,
|
||||
)
|
||||
|
||||
async def edit_live_location(
|
||||
|
@ -3765,7 +3793,10 @@ class Message(MaybeInaccessibleMessage):
|
|||
"""Shortcut for::
|
||||
|
||||
await bot.edit_message_live_location(
|
||||
chat_id=message.chat_id, message_id=message.message_id, *args, **kwargs
|
||||
chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
business_connection_id=message.business_connection_id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
|
@ -3776,6 +3807,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
of methods) or channel posts, if the bot is an admin in that channel. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
Now also passes :attr:`business_connection_id`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise :obj:`True` is returned.
|
||||
|
@ -3797,6 +3831,7 @@ class Message(MaybeInaccessibleMessage):
|
|||
proximity_alert_radius=proximity_alert_radius,
|
||||
live_period=live_period,
|
||||
inline_message_id=None,
|
||||
business_connection_id=self.business_connection_id,
|
||||
)
|
||||
|
||||
async def stop_live_location(
|
||||
|
@ -3812,7 +3847,10 @@ class Message(MaybeInaccessibleMessage):
|
|||
"""Shortcut for::
|
||||
|
||||
await bot.stop_message_live_location(
|
||||
chat_id=message.chat_id, message_id=message.message_id, *args, **kwargs
|
||||
chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
business_connection_id=message.business_connection_id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
|
@ -3823,6 +3861,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
of methods) or channel posts, if the bot is an admin in that channel. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
Now also passes :attr:`business_connection_id`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise :obj:`True` is returned.
|
||||
|
@ -3837,6 +3878,7 @@ class Message(MaybeInaccessibleMessage):
|
|||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
inline_message_id=None,
|
||||
business_connection_id=self.business_connection_id,
|
||||
)
|
||||
|
||||
async def set_game_score(
|
||||
|
@ -3967,11 +4009,17 @@ class Message(MaybeInaccessibleMessage):
|
|||
"""Shortcut for::
|
||||
|
||||
await bot.stop_poll(
|
||||
chat_id=message.chat_id, message_id=message.message_id, *args, **kwargs
|
||||
chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
business_connection_id=message.business_connection_id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.stop_poll`.
|
||||
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
Now also passes :attr:`business_connection_id`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Poll`: On success, the stopped Poll with the final results is
|
||||
returned.
|
||||
|
@ -3986,6 +4034,7 @@ class Message(MaybeInaccessibleMessage):
|
|||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=self.business_connection_id,
|
||||
)
|
||||
|
||||
async def pin(
|
||||
|
|
477
telegram/_stars.py
Normal file
477
telegram/_stars.py
Normal file
|
@ -0,0 +1,477 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2024
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
# pylint: disable=redefined-builtin
|
||||
"""This module contains the classes for Telegram Stars transactions."""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Sequence, Tuple, Type
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._user import User
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class RevenueWithdrawalState(TelegramObject):
|
||||
"""This object escribes the state of a revenue withdrawal operation. Currently, it can be one
|
||||
of:
|
||||
|
||||
* :class:`telegram.RevenueWithdrawalStatePending`
|
||||
* :class:`telegram.RevenueWithdrawalStateSucceeded`
|
||||
* :class:`telegram.RevenueWithdrawalStateFailed`
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`type` is equal.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): The type of the state.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): The type of the state.
|
||||
"""
|
||||
|
||||
__slots__ = ("type",)
|
||||
|
||||
PENDING: Final[str] = constants.RevenueWithdrawalStateType.PENDING
|
||||
""":const:`telegram.constants.RevenueWithdrawalStateType.PENDING`"""
|
||||
SUCCEEDED: Final[str] = constants.RevenueWithdrawalStateType.SUCCEEDED
|
||||
""":const:`telegram.constants.RevenueWithdrawalStateType.SUCCEEDED`"""
|
||||
FAILED: Final[str] = constants.RevenueWithdrawalStateType.FAILED
|
||||
""":const:`telegram.constants.RevenueWithdrawalStateType.FAILED`"""
|
||||
|
||||
def __init__(self, type: str, *, api_kwargs: Optional[JSONDict] = None) -> None:
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.type: str = enum.get_member(constants.RevenueWithdrawalStateType, type, type)
|
||||
|
||||
self._id_attrs = (self.type,)
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["RevenueWithdrawalState"]:
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[RevenueWithdrawalState]] = {
|
||||
cls.PENDING: RevenueWithdrawalStatePending,
|
||||
cls.SUCCEEDED: RevenueWithdrawalStateSucceeded,
|
||||
cls.FAILED: RevenueWithdrawalStateFailed,
|
||||
}
|
||||
|
||||
if cls is RevenueWithdrawalState and data.get("type") in _class_mapping:
|
||||
return _class_mapping[data.pop("type")].de_json(data=data, bot=bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class RevenueWithdrawalStatePending(RevenueWithdrawalState):
|
||||
"""The withdrawal is in progress.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): The type of the state, always
|
||||
:tg-const:`telegram.RevenueWithdrawalState.PENDING`.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, *, api_kwargs: Optional[JSONDict] = None) -> None:
|
||||
super().__init__(type=RevenueWithdrawalState.PENDING, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class RevenueWithdrawalStateSucceeded(RevenueWithdrawalState):
|
||||
"""The withdrawal succeeded.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`date` are equal.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
date (:obj:`datetime.datetime`): Date the withdrawal was completed as a datetime object.
|
||||
url (:obj:`str`): An HTTPS URL that can be used to see transaction details.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): The type of the state, always
|
||||
:tg-const:`telegram.RevenueWithdrawalState.SUCCEEDED`.
|
||||
date (:obj:`datetime.datetime`): Date the withdrawal was completed as a datetime object.
|
||||
url (:obj:`str`): An HTTPS URL that can be used to see transaction details.
|
||||
"""
|
||||
|
||||
__slots__ = ("date", "url")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
date: datetime,
|
||||
url: str,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> None:
|
||||
super().__init__(type=RevenueWithdrawalState.SUCCEEDED, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.date: datetime = date
|
||||
self.url: str = url
|
||||
self._id_attrs = (
|
||||
self.type,
|
||||
self.date,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["RevenueWithdrawalStateSucceeded"]:
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
# Get the local timezone from the bot if it has defaults
|
||||
loc_tzinfo = extract_tzinfo_from_defaults(bot)
|
||||
data["date"] = from_timestamp(data.get("date", None), tzinfo=loc_tzinfo)
|
||||
|
||||
return super().de_json(data=data, bot=bot) # type: ignore[return-value]
|
||||
|
||||
|
||||
class RevenueWithdrawalStateFailed(RevenueWithdrawalState):
|
||||
"""The withdrawal failed and the transaction was refunded.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): The type of the state, always
|
||||
:tg-const:`telegram.RevenueWithdrawalState.FAILED`.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, *, api_kwargs: Optional[JSONDict] = None) -> None:
|
||||
super().__init__(type=RevenueWithdrawalState.FAILED, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class TransactionPartner(TelegramObject):
|
||||
"""This object describes the source of a transaction, or its recipient for outgoing
|
||||
transactions. Currently, it can be one of:
|
||||
|
||||
* :class:`TransactionPartnerFragment`
|
||||
* :class:`TransactionPartnerUser`
|
||||
* :class:`TransactionPartnerOther`
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`type` is equal.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): The type of the transaction partner.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): The type of the transaction partner.
|
||||
"""
|
||||
|
||||
__slots__ = ("type",)
|
||||
|
||||
FRAGMENT: Final[str] = constants.TransactionPartnerType.FRAGMENT
|
||||
""":const:`telegram.constants.TransactionPartnerType.FRAGMENT`"""
|
||||
USER: Final[str] = constants.TransactionPartnerType.USER
|
||||
""":const:`telegram.constants.TransactionPartnerType.USER`"""
|
||||
OTHER: Final[str] = constants.TransactionPartnerType.OTHER
|
||||
""":const:`telegram.constants.TransactionPartnerType.OTHER`"""
|
||||
|
||||
def __init__(self, type: str, *, api_kwargs: Optional[JSONDict] = None) -> None:
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.type: str = enum.get_member(constants.TransactionPartnerType, type, type)
|
||||
|
||||
self._id_attrs = (self.type,)
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["TransactionPartner"]:
|
||||
"""Converts JSON data to the appropriate :class:`TransactionPartner` object, i.e. takes
|
||||
care of selecting the correct subclass.
|
||||
|
||||
Args:
|
||||
data (Dict[:obj:`str`, ...]): The JSON data.
|
||||
bot (:class:`telegram.Bot`): The bot associated with this object.
|
||||
|
||||
Returns:
|
||||
The Telegram object.
|
||||
|
||||
"""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
if not data and cls is TransactionPartner:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[TransactionPartner]] = {
|
||||
cls.FRAGMENT: TransactionPartnerFragment,
|
||||
cls.USER: TransactionPartnerUser,
|
||||
cls.OTHER: TransactionPartnerOther,
|
||||
}
|
||||
|
||||
if cls is TransactionPartner and data.get("type") in _class_mapping:
|
||||
return _class_mapping[data.pop("type")].de_json(data=data, bot=bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class TransactionPartnerFragment(TransactionPartner):
|
||||
"""Describes a withdrawal transaction with Fragment.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
withdrawal_state (:obj:`telegram.RevenueWithdrawalState`, optional): State of the
|
||||
transaction if the transaction is outgoing.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): The type of the transaction partner,
|
||||
always :tg-const:`telegram.TransactionPartner.FRAGMENT`.
|
||||
withdrawal_state (:obj:`telegram.RevenueWithdrawalState`): Optional. State of the
|
||||
transaction if the transaction is outgoing.
|
||||
"""
|
||||
|
||||
__slots__ = ("withdrawal_state",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
withdrawal_state: Optional["RevenueWithdrawalState"] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> None:
|
||||
super().__init__(type=TransactionPartner.FRAGMENT, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.withdrawal_state: Optional[RevenueWithdrawalState] = withdrawal_state
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["TransactionPartnerFragment"]:
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["withdrawal_state"] = RevenueWithdrawalState.de_json(
|
||||
data.get("withdrawal_state"), bot
|
||||
)
|
||||
|
||||
return super().de_json(data=data, bot=bot) # type: ignore[return-value]
|
||||
|
||||
|
||||
class TransactionPartnerUser(TransactionPartner):
|
||||
"""Describes a transaction with a user.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`user` are equal.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): The type of the transaction partner,
|
||||
always :tg-const:`telegram.TransactionPartner.USER`.
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
"""
|
||||
|
||||
__slots__ = ("user",)
|
||||
|
||||
def __init__(self, user: "User", *, api_kwargs: Optional[JSONDict] = None) -> None:
|
||||
super().__init__(type=TransactionPartner.USER, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.user: User = user
|
||||
self._id_attrs = (
|
||||
self.type,
|
||||
self.user,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["TransactionPartnerUser"]:
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["user"] = User.de_json(data.get("user"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot) # type: ignore[return-value]
|
||||
|
||||
|
||||
class TransactionPartnerOther(TransactionPartner):
|
||||
"""Describes a transaction with an unknown partner.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): The type of the transaction partner,
|
||||
always :tg-const:`telegram.TransactionPartner.OTHER`.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, *, api_kwargs: Optional[JSONDict] = None) -> None:
|
||||
super().__init__(type=TransactionPartner.OTHER, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class StarTransaction(TelegramObject):
|
||||
"""Describes a Telegram Star transaction.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`id`, :attr:`source`, and :attr:`receiver` are equal.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier of the transaction. Coincides with the identifer
|
||||
of the original transaction for refund transactions.
|
||||
Coincides with :attr:`SuccessfulPayment.telegram_payment_charge_id` for
|
||||
successful incoming payments from users.
|
||||
amount (:obj:`int`): Number of Telegram Stars transferred by the transaction.
|
||||
date (:obj:`datetime.datetime`): Date the transaction was created as a datetime object.
|
||||
source (:class:`telegram.TransactionPartner`, optional): Source of an incoming transaction
|
||||
(e.g., a user purchasing goods or services, Fragment refunding a failed withdrawal).
|
||||
Only for incoming transactions.
|
||||
receiver (:class:`telegram.TransactionPartner`, optional): Receiver of an outgoing
|
||||
transaction (e.g., a user for a purchase refund, Fragment for a withdrawal). Only for
|
||||
outgoing transactions.
|
||||
|
||||
Attributes:
|
||||
id (:obj:`str`): Unique identifier of the transaction. Coincides with the identifer
|
||||
of the original transaction for refund transactions.
|
||||
Coincides with :attr:`SuccessfulPayment.telegram_payment_charge_id` for
|
||||
successful incoming payments from users.
|
||||
amount (:obj:`int`): Number of Telegram Stars transferred by the transaction.
|
||||
date (:obj:`datetime.datetime`): Date the transaction was created as a datetime object.
|
||||
source (:class:`telegram.TransactionPartner`): Optional. Source of an incoming transaction
|
||||
(e.g., a user purchasing goods or services, Fragment refunding a failed withdrawal).
|
||||
Only for incoming transactions.
|
||||
receiver (:class:`telegram.TransactionPartner`): Optional. Receiver of an outgoing
|
||||
transaction (e.g., a user for a purchase refund, Fragment for a withdrawal). Only for
|
||||
outgoing transactions.
|
||||
"""
|
||||
|
||||
__slots__ = ("amount", "date", "id", "receiver", "source")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
id: str,
|
||||
amount: int,
|
||||
date: datetime,
|
||||
source: Optional[TransactionPartner] = None,
|
||||
receiver: Optional[TransactionPartner] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> None:
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.id: str = id
|
||||
self.amount: int = amount
|
||||
self.date: datetime = date
|
||||
self.source: Optional[TransactionPartner] = source
|
||||
self.receiver: Optional[TransactionPartner] = receiver
|
||||
|
||||
self._id_attrs = (
|
||||
self.id,
|
||||
self.source,
|
||||
self.receiver,
|
||||
)
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["StarTransaction"]:
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
# Get the local timezone from the bot if it has defaults
|
||||
loc_tzinfo = extract_tzinfo_from_defaults(bot)
|
||||
data["date"] = from_timestamp(data.get("date", None), tzinfo=loc_tzinfo)
|
||||
|
||||
data["source"] = TransactionPartner.de_json(data.get("source"), bot)
|
||||
data["receiver"] = TransactionPartner.de_json(data.get("receiver"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class StarTransactions(TelegramObject):
|
||||
"""
|
||||
Contains a list of Telegram Star transactions.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`transactions` are equal.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
transactions (Sequence[:class:`telegram.StarTransaction`]): The list of transactions.
|
||||
|
||||
Attributes:
|
||||
transactions (Tuple[:class:`telegram.StarTransaction`]): The list of transactions.
|
||||
"""
|
||||
|
||||
__slots__ = ("transactions",)
|
||||
|
||||
def __init__(
|
||||
self, transactions: Sequence[StarTransaction], *, api_kwargs: Optional[JSONDict] = None
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.transactions: Tuple[StarTransaction, ...] = parse_sequence_arg(transactions)
|
||||
|
||||
self._id_attrs = (self.transactions,)
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["StarTransactions"]:
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
data["transactions"] = StarTransaction.de_list(data.get("transactions"), bot)
|
||||
return super().de_json(data=data, bot=bot)
|
|
@ -90,10 +90,13 @@ __all__ = [
|
|||
"ReactionEmoji",
|
||||
"ReactionType",
|
||||
"ReplyLimit",
|
||||
"RevenueWithdrawalStateType",
|
||||
"StarTransactionsLimit",
|
||||
"StickerFormat",
|
||||
"StickerLimit",
|
||||
"StickerSetLimit",
|
||||
"StickerType",
|
||||
"TransactionPartnerType",
|
||||
"UpdateType",
|
||||
"UserProfilePhotosLimit",
|
||||
"WebhookLimit",
|
||||
|
@ -146,7 +149,7 @@ class _AccentColor(NamedTuple):
|
|||
#: :data:`telegram.__bot_api_version_info__`.
|
||||
#:
|
||||
#: .. versionadded:: 20.0
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=4)
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=5)
|
||||
#: :obj:`str`: Telegram Bot API
|
||||
#: version supported by this version of `python-telegram-bot`. Also available as
|
||||
#: :data:`telegram.__bot_api_version__`.
|
||||
|
@ -2303,6 +2306,42 @@ class ReplyLimit(IntEnum):
|
|||
"""
|
||||
|
||||
|
||||
class RevenueWithdrawalStateType(StringEnum):
|
||||
"""This enum contains the available types of :class:`telegram.RevenueWithdrawalState`.
|
||||
The enum members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
PENDING = "pending"
|
||||
""":obj:`str`: A withdrawal in progress."""
|
||||
SUCCEEDED = "succeeded"
|
||||
""":obj:`str`: A withdrawal succeeded."""
|
||||
FAILED = "failed"
|
||||
""":obj:`str`: A withdrawal failed and the transaction was refunded."""
|
||||
|
||||
|
||||
class StarTransactionsLimit(IntEnum):
|
||||
"""This enum contains limitations for :class:`telegram.Bot.get_star_transactions`.
|
||||
The enum members of this enumeration are instances of :class:`int` and can be treated as such.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
MIN_LIMIT = 1
|
||||
""":obj:`int`: Minimum value allowed for the
|
||||
:paramref:`~telegram.Bot.get_star_transactions.limit` parameter of
|
||||
:meth:`telegram.Bot.get_star_transactions`."""
|
||||
MAX_LIMIT = 100
|
||||
""":obj:`int`: Maximum value allowed for the
|
||||
:paramref:`~telegram.Bot.get_star_transactions.limit` parameter of
|
||||
:meth:`telegram.Bot.get_star_transactions`."""
|
||||
|
||||
|
||||
class StickerFormat(StringEnum):
|
||||
"""This enum contains the available formats of :class:`telegram.Sticker` in the set. The enum
|
||||
members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||
|
@ -2436,6 +2475,23 @@ class StickerType(StringEnum):
|
|||
""":obj:`str`: Custom emoji sticker."""
|
||||
|
||||
|
||||
class TransactionPartnerType(StringEnum):
|
||||
"""This enum contains the available types of :class:`telegram.TransactionPartner`. The enum
|
||||
members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
FRAGMENT = "fragment"
|
||||
""":obj:`str`: Withdrawal transaction with Fragment."""
|
||||
USER = "user"
|
||||
""":obj:`str`: Transaction with a user."""
|
||||
OTHER = "other"
|
||||
""":obj:`str`: Transaction with unknown source or recipient."""
|
||||
|
||||
|
||||
class ParseMode(StringEnum):
|
||||
"""This enum contains the available parse modes. The enum
|
||||
members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||
|
|
|
@ -76,6 +76,7 @@ from telegram import (
|
|||
ReactionType,
|
||||
ReplyParameters,
|
||||
SentWebAppMessage,
|
||||
StarTransactions,
|
||||
Sticker,
|
||||
StickerSet,
|
||||
TelegramObject,
|
||||
|
@ -767,6 +768,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
chat_id: Union[int, str],
|
||||
message_id: int,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -780,6 +782,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
chat_id=chat_id,
|
||||
message_id=message_id,
|
||||
reply_markup=self._replace_keyboard(reply_markup),
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -1511,6 +1514,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -1527,6 +1531,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
reply_markup=reply_markup,
|
||||
parse_mode=parse_mode,
|
||||
caption_entities=caption_entities,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -1547,6 +1552,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
heading: Optional[int] = None,
|
||||
proximity_alert_radius: Optional[int] = None,
|
||||
live_period: Optional[int] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
location: Optional[Location] = None,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -1568,6 +1574,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
proximity_alert_radius=proximity_alert_radius,
|
||||
live_period=live_period,
|
||||
location=location,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -1582,6 +1589,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
message_id: Optional[int] = None,
|
||||
inline_message_id: Optional[str] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -1596,6 +1604,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
message_id=message_id,
|
||||
inline_message_id=inline_message_id,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -1609,6 +1618,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
message_id: Optional[int] = None,
|
||||
inline_message_id: Optional[str] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -1622,6 +1632,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
message_id=message_id,
|
||||
inline_message_id=inline_message_id,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -1639,6 +1650,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
disable_web_page_preview: Optional[bool] = None,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -1657,6 +1669,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
disable_web_page_preview=disable_web_page_preview,
|
||||
reply_markup=reply_markup,
|
||||
entities=entities,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -3633,6 +3646,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
message_id: Optional[int] = None,
|
||||
inline_message_id: Optional[str] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -3646,6 +3660,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
message_id=message_id,
|
||||
inline_message_id=inline_message_id,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -4179,6 +4194,28 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
)
|
||||
|
||||
async def get_star_transactions(
|
||||
self,
|
||||
offset: Optional[int] = None,
|
||||
limit: Optional[int] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
rate_limit_args: Optional[RLARGS] = None,
|
||||
) -> StarTransactions:
|
||||
return await super().get_star_transactions(
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
)
|
||||
|
||||
# updated camelCase aliases
|
||||
getMe = get_me
|
||||
sendMessage = send_message
|
||||
|
@ -4301,3 +4338,4 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
getBusinessConnection = get_business_connection
|
||||
replaceStickerInSet = replace_sticker_in_set
|
||||
refundStarPayment = refund_star_payment
|
||||
getStarTransactions = get_star_transactions
|
||||
|
|
|
@ -73,6 +73,8 @@ from telegram import (
|
|||
ReplyParameters,
|
||||
SentWebAppMessage,
|
||||
ShippingOption,
|
||||
StarTransaction,
|
||||
StarTransactions,
|
||||
Update,
|
||||
User,
|
||||
WebAppInfo,
|
||||
|
@ -2171,14 +2173,17 @@ class TestBotWithoutRequest:
|
|||
|
||||
async def test_business_connection_id_argument(self, bot, monkeypatch):
|
||||
"""We can't connect to a business acc, so we just test that the correct data is passed.
|
||||
We also can't test every single method easily, so we just test one. Our linting will catch
|
||||
any unused args with the others."""
|
||||
We also can't test every single method easily, so we just test a few. Our linting will
|
||||
catch any unused args with the others."""
|
||||
|
||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||
return request_data.parameters.get("business_connection_id") == 42
|
||||
assert request_data.parameters.get("business_connection_id") == 42
|
||||
return {}
|
||||
|
||||
monkeypatch.setattr(bot.request, "post", make_assertion)
|
||||
assert await bot.send_message(2, "text", business_connection_id=42)
|
||||
|
||||
await bot.send_message(2, "text", business_connection_id=42)
|
||||
await bot.stop_poll(chat_id=1, message_id=2, business_connection_id=42)
|
||||
|
||||
async def test_message_effect_id_argument(self, bot, monkeypatch):
|
||||
"""We can't test every single method easily, so we just test one. Our linting will catch
|
||||
|
@ -2221,6 +2226,20 @@ class TestBotWithoutRequest:
|
|||
monkeypatch.setattr(bot.request, "post", make_assertion)
|
||||
assert await bot.refund_star_payment(42, "37")
|
||||
|
||||
async def test_get_star_transactions(self, bot, monkeypatch):
|
||||
# we just want to test the offset parameter
|
||||
st = StarTransactions([StarTransaction("1", 1, dtm.datetime.now())]).to_json()
|
||||
|
||||
async def do_request(url, request_data: RequestData, *args, **kwargs):
|
||||
offset = request_data.parameters.get("offset") == 3
|
||||
if offset:
|
||||
return 200, f'{{"ok": true, "result": {st}}}'.encode()
|
||||
return 400, b'{"ok": false, "result": []}'
|
||||
|
||||
monkeypatch.setattr(bot.request, "do_request", do_request)
|
||||
obj = await bot.get_star_transactions(offset=3)
|
||||
assert isinstance(obj, StarTransactions)
|
||||
|
||||
|
||||
class TestBotWithRequest:
|
||||
"""
|
||||
|
@ -4208,3 +4227,8 @@ class TestBotWithRequest:
|
|||
@pytest.mark.parametrize("return_type", [Message, None])
|
||||
async def test_do_api_request_bool_return_type(self, bot, chat_id, return_type):
|
||||
assert await bot.do_api_request("delete_my_commands", return_type=return_type) is True
|
||||
|
||||
async def test_get_star_transactions(self, bot):
|
||||
transactions = await bot.get_star_transactions(limit=1)
|
||||
assert isinstance(transactions, StarTransactions)
|
||||
assert len(transactions.transactions) == 0
|
||||
|
|
|
@ -68,8 +68,8 @@ class TestCallbackQueryWithoutRequest(TestCallbackQueryBase):
|
|||
@staticmethod
|
||||
def skip_params(callback_query: CallbackQuery):
|
||||
if callback_query.inline_message_id:
|
||||
return {"message_id", "chat_id"}
|
||||
return {"inline_message_id"}
|
||||
return {"message_id", "chat_id", "business_connection_id"}
|
||||
return {"inline_message_id", "business_connection_id"}
|
||||
|
||||
@staticmethod
|
||||
def shortcut_kwargs(callback_query: CallbackQuery):
|
||||
|
@ -178,7 +178,7 @@ class TestCallbackQueryWithoutRequest(TestCallbackQueryBase):
|
|||
assert check_shortcut_signature(
|
||||
CallbackQuery.edit_message_text,
|
||||
Bot.edit_message_text,
|
||||
["inline_message_id", "message_id", "chat_id"],
|
||||
["inline_message_id", "message_id", "chat_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
@ -210,7 +210,7 @@ class TestCallbackQueryWithoutRequest(TestCallbackQueryBase):
|
|||
assert check_shortcut_signature(
|
||||
CallbackQuery.edit_message_caption,
|
||||
Bot.edit_message_caption,
|
||||
["inline_message_id", "message_id", "chat_id"],
|
||||
["inline_message_id", "message_id", "chat_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
@ -242,7 +242,7 @@ class TestCallbackQueryWithoutRequest(TestCallbackQueryBase):
|
|||
assert check_shortcut_signature(
|
||||
CallbackQuery.edit_message_reply_markup,
|
||||
Bot.edit_message_reply_markup,
|
||||
["inline_message_id", "message_id", "chat_id"],
|
||||
["inline_message_id", "message_id", "chat_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
@ -274,7 +274,7 @@ class TestCallbackQueryWithoutRequest(TestCallbackQueryBase):
|
|||
assert check_shortcut_signature(
|
||||
CallbackQuery.edit_message_media,
|
||||
Bot.edit_message_media,
|
||||
["inline_message_id", "message_id", "chat_id"],
|
||||
["inline_message_id", "message_id", "chat_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
@ -308,7 +308,7 @@ class TestCallbackQueryWithoutRequest(TestCallbackQueryBase):
|
|||
assert check_shortcut_signature(
|
||||
CallbackQuery.edit_message_live_location,
|
||||
Bot.edit_message_live_location,
|
||||
["inline_message_id", "message_id", "chat_id"],
|
||||
["inline_message_id", "message_id", "chat_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
@ -340,7 +340,7 @@ class TestCallbackQueryWithoutRequest(TestCallbackQueryBase):
|
|||
assert check_shortcut_signature(
|
||||
CallbackQuery.stop_message_live_location,
|
||||
Bot.stop_message_live_location,
|
||||
["inline_message_id", "message_id", "chat_id"],
|
||||
["inline_message_id", "message_id", "chat_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
|
|
@ -2347,7 +2347,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
assert check_shortcut_signature(
|
||||
Message.edit_text,
|
||||
Bot.edit_message_text,
|
||||
["chat_id", "message_id", "inline_message_id"],
|
||||
["chat_id", "message_id", "inline_message_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
@ -2355,7 +2355,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
message.get_bot(),
|
||||
"edit_message_text",
|
||||
skip_params=["inline_message_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id", "business_connection_id"],
|
||||
)
|
||||
assert await check_defaults_handling(message.edit_text, message.get_bot())
|
||||
|
||||
|
@ -2372,7 +2372,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
assert check_shortcut_signature(
|
||||
Message.edit_caption,
|
||||
Bot.edit_message_caption,
|
||||
["chat_id", "message_id", "inline_message_id"],
|
||||
["chat_id", "message_id", "inline_message_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
@ -2380,7 +2380,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
message.get_bot(),
|
||||
"edit_message_caption",
|
||||
skip_params=["inline_message_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id", "business_connection_id"],
|
||||
)
|
||||
assert await check_defaults_handling(message.edit_caption, message.get_bot())
|
||||
|
||||
|
@ -2397,7 +2397,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
assert check_shortcut_signature(
|
||||
Message.edit_media,
|
||||
Bot.edit_message_media,
|
||||
["chat_id", "message_id", "inline_message_id"],
|
||||
["chat_id", "message_id", "inline_message_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
@ -2405,7 +2405,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
message.get_bot(),
|
||||
"edit_message_media",
|
||||
skip_params=["inline_message_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id", "business_connection_id"],
|
||||
)
|
||||
assert await check_defaults_handling(message.edit_media, message.get_bot())
|
||||
|
||||
|
@ -2422,7 +2422,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
assert check_shortcut_signature(
|
||||
Message.edit_reply_markup,
|
||||
Bot.edit_message_reply_markup,
|
||||
["chat_id", "message_id", "inline_message_id"],
|
||||
["chat_id", "message_id", "inline_message_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
@ -2430,7 +2430,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
message.get_bot(),
|
||||
"edit_message_reply_markup",
|
||||
skip_params=["inline_message_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id", "business_connection_id"],
|
||||
)
|
||||
assert await check_defaults_handling(message.edit_reply_markup, message.get_bot())
|
||||
|
||||
|
@ -2449,7 +2449,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
assert check_shortcut_signature(
|
||||
Message.edit_live_location,
|
||||
Bot.edit_message_live_location,
|
||||
["chat_id", "message_id", "inline_message_id"],
|
||||
["chat_id", "message_id", "inline_message_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
@ -2457,7 +2457,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
message.get_bot(),
|
||||
"edit_message_live_location",
|
||||
skip_params=["inline_message_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id", "business_connection_id"],
|
||||
)
|
||||
assert await check_defaults_handling(message.edit_live_location, message.get_bot())
|
||||
|
||||
|
@ -2473,7 +2473,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
assert check_shortcut_signature(
|
||||
Message.stop_live_location,
|
||||
Bot.stop_message_live_location,
|
||||
["chat_id", "message_id", "inline_message_id"],
|
||||
["chat_id", "message_id", "inline_message_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
|
@ -2481,7 +2481,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
message.get_bot(),
|
||||
"stop_message_live_location",
|
||||
skip_params=["inline_message_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id"],
|
||||
shortcut_kwargs=["message_id", "chat_id", "business_connection_id"],
|
||||
)
|
||||
assert await check_defaults_handling(message.stop_live_location, message.get_bot())
|
||||
|
||||
|
@ -2561,9 +2561,17 @@ class TestMessageWithoutRequest(TestMessageBase):
|
|||
return chat_id and message_id
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Message.stop_poll, Bot.stop_poll, ["chat_id", "message_id"], []
|
||||
Message.stop_poll,
|
||||
Bot.stop_poll,
|
||||
["chat_id", "message_id", "business_connection_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
message.stop_poll,
|
||||
message.get_bot(),
|
||||
"stop_poll",
|
||||
shortcut_kwargs=["business_connection_id"],
|
||||
)
|
||||
assert await check_shortcut_call(message.stop_poll, message.get_bot(), "stop_poll")
|
||||
assert await check_defaults_handling(message.stop_poll, message.get_bot())
|
||||
|
||||
monkeypatch.setattr(message.get_bot(), "stop_poll", make_assertion)
|
||||
|
|
|
@ -125,6 +125,8 @@ PTB_EXTRA_PARAMS = {
|
|||
"BackgroundType": {"type"}, # attributes common to all subclasses
|
||||
"BackgroundFill": {"type"}, # attributes common to all subclasses
|
||||
"InputTextMessageContent": {"disable_web_page_preview"}, # convenience arg, here for bw compat
|
||||
"RevenueWithdrawalState": {"type"}, # attributes common to all subclasses
|
||||
"TransactionPartner": {"type"}, # attributes common to all subclasses
|
||||
}
|
||||
|
||||
|
||||
|
@ -149,6 +151,8 @@ PTB_IGNORED_PARAMS = {
|
|||
r"ReactionType\w+": {"type"},
|
||||
r"BackgroundType\w+": {"type"},
|
||||
r"BackgroundFill\w+": {"type"},
|
||||
r"RevenueWithdrawalState\w+": {"type"},
|
||||
r"TransactionPartner\w+": {"type"},
|
||||
}
|
||||
|
||||
|
||||
|
|
580
tests/test_stars.py
Normal file
580
tests/test_stars.py
Normal file
|
@ -0,0 +1,580 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2024
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
import datetime
|
||||
from copy import deepcopy
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import (
|
||||
Dice,
|
||||
RevenueWithdrawalState,
|
||||
RevenueWithdrawalStateFailed,
|
||||
RevenueWithdrawalStatePending,
|
||||
RevenueWithdrawalStateSucceeded,
|
||||
StarTransaction,
|
||||
StarTransactions,
|
||||
TransactionPartner,
|
||||
TransactionPartnerFragment,
|
||||
TransactionPartnerOther,
|
||||
TransactionPartnerUser,
|
||||
User,
|
||||
)
|
||||
from telegram._utils.datetime import UTC, from_timestamp, to_timestamp
|
||||
from telegram.constants import RevenueWithdrawalStateType, TransactionPartnerType
|
||||
from tests.auxil.slots import mro_slots
|
||||
|
||||
|
||||
def withdrawal_state_succeeded():
|
||||
return RevenueWithdrawalStateSucceeded(
|
||||
date=datetime.datetime(2024, 1, 1, 0, 0, 0, 0, tzinfo=UTC),
|
||||
url="url",
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def withdrawal_state_failed():
|
||||
return RevenueWithdrawalStateFailed()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def withdrawal_state_pending():
|
||||
return RevenueWithdrawalStatePending()
|
||||
|
||||
|
||||
def transaction_partner_user():
|
||||
return TransactionPartnerUser(
|
||||
user=User(id=1, is_bot=False, first_name="first_name", username="username"),
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def transaction_partner_other():
|
||||
return TransactionPartnerOther()
|
||||
|
||||
|
||||
def transaction_partner_fragment():
|
||||
return TransactionPartnerFragment(
|
||||
withdrawal_state=withdrawal_state_succeeded(),
|
||||
)
|
||||
|
||||
|
||||
def star_transaction():
|
||||
return StarTransaction(
|
||||
id="1",
|
||||
amount=1,
|
||||
date=to_timestamp(datetime.datetime(2024, 1, 1, 0, 0, 0, 0, tzinfo=UTC)),
|
||||
source=transaction_partner_user(),
|
||||
receiver=transaction_partner_fragment(),
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def star_transactions():
|
||||
return StarTransactions(
|
||||
transactions=[
|
||||
star_transaction(),
|
||||
star_transaction(),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
scope="module",
|
||||
params=[
|
||||
TransactionPartner.FRAGMENT,
|
||||
TransactionPartner.OTHER,
|
||||
TransactionPartner.USER,
|
||||
],
|
||||
)
|
||||
def tp_scope_type(request):
|
||||
return request.param
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
scope="module",
|
||||
params=[
|
||||
TransactionPartnerFragment,
|
||||
TransactionPartnerOther,
|
||||
TransactionPartnerUser,
|
||||
],
|
||||
ids=[
|
||||
TransactionPartner.FRAGMENT,
|
||||
TransactionPartner.OTHER,
|
||||
TransactionPartner.USER,
|
||||
],
|
||||
)
|
||||
def tp_scope_class(request):
|
||||
return request.param
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
scope="module",
|
||||
params=[
|
||||
(TransactionPartnerFragment, TransactionPartner.FRAGMENT),
|
||||
(TransactionPartnerOther, TransactionPartner.OTHER),
|
||||
(TransactionPartnerUser, TransactionPartner.USER),
|
||||
],
|
||||
ids=[
|
||||
TransactionPartner.FRAGMENT,
|
||||
TransactionPartner.OTHER,
|
||||
TransactionPartner.USER,
|
||||
],
|
||||
)
|
||||
def tp_scope_class_and_type(request):
|
||||
return request.param
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def transaction_partner(tp_scope_class_and_type):
|
||||
# We use de_json here so that we don't have to worry about which class gets which arguments
|
||||
return tp_scope_class_and_type[0].de_json(
|
||||
{
|
||||
"type": tp_scope_class_and_type[1],
|
||||
"withdrawal_state": TestTransactionPartnerBase.withdrawal_state.to_dict(),
|
||||
"user": TestTransactionPartnerBase.user.to_dict(),
|
||||
},
|
||||
bot=None,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
scope="module",
|
||||
params=[
|
||||
RevenueWithdrawalState.FAILED,
|
||||
RevenueWithdrawalState.SUCCEEDED,
|
||||
RevenueWithdrawalState.PENDING,
|
||||
],
|
||||
)
|
||||
def rws_scope_type(request):
|
||||
return request.param
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
scope="module",
|
||||
params=[
|
||||
RevenueWithdrawalStateFailed,
|
||||
RevenueWithdrawalStateSucceeded,
|
||||
RevenueWithdrawalStatePending,
|
||||
],
|
||||
ids=[
|
||||
RevenueWithdrawalState.FAILED,
|
||||
RevenueWithdrawalState.SUCCEEDED,
|
||||
RevenueWithdrawalState.PENDING,
|
||||
],
|
||||
)
|
||||
def rws_scope_class(request):
|
||||
return request.param
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
scope="module",
|
||||
params=[
|
||||
(RevenueWithdrawalStateFailed, RevenueWithdrawalState.FAILED),
|
||||
(RevenueWithdrawalStateSucceeded, RevenueWithdrawalState.SUCCEEDED),
|
||||
(RevenueWithdrawalStatePending, RevenueWithdrawalState.PENDING),
|
||||
],
|
||||
ids=[
|
||||
RevenueWithdrawalState.FAILED,
|
||||
RevenueWithdrawalState.SUCCEEDED,
|
||||
RevenueWithdrawalState.PENDING,
|
||||
],
|
||||
)
|
||||
def rws_scope_class_and_type(request):
|
||||
return request.param
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def revenue_withdrawal_state(rws_scope_class_and_type):
|
||||
# We use de_json here so that we don't have to worry about which class gets which arguments
|
||||
return rws_scope_class_and_type[0].de_json(
|
||||
{
|
||||
"type": rws_scope_class_and_type[1],
|
||||
"date": to_timestamp(TestRevenueWithdrawalStateBase.date),
|
||||
"url": TestRevenueWithdrawalStateBase.url,
|
||||
},
|
||||
bot=None,
|
||||
)
|
||||
|
||||
|
||||
class TestStarTransactionBase:
|
||||
id = "2"
|
||||
amount = 2
|
||||
date = to_timestamp(datetime.datetime(2024, 1, 1, 0, 0, 0, 0, tzinfo=UTC))
|
||||
source = TransactionPartnerUser(
|
||||
user=User(
|
||||
id=2,
|
||||
is_bot=False,
|
||||
first_name="first_name",
|
||||
),
|
||||
)
|
||||
receiver = TransactionPartnerOther()
|
||||
|
||||
|
||||
class TestStarTransactionWithoutRequest(TestStarTransactionBase):
|
||||
def test_slot_behaviour(self):
|
||||
inst = star_transaction()
|
||||
for attr in inst.__slots__:
|
||||
assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
"id": self.id,
|
||||
"amount": self.amount,
|
||||
"date": self.date,
|
||||
"source": self.source.to_dict(),
|
||||
"receiver": self.receiver.to_dict(),
|
||||
}
|
||||
st = StarTransaction.de_json(json_dict, bot)
|
||||
st_none = StarTransaction.de_json(None, bot)
|
||||
assert st.id == self.id
|
||||
assert st.amount == self.amount
|
||||
assert st.date == from_timestamp(self.date)
|
||||
assert st.source == self.source
|
||||
assert st.receiver == self.receiver
|
||||
assert st_none is None
|
||||
|
||||
def test_de_json_star_transaction_localization(self, tz_bot, bot, raw_bot):
|
||||
json_dict = star_transaction().to_dict()
|
||||
st_raw = StarTransaction.de_json(json_dict, raw_bot)
|
||||
st_bot = StarTransaction.de_json(json_dict, bot)
|
||||
st_tz = StarTransaction.de_json(json_dict, tz_bot)
|
||||
|
||||
# comparing utcoffsets because comparing timezones is unpredicatable
|
||||
st_offset = st_tz.date.utcoffset()
|
||||
tz_bot_offset = tz_bot.defaults.tzinfo.utcoffset(st_tz.date.replace(tzinfo=None))
|
||||
|
||||
assert st_raw.date.tzinfo == UTC
|
||||
assert st_bot.date.tzinfo == UTC
|
||||
assert st_offset == tz_bot_offset
|
||||
|
||||
def test_to_dict(self):
|
||||
st = star_transaction()
|
||||
expected_dict = {
|
||||
"id": "1",
|
||||
"amount": 1,
|
||||
"date": st.date,
|
||||
"source": st.source.to_dict(),
|
||||
"receiver": st.receiver.to_dict(),
|
||||
}
|
||||
assert st.to_dict() == expected_dict
|
||||
|
||||
def test_equality(self):
|
||||
a = StarTransaction(
|
||||
id=self.id,
|
||||
amount=self.amount,
|
||||
date=self.date,
|
||||
source=self.source,
|
||||
receiver=self.receiver,
|
||||
)
|
||||
b = StarTransaction(
|
||||
id=self.id,
|
||||
amount=self.amount,
|
||||
date=None,
|
||||
source=self.source,
|
||||
receiver=self.receiver,
|
||||
)
|
||||
c = StarTransaction(
|
||||
id="3",
|
||||
amount=3,
|
||||
date=to_timestamp(datetime.datetime.utcnow()),
|
||||
source=TransactionPartnerUser(
|
||||
user=User(
|
||||
id=3,
|
||||
is_bot=False,
|
||||
first_name="first_name",
|
||||
),
|
||||
),
|
||||
receiver=TransactionPartnerOther(),
|
||||
)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
|
||||
class TestStarTransactionsBase:
|
||||
transactions = [star_transaction(), star_transaction()]
|
||||
|
||||
|
||||
class TestStarTransactionsWithoutRequest(TestStarTransactionsBase):
|
||||
def test_slot_behaviour(self, star_transactions):
|
||||
inst = star_transactions
|
||||
for attr in inst.__slots__:
|
||||
assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
"transactions": [t.to_dict() for t in self.transactions],
|
||||
}
|
||||
st = StarTransactions.de_json(json_dict, bot)
|
||||
st_none = StarTransactions.de_json(None, bot)
|
||||
assert st.transactions == tuple(self.transactions)
|
||||
assert st_none is None
|
||||
|
||||
def test_to_dict(self, star_transactions):
|
||||
expected_dict = {
|
||||
"transactions": [t.to_dict() for t in self.transactions],
|
||||
}
|
||||
assert star_transactions.to_dict() == expected_dict
|
||||
|
||||
def test_equality(self):
|
||||
a = StarTransactions(
|
||||
transactions=self.transactions,
|
||||
)
|
||||
b = StarTransactions(
|
||||
transactions=self.transactions,
|
||||
)
|
||||
c = StarTransactions(
|
||||
transactions=[star_transaction()],
|
||||
)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
|
||||
class TestTransactionPartnerBase:
|
||||
withdrawal_state = withdrawal_state_succeeded()
|
||||
user = transaction_partner_user().user
|
||||
|
||||
|
||||
class TestTransactionPartner(TestTransactionPartnerBase):
|
||||
def test_slot_behaviour(self, transaction_partner):
|
||||
inst = transaction_partner
|
||||
for attr in inst.__slots__:
|
||||
assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||
|
||||
def test_de_json(self, bot, tp_scope_class_and_type):
|
||||
cls = tp_scope_class_and_type[0]
|
||||
type_ = tp_scope_class_and_type[1]
|
||||
|
||||
json_dict = {
|
||||
"type": type_,
|
||||
"withdrawal_state": self.withdrawal_state.to_dict(),
|
||||
"user": self.user.to_dict(),
|
||||
}
|
||||
tp = TransactionPartner.de_json(json_dict, bot)
|
||||
assert set(tp.api_kwargs.keys()) == {"user", "withdrawal_state"} - set(cls.__slots__)
|
||||
|
||||
assert isinstance(tp, TransactionPartner)
|
||||
assert type(tp) is cls
|
||||
assert tp.type == type_
|
||||
if "withdrawal_state" in cls.__slots__:
|
||||
assert tp.withdrawal_state == self.withdrawal_state
|
||||
if "user" in cls.__slots__:
|
||||
assert tp.user == self.user
|
||||
|
||||
assert cls.de_json(None, bot) is None
|
||||
assert TransactionPartner.de_json({}, bot) is None
|
||||
|
||||
def test_de_json_invalid_type(self, bot):
|
||||
json_dict = {
|
||||
"type": "invalid",
|
||||
"withdrawal_state": self.withdrawal_state.to_dict(),
|
||||
"user": self.user.to_dict(),
|
||||
}
|
||||
tp = TransactionPartner.de_json(json_dict, bot)
|
||||
assert tp.api_kwargs == {
|
||||
"withdrawal_state": self.withdrawal_state.to_dict(),
|
||||
"user": self.user.to_dict(),
|
||||
}
|
||||
|
||||
assert type(tp) is TransactionPartner
|
||||
assert tp.type == "invalid"
|
||||
|
||||
def test_de_json_subclass(self, tp_scope_class, bot):
|
||||
"""This makes sure that e.g. TransactionPartnerUser(data) never returns a
|
||||
TransactionPartnerFragment instance."""
|
||||
json_dict = {
|
||||
"type": "invalid",
|
||||
"withdrawal_state": self.withdrawal_state.to_dict(),
|
||||
"user": self.user.to_dict(),
|
||||
}
|
||||
assert type(tp_scope_class.de_json(json_dict, bot)) is tp_scope_class
|
||||
|
||||
def test_to_dict(self, transaction_partner):
|
||||
tp_dict = transaction_partner.to_dict()
|
||||
|
||||
assert isinstance(tp_dict, dict)
|
||||
assert tp_dict["type"] == transaction_partner.type
|
||||
if hasattr(transaction_partner, "web_app"):
|
||||
assert tp_dict["user"] == transaction_partner.user.to_dict()
|
||||
if hasattr(transaction_partner, "withdrawal_state"):
|
||||
assert tp_dict["withdrawal_state"] == transaction_partner.withdrawal_state.to_dict()
|
||||
|
||||
def test_type_enum_conversion(self):
|
||||
assert type(TransactionPartner("other").type) is TransactionPartnerType
|
||||
assert TransactionPartner("unknown").type == "unknown"
|
||||
|
||||
def test_equality(self, transaction_partner, bot):
|
||||
a = TransactionPartner("base_type")
|
||||
b = TransactionPartner("base_type")
|
||||
c = transaction_partner
|
||||
d = deepcopy(transaction_partner)
|
||||
e = Dice(4, "emoji")
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
assert a != e
|
||||
assert hash(a) != hash(e)
|
||||
|
||||
assert c == d
|
||||
assert hash(c) == hash(d)
|
||||
|
||||
assert c != e
|
||||
assert hash(c) != hash(e)
|
||||
|
||||
if hasattr(c, "user"):
|
||||
json_dict = c.to_dict()
|
||||
json_dict["user"] = User(2, "something", True).to_dict()
|
||||
f = c.__class__.de_json(json_dict, bot)
|
||||
|
||||
assert c != f
|
||||
assert hash(c) != hash(f)
|
||||
|
||||
|
||||
class TestRevenueWithdrawalStateBase:
|
||||
date = datetime.datetime(2024, 1, 1, 0, 0, 0, 0, tzinfo=UTC)
|
||||
url = "url"
|
||||
|
||||
|
||||
class TestRevenueWithdrawalState(TestRevenueWithdrawalStateBase):
|
||||
def test_slot_behaviour(self, revenue_withdrawal_state):
|
||||
inst = revenue_withdrawal_state
|
||||
for attr in inst.__slots__:
|
||||
assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||
|
||||
def test_de_json(self, bot, rws_scope_class_and_type):
|
||||
cls = rws_scope_class_and_type[0]
|
||||
type_ = rws_scope_class_and_type[1]
|
||||
|
||||
json_dict = {
|
||||
"type": type_,
|
||||
"date": to_timestamp(self.date),
|
||||
"url": self.url,
|
||||
}
|
||||
rws = RevenueWithdrawalState.de_json(json_dict, bot)
|
||||
assert set(rws.api_kwargs.keys()) == {"date", "url"} - set(cls.__slots__)
|
||||
|
||||
assert isinstance(rws, RevenueWithdrawalState)
|
||||
assert type(rws) is cls
|
||||
assert rws.type == type_
|
||||
if "date" in cls.__slots__:
|
||||
assert rws.date == self.date
|
||||
if "url" in cls.__slots__:
|
||||
assert rws.url == self.url
|
||||
|
||||
assert cls.de_json(None, bot) is None
|
||||
assert RevenueWithdrawalState.de_json({}, bot) is None
|
||||
|
||||
def test_de_json_invalid_type(self, bot):
|
||||
json_dict = {
|
||||
"type": "invalid",
|
||||
"date": to_timestamp(self.date),
|
||||
"url": self.url,
|
||||
}
|
||||
rws = RevenueWithdrawalState.de_json(json_dict, bot)
|
||||
assert rws.api_kwargs == {
|
||||
"date": to_timestamp(self.date),
|
||||
"url": self.url,
|
||||
}
|
||||
|
||||
assert type(rws) is RevenueWithdrawalState
|
||||
assert rws.type == "invalid"
|
||||
|
||||
def test_de_json_subclass(self, rws_scope_class, bot):
|
||||
"""This makes sure that e.g. RevenueWithdrawalState(data) never returns a
|
||||
RevenueWithdrawalStateFailed instance."""
|
||||
json_dict = {
|
||||
"type": "invalid",
|
||||
"date": to_timestamp(self.date),
|
||||
"url": self.url,
|
||||
}
|
||||
assert type(rws_scope_class.de_json(json_dict, bot)) is rws_scope_class
|
||||
|
||||
def test_to_dict(self, revenue_withdrawal_state):
|
||||
rws_dict = revenue_withdrawal_state.to_dict()
|
||||
|
||||
assert isinstance(rws_dict, dict)
|
||||
assert rws_dict["type"] == revenue_withdrawal_state.type
|
||||
if hasattr(revenue_withdrawal_state, "date"):
|
||||
assert rws_dict["date"] == to_timestamp(revenue_withdrawal_state.date)
|
||||
if hasattr(revenue_withdrawal_state, "url"):
|
||||
assert rws_dict["url"] == revenue_withdrawal_state.url
|
||||
|
||||
def test_type_enum_conversion(self):
|
||||
assert type(RevenueWithdrawalState("failed").type) is RevenueWithdrawalStateType
|
||||
assert RevenueWithdrawalState("unknown").type == "unknown"
|
||||
|
||||
def test_equality(self, revenue_withdrawal_state, bot):
|
||||
a = RevenueWithdrawalState("base_type")
|
||||
b = RevenueWithdrawalState("base_type")
|
||||
c = revenue_withdrawal_state
|
||||
d = deepcopy(revenue_withdrawal_state)
|
||||
e = Dice(4, "emoji")
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
assert a != e
|
||||
assert hash(a) != hash(e)
|
||||
|
||||
assert c == d
|
||||
assert hash(c) == hash(d)
|
||||
|
||||
assert c != e
|
||||
assert hash(c) != hash(e)
|
||||
|
||||
if hasattr(c, "url"):
|
||||
json_dict = c.to_dict()
|
||||
json_dict["url"] = "something"
|
||||
f = c.__class__.de_json(json_dict, bot)
|
||||
|
||||
assert c == f
|
||||
assert hash(c) == hash(f)
|
||||
|
||||
if hasattr(c, "date"):
|
||||
json_dict = c.to_dict()
|
||||
json_dict["date"] = to_timestamp(datetime.datetime.utcnow())
|
||||
f = c.__class__.de_json(json_dict, bot)
|
||||
|
||||
assert c != f
|
||||
assert hash(c) != hash(f)
|
Loading…
Add table
Reference in a new issue