mirror of
https://github.com/TeamPGM/pyrogram.git
synced 2024-11-18 21:44:22 +00:00
Merge branch 'develop' into asyncio
# Conflicts: # pyrogram/client/client.py # pyrogram/client/ext/base_client.py # pyrogram/client/methods/bots/request_callback_answer.py # pyrogram/session/session.py
This commit is contained in:
commit
5f727cb5a2
@ -1,5 +1,5 @@
|
||||
## Include
|
||||
include COPYING COPYING.lesser NOTICE requirements.txt requirements_extras.txt
|
||||
include COPYING COPYING.lesser NOTICE requirements.txt
|
||||
recursive-include compiler *.py *.tl *.tsv *.txt
|
||||
|
||||
## Exclude
|
||||
|
25
README.rst
25
README.rst
@ -1,7 +1,7 @@
|
||||
|header|
|
||||
|
||||
Pyrogram |twitter|
|
||||
==================
|
||||
Pyrogram
|
||||
========
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -26,8 +26,8 @@ Features
|
||||
- **Easy to use**: You can easily install Pyrogram using pip and start building your app right away.
|
||||
- **High-level**: The low-level details of MTProto are abstracted and automatically handled.
|
||||
- **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C.
|
||||
- **Updated** to the latest Telegram API version, currently Layer 76 running on MTProto 2.0.
|
||||
- **Documented**: Pyrogram API methods are documented and resemble the Telegram Bot API.
|
||||
- **Updated** to the latest Telegram API version, currently Layer 79 on top of MTProto 2.0.
|
||||
- **Documented**: The Pyrogram API is well documented and resembles the Telegram Bot API.
|
||||
- **Full API**, allowing to execute any advanced action an official client is able to do, and more.
|
||||
|
||||
Requirements
|
||||
@ -54,7 +54,7 @@ Getting Started
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Pyrogram is brand new! **You are welcome to try it and help make it better** by either submitting pull
|
||||
Pyrogram is brand new, and **you are welcome to try it and help make it even better** by either submitting pull
|
||||
requests or reporting issues/bugs as well as suggesting best practices, ideas, enhancements on both code
|
||||
and documentation. Any help is appreciated!
|
||||
|
||||
@ -100,28 +100,25 @@ Copyright & License
|
||||
</a>
|
||||
<br><br>
|
||||
<a href="compiler/api/source/main_api.tl">
|
||||
<img src="https://media.pyrogram.ml/images/scheme.svg"
|
||||
alt="Scheme Layer 76">
|
||||
<img src="https://img.shields.io/badge/SCHEME-LAYER%2079-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30"
|
||||
alt="Scheme Layer">
|
||||
</a>
|
||||
<a href="https://github.com/pyrogram/tgcrypto">
|
||||
<img src="https://media.pyrogram.ml/images/tgcrypto.svg"
|
||||
<img src="https://img.shields.io/badge/TGCRYPTO-V1.0.4-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30"
|
||||
alt="TgCrypto">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
.. |twitter| image:: https://media.pyrogram.ml/images/twitter.svg
|
||||
:target: https://twitter.com/intent/tweet?text=Build%20custom%20Telegram%20applications%20with%20Pyrogram&url=https://github.com/pyrogram/pyrogram&hashtags=Telegram,MTProto,Python
|
||||
|
||||
.. |logo| image:: https://pyrogram.ml/images/logo.png
|
||||
:target: https://pyrogram.ml
|
||||
:alt: Pyrogram
|
||||
|
||||
.. |description| replace:: **Telegram MTProto API Client Library for Python**
|
||||
|
||||
.. |scheme| image:: https://www.pyrogram.ml/images/scheme.svg
|
||||
.. |scheme| image:: "https://img.shields.io/badge/SCHEME-LAYER%2079-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30"
|
||||
:target: compiler/api/source/main_api.tl
|
||||
:alt: Scheme Layer 76
|
||||
:alt: Scheme Layer
|
||||
|
||||
.. |tgcrypto| image:: https://www.pyrogram.ml/images/tgcrypto.svg
|
||||
.. |tgcrypto| image:: "https://img.shields.io/badge/TGCRYPTO-V1.0.4-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30"
|
||||
:target: https://github.com/pyrogram/tgcrypto
|
||||
:alt: TgCrypto
|
||||
|
@ -14,27 +14,31 @@ Log In
|
||||
|
||||
To automate the **Log In** process, pass your ``phone_number`` and ``password`` (if you have one) in the Client parameters.
|
||||
If you want to retrieve the phone code programmatically, pass a callback function in the ``phone_code`` field — this
|
||||
function must return the correct phone code as string (e.g., "12345") — otherwise, ignore this parameter, Pyrogram will
|
||||
ask you to input the phone code manually.
|
||||
function accepts a single positional argument (phone_number) and must return the correct phone code (e.g., "12345")
|
||||
— otherwise, ignore this parameter, Pyrogram will ask you to input the phone code manually.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
def phone_code_callback():
|
||||
def phone_code_callback(phone_number):
|
||||
code = ... # Get your code programmatically
|
||||
return code # Must be string, e.g., "12345"
|
||||
return code # e.g., "12345"
|
||||
|
||||
|
||||
app = Client(
|
||||
session_name="example",
|
||||
phone_number="39**********",
|
||||
phone_code=phone_code_callback,
|
||||
phone_code=phone_code_callback, # Note the missing parentheses
|
||||
password="password" # (if you have one)
|
||||
)
|
||||
|
||||
app.start()
|
||||
|
||||
print(app.get_me())
|
||||
|
||||
app.stop()
|
||||
|
||||
Sign Up
|
||||
@ -44,23 +48,27 @@ To automate the **Sign Up** process (i.e., automatically create a new Telegram a
|
||||
``first_name`` and ``last_name`` fields alongside the other parameters; they will be used to automatically create a new
|
||||
Telegram account in case the phone number you passed is not registered yet.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
def phone_code_callback():
|
||||
def phone_code_callback(phone_number):
|
||||
code = ... # Get your code programmatically
|
||||
return code # Must be string, e.g., "12345"
|
||||
return code # e.g., "12345"
|
||||
|
||||
|
||||
app = Client(
|
||||
session_name="example",
|
||||
phone_number="39**********",
|
||||
phone_code=phone_code_callback,
|
||||
phone_code=phone_code_callback, # Note the missing parentheses
|
||||
first_name="Pyrogram",
|
||||
last_name="" # Can be an empty string
|
||||
)
|
||||
|
||||
app.start()
|
||||
|
||||
print(app.get_me())
|
||||
|
||||
app.stop()
|
@ -31,7 +31,7 @@ __copyright__ = "Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance
|
||||
"e" if sys.getfilesystemencoding() != "utf-8" else "\xe8"
|
||||
)
|
||||
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
|
||||
__version__ = "0.7.5.dev2"
|
||||
__version__ = "0.7.5.dev3"
|
||||
|
||||
from .api.errors import Error
|
||||
from .client.types import (
|
||||
|
@ -50,9 +50,6 @@ from .ext import BaseClient, Syncer, utils
|
||||
from .handlers import DisconnectHandler
|
||||
from .methods import Methods
|
||||
|
||||
# Custom format for nice looking log lines
|
||||
LOG_FORMAT = "[%(asctime)s.%(msecs)03d] %(filename)s:%(lineno)s %(levelname)s: %(message)s"
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -76,6 +73,26 @@ class Client(Methods, BaseClient):
|
||||
The *api_hash* part of your Telegram API Key, as string. E.g.: "0123456789abcdef0123456789abcdef"
|
||||
This is an alternative way to pass it if you don't want to use the *config.ini* file.
|
||||
|
||||
app_version (``str``, *optional*):
|
||||
Application version. Defaults to "Pyrogram \U0001f525 vX.Y.Z"
|
||||
This is an alternative way to set it if you don't want to use the *config.ini* file.
|
||||
|
||||
device_model (``str``, *optional*):
|
||||
Device model. Defaults to *platform.python_implementation() + " " + platform.python_version()*
|
||||
This is an alternative way to set it if you don't want to use the *config.ini* file.
|
||||
|
||||
system_version (``str``, *optional*):
|
||||
Operating System version. Defaults to *platform.system() + " " + platform.release()*
|
||||
This is an alternative way to set it if you don't want to use the *config.ini* file.
|
||||
|
||||
system_lang_code (``str``, *optional*):
|
||||
Code of the language used on the system, in ISO 639-1 standard. Defaults to "en".
|
||||
This is an alternative way to set it if you don't want to use the *config.ini* file.
|
||||
|
||||
lang_code (``str``, *optional*):
|
||||
Code of the language used on the client, in ISO 639-1 standard. Defaults to "en".
|
||||
This is an alternative way to set it if you don't want to use the *config.ini* file.
|
||||
|
||||
proxy (``dict``, *optional*):
|
||||
Your SOCKS5 Proxy settings as dict,
|
||||
e.g.: *dict(hostname="11.22.33.44", port=1080, username="user", password="pass")*.
|
||||
@ -92,8 +109,8 @@ class Client(Methods, BaseClient):
|
||||
entering it manually. Only applicable for new sessions.
|
||||
|
||||
phone_code (``str`` | ``callable``, *optional*):
|
||||
Pass the phone code as string (for test numbers only), or pass a callback function
|
||||
which must return the correct phone code as string (e.g., "12345").
|
||||
Pass the phone code as string (for test numbers only), or pass a callback function which accepts
|
||||
a single positional argument *(phone_number)* and must return the correct phone code (e.g., "12345").
|
||||
Only applicable for new sessions.
|
||||
|
||||
password (``str``, *optional*):
|
||||
@ -128,6 +145,11 @@ class Client(Methods, BaseClient):
|
||||
session_name: str,
|
||||
api_id: int or str = None,
|
||||
api_hash: str = None,
|
||||
app_version: str = None,
|
||||
device_model: str = None,
|
||||
system_version: str = None,
|
||||
system_lang_code: str = None,
|
||||
lang_code: str = None,
|
||||
proxy: dict = None,
|
||||
test_mode: bool = False,
|
||||
phone_number: str = None,
|
||||
@ -144,6 +166,11 @@ class Client(Methods, BaseClient):
|
||||
self.session_name = session_name
|
||||
self.api_id = int(api_id) if api_id else None
|
||||
self.api_hash = api_hash
|
||||
self.app_version = app_version
|
||||
self.device_model = device_model
|
||||
self.system_version = system_version
|
||||
self.system_lang_code = system_lang_code
|
||||
self.lang_code = lang_code
|
||||
# TODO: Make code consistent, use underscore for private/protected fields
|
||||
self._proxy = proxy
|
||||
self.test_mode = test_mode
|
||||
@ -186,12 +213,9 @@ class Client(Methods, BaseClient):
|
||||
await self.load_session()
|
||||
|
||||
self.session = Session(
|
||||
self,
|
||||
self.dc_id,
|
||||
self.test_mode,
|
||||
self._proxy,
|
||||
self.auth_key,
|
||||
self.api_id,
|
||||
client=self
|
||||
self.auth_key
|
||||
)
|
||||
|
||||
await self.session.start()
|
||||
@ -274,6 +298,7 @@ class Client(Methods, BaseClient):
|
||||
Iterable containing signals the signal handler will listen to.
|
||||
Defaults to (SIGINT, SIGTERM, SIGABRT).
|
||||
"""
|
||||
|
||||
def signal_handler(*args):
|
||||
log.info("Stop signal received ({}). Exiting...".format(args[0]))
|
||||
self.is_idle = False
|
||||
@ -368,12 +393,9 @@ class Client(Methods, BaseClient):
|
||||
self.auth_key = await Auth(self.dc_id, self.test_mode, self._proxy).create()
|
||||
|
||||
self.session = Session(
|
||||
self,
|
||||
self.dc_id,
|
||||
self.test_mode,
|
||||
self._proxy,
|
||||
self.auth_key,
|
||||
self.api_id,
|
||||
client=self
|
||||
self.auth_key
|
||||
)
|
||||
|
||||
await self.session.start()
|
||||
@ -416,12 +438,9 @@ class Client(Methods, BaseClient):
|
||||
self.auth_key = await Auth(self.dc_id, self.test_mode, self._proxy).create()
|
||||
|
||||
self.session = Session(
|
||||
self,
|
||||
self.dc_id,
|
||||
self.test_mode,
|
||||
self._proxy,
|
||||
self.auth_key,
|
||||
self.api_id,
|
||||
client=self
|
||||
self.auth_key
|
||||
)
|
||||
await self.session.start()
|
||||
|
||||
@ -465,7 +484,7 @@ class Client(Methods, BaseClient):
|
||||
self.phone_code = (
|
||||
input("Enter phone code: ") if self.phone_code is None
|
||||
else self.phone_code if type(self.phone_code) is str
|
||||
else str(self.phone_code())
|
||||
else str(self.phone_code(self.phone_number))
|
||||
)
|
||||
|
||||
try:
|
||||
@ -807,7 +826,7 @@ class Client(Methods, BaseClient):
|
||||
|
||||
log.info("UpdatesWorkerTask stopped")
|
||||
|
||||
async def send(self, data: Object):
|
||||
async def send(self, data: Object, retries: int = Session.MAX_RETRIES, timeout: float = Session.WAIT_TIMEOUT):
|
||||
"""Use this method to send Raw Function queries.
|
||||
|
||||
This method makes possible to manually call every single Telegram API method in a low-level manner.
|
||||
@ -818,13 +837,19 @@ class Client(Methods, BaseClient):
|
||||
data (``Object``):
|
||||
The API Scheme function filled with proper arguments.
|
||||
|
||||
retries (``int``):
|
||||
Number of retries.
|
||||
|
||||
timeout (``float``):
|
||||
Timeout in seconds.
|
||||
|
||||
Raises:
|
||||
:class:`Error <pyrogram.Error>`
|
||||
"""
|
||||
if not self.is_started:
|
||||
raise ConnectionError("Client has not been started")
|
||||
|
||||
r = await self.session.send(data)
|
||||
r = await self.session.send(data, retries, timeout)
|
||||
|
||||
self.fetch_peers(getattr(r, "users", []))
|
||||
self.fetch_peers(getattr(r, "chats", []))
|
||||
@ -847,6 +872,31 @@ class Client(Methods, BaseClient):
|
||||
"More info: https://docs.pyrogram.ml/start/ProjectSetup#configuration"
|
||||
)
|
||||
|
||||
for option in {"app_version", "device_model", "system_version", "system_lang_code", "lang_code"}:
|
||||
if getattr(self, option):
|
||||
pass
|
||||
else:
|
||||
setattr(self, option, Client.APP_VERSION)
|
||||
|
||||
if parser.has_section("pyrogram"):
|
||||
setattr(self, option, parser.get(
|
||||
"pyrogram",
|
||||
option,
|
||||
fallback=getattr(Client, option.upper())
|
||||
))
|
||||
|
||||
if self.lang_code:
|
||||
pass
|
||||
else:
|
||||
self.lang_code = Client.LANG_CODE
|
||||
|
||||
if parser.has_section("pyrogram"):
|
||||
self.lang_code = parser.get(
|
||||
"pyrogram",
|
||||
"lang_code",
|
||||
fallback=Client.LANG_CODE
|
||||
)
|
||||
|
||||
if self._proxy:
|
||||
self._proxy["enabled"] = True
|
||||
else:
|
||||
@ -1017,7 +1067,7 @@ class Client(Methods, BaseClient):
|
||||
file_id = file_id or self.rnd_id()
|
||||
md5_sum = md5() if not is_big and not is_missing_part else None
|
||||
|
||||
session = Session(self.dc_id, self.test_mode, self._proxy, self.auth_key, self.api_id)
|
||||
session = Session(self, self.dc_id, self.auth_key, is_media=True)
|
||||
await session.start()
|
||||
|
||||
try:
|
||||
@ -1101,11 +1151,10 @@ class Client(Methods, BaseClient):
|
||||
)
|
||||
|
||||
session = Session(
|
||||
self,
|
||||
dc_id,
|
||||
self.test_mode,
|
||||
self._proxy,
|
||||
await Auth(dc_id, self.test_mode, self._proxy).create(),
|
||||
self.api_id
|
||||
is_media=True
|
||||
)
|
||||
|
||||
await session.start()
|
||||
@ -1120,11 +1169,10 @@ class Client(Methods, BaseClient):
|
||||
)
|
||||
else:
|
||||
session = Session(
|
||||
self,
|
||||
dc_id,
|
||||
self.test_mode,
|
||||
self._proxy,
|
||||
self.auth_key,
|
||||
self.api_id
|
||||
is_media=True
|
||||
)
|
||||
|
||||
await session.start()
|
||||
@ -1190,11 +1238,10 @@ class Client(Methods, BaseClient):
|
||||
|
||||
if cdn_session is None:
|
||||
cdn_session = Session(
|
||||
self,
|
||||
r.dc_id,
|
||||
self.test_mode,
|
||||
self._proxy,
|
||||
await Auth(r.dc_id, self.test_mode, self._proxy).create(),
|
||||
self.api_id,
|
||||
is_media=True,
|
||||
is_cdn=True
|
||||
)
|
||||
|
||||
|
@ -17,14 +17,32 @@
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import asyncio
|
||||
import platform
|
||||
import re
|
||||
|
||||
from pyrogram import __version__
|
||||
from ..style import Markdown, HTML
|
||||
from ...api.core import Object
|
||||
from ...session import Session
|
||||
from ...session.internals import MsgId
|
||||
|
||||
|
||||
class BaseClient:
|
||||
APP_VERSION = "Pyrogram \U0001f525 {}".format(__version__)
|
||||
|
||||
DEVICE_MODEL = "{} {}".format(
|
||||
platform.python_implementation(),
|
||||
platform.python_version()
|
||||
)
|
||||
|
||||
SYSTEM_VERSION = "{} {}".format(
|
||||
platform.system(),
|
||||
platform.release()
|
||||
)
|
||||
|
||||
SYSTEM_LANG_CODE = "en"
|
||||
LANG_CODE = "en"
|
||||
|
||||
INVITE_LINK_RE = re.compile(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/joinchat/)([\w-]+)$")
|
||||
BOT_TOKEN_RE = re.compile(r"^\d+:[\w-]+$")
|
||||
DIALOGS_AT_ONCE = 100
|
||||
@ -76,7 +94,7 @@ class BaseClient:
|
||||
|
||||
self.disconnect_handler = None
|
||||
|
||||
def send(self, data: Object):
|
||||
def send(self, data: Object, retries: int = Session.MAX_RETRIES, timeout: float = Session.WAIT_TIMEOUT):
|
||||
pass
|
||||
|
||||
def resolve_peer(self, peer_id: int or str):
|
||||
|
@ -25,9 +25,8 @@ class RequestCallbackAnswer(BaseClient):
|
||||
chat_id: int or str,
|
||||
message_id: int,
|
||||
callback_data: str):
|
||||
"""Use this method to request a callback answer from bots. This is the equivalent of clicking an inline button
|
||||
containing callback data. The answer contains info useful for clients to display a notification at the top of
|
||||
the chat screen or as an alert.
|
||||
"""Use this method to request a callback answer from bots. This is the equivalent of clicking an
|
||||
inline button containing callback data.
|
||||
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
@ -41,11 +40,21 @@ class RequestCallbackAnswer(BaseClient):
|
||||
|
||||
callback_data (``str``):
|
||||
Callback data associated with the inline button you want to get the answer from.
|
||||
|
||||
Returns:
|
||||
The answer containing info useful for clients to display a notification at the top of the chat screen
|
||||
or as an alert.
|
||||
|
||||
Raises:
|
||||
:class:`Error <pyrogram.Error>`
|
||||
``TimeoutError``: If the bot fails to answer within 10 seconds
|
||||
"""
|
||||
return await self.send(
|
||||
functions.messages.GetBotCallbackAnswer(
|
||||
peer=self.resolve_peer(chat_id),
|
||||
msg_id=message_id,
|
||||
data=callback_data.encode()
|
||||
)
|
||||
),
|
||||
retries=0,
|
||||
timeout=10
|
||||
)
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import platform
|
||||
from datetime import datetime, timedelta
|
||||
from hashlib import sha1
|
||||
from io import BytesIO
|
||||
@ -43,19 +42,8 @@ class Result:
|
||||
|
||||
|
||||
class Session:
|
||||
VERSION = __version__
|
||||
APP_VERSION = "Pyrogram \U0001f525 {}".format(VERSION)
|
||||
|
||||
DEVICE_MODEL = "{} {}".format(
|
||||
platform.python_implementation(),
|
||||
platform.python_version()
|
||||
)
|
||||
|
||||
SYSTEM_VERSION = "{} {}".format(
|
||||
platform.system(),
|
||||
platform.release()
|
||||
)
|
||||
|
||||
INITIAL_SALT = 0x616e67656c696361
|
||||
NET_WORKERS = 1
|
||||
WAIT_TIMEOUT = 15
|
||||
MAX_RETRIES = 5
|
||||
ACKS_THRESHOLD = 8
|
||||
@ -78,28 +66,24 @@ class Session:
|
||||
}
|
||||
|
||||
def __init__(self,
|
||||
client: pyrogram,
|
||||
dc_id: int,
|
||||
test_mode: bool,
|
||||
proxy: dict,
|
||||
auth_key: bytes,
|
||||
api_id: int,
|
||||
is_cdn: bool = False,
|
||||
client: pyrogram = None):
|
||||
is_media: bool = False,
|
||||
is_cdn: bool = False):
|
||||
if not Session.notice_displayed:
|
||||
print("Pyrogram v{}, {}".format(__version__, __copyright__))
|
||||
print("Licensed under the terms of the " + __license__, end="\n\n")
|
||||
Session.notice_displayed = True
|
||||
|
||||
self.dc_id = dc_id
|
||||
self.test_mode = test_mode
|
||||
self.proxy = proxy
|
||||
self.api_id = api_id
|
||||
self.is_cdn = is_cdn
|
||||
self.client = client
|
||||
self.dc_id = dc_id
|
||||
self.auth_key = auth_key
|
||||
self.is_media = is_media
|
||||
self.is_cdn = is_cdn
|
||||
|
||||
self.connection = None
|
||||
|
||||
self.auth_key = auth_key
|
||||
self.auth_key_id = sha1(auth_key).digest()[-8:]
|
||||
|
||||
self.session_id = Long(MsgId())
|
||||
@ -125,7 +109,7 @@ class Session:
|
||||
|
||||
async def start(self):
|
||||
while True:
|
||||
self.connection = Connection(DataCenter(self.dc_id, self.test_mode), self.proxy)
|
||||
self.connection = Connection(DataCenter(self.dc_id, self.client.test_mode), self.client.proxy)
|
||||
|
||||
try:
|
||||
await self.connection.connect()
|
||||
@ -144,12 +128,14 @@ class Session:
|
||||
functions.InvokeWithLayer(
|
||||
layer,
|
||||
functions.InitConnection(
|
||||
self.api_id,
|
||||
self.DEVICE_MODEL,
|
||||
self.SYSTEM_VERSION,
|
||||
self.APP_VERSION,
|
||||
"en", "", "en",
|
||||
functions.help.GetConfig(),
|
||||
api_id=self.client.api_id,
|
||||
app_version=self.client.app_version,
|
||||
device_model=self.client.device_model,
|
||||
system_version=self.client.system_version,
|
||||
system_lang_code=self.client.system_lang_code,
|
||||
lang_code=self.client.lang_code,
|
||||
lang_pack="",
|
||||
query=functions.help.GetConfig(),
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -349,7 +335,7 @@ class Session:
|
||||
|
||||
log.info("RecvTask stopped")
|
||||
|
||||
async def _send(self, data: Object, wait_response: bool = True):
|
||||
async def _send(self, data: Object, wait_response: bool = True, timeout: float = WAIT_TIMEOUT):
|
||||
message = self.msg_factory(data)
|
||||
msg_id = message.msg_id
|
||||
|
||||
@ -372,7 +358,7 @@ class Session:
|
||||
|
||||
if wait_response:
|
||||
try:
|
||||
await asyncio.wait_for(self.results[msg_id].event.wait(), self.WAIT_TIMEOUT)
|
||||
await asyncio.wait_for(self.results[msg_id].event.wait(), timeout)
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
|
||||
@ -390,14 +376,14 @@ class Session:
|
||||
else:
|
||||
return result
|
||||
|
||||
async def send(self, data: Object, retries: int = MAX_RETRIES):
|
||||
async def send(self, data: Object, retries: int = MAX_RETRIES, timeout: float = WAIT_TIMEOUT):
|
||||
try:
|
||||
await asyncio.wait_for(self.is_connected.wait(), self.WAIT_TIMEOUT)
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
|
||||
try:
|
||||
return await self._send(data)
|
||||
return await self._send(data, timeout=timeout)
|
||||
except (OSError, TimeoutError, InternalServerError) as e:
|
||||
if retries == 0:
|
||||
raise e from None
|
||||
@ -408,7 +394,7 @@ class Session:
|
||||
datetime.now(), type(data)))
|
||||
|
||||
await asyncio.sleep(0.5)
|
||||
return await self.send(data, retries - 1)
|
||||
return await self.send(data, retries - 1, timeout)
|
||||
|
||||
# class Result:
|
||||
# def __init__(self):
|
||||
@ -807,4 +793,4 @@ class Session:
|
||||
# datetime.now(), type(data)))
|
||||
#
|
||||
# time.sleep(0.5)
|
||||
# return self.send(data, retries - 1)
|
||||
# return self.send(data, retries - 1, timeout)
|
||||
|
Loading…
Reference in New Issue
Block a user