diff --git a/optional-requirements.txt b/optional-requirements.txt index dabb83a5..aad46334 100644 --- a/optional-requirements.txt +++ b/optional-requirements.txt @@ -1,5 +1,4 @@ cryptg -pysocks python-socks[asyncio] hachoir pillow diff --git a/readthedocs/basic/signing-in.rst b/readthedocs/basic/signing-in.rst index 9fb14853..98a0ff22 100644 --- a/readthedocs/basic/signing-in.rst +++ b/readthedocs/basic/signing-in.rst @@ -117,43 +117,14 @@ Signing In behind a Proxy ========================= If you need to use a proxy to access Telegram, -you will need to either: - -* For Python >= 3.6 : `install python-socks[asyncio]`__ -* For Python <= 3.5 : `install PySocks`__ - -and then change +you will need to `install python-socks[asyncio]`__ +and then pass a proxy argument to the client: .. code-block:: python - TelegramClient('anon', api_id, api_hash) + TelegramClient('anon', api_id, api_hash, proxy=...) -with - -.. code-block:: python - - TelegramClient('anon', api_id, api_hash, proxy=("socks5", '127.0.0.1', 4444)) - -(of course, replacing the protocol, IP and port with the protocol, IP and port of the proxy). - -The ``proxy=`` argument should be a dict (or tuple, for backwards compatibility), -consisting of parameters described `in PySocks usage`__. - -The allowed values for the argument ``proxy_type`` are: - -* For Python <= 3.5: - * ``socks.SOCKS5`` or ``'socks5'`` - * ``socks.SOCKS4`` or ``'socks4'`` - * ``socks.HTTP`` or ``'http'`` - -* For Python >= 3.6: - * All of the above - * ``python_socks.ProxyType.SOCKS5`` - * ``python_socks.ProxyType.SOCKS4`` - * ``python_socks.ProxyType.HTTP`` - - -Example: +The ``proxy=`` argument should be a dict with the following properties: .. code-block:: python @@ -166,16 +137,9 @@ Example: 'rdns': True # (optional) whether to use remote or local resolve, default remote } -For backwards compatibility with ``PySocks`` the following format -is possible (but discouraged): - -.. code-block:: python - - proxy = (socks.SOCKS5, '1.1.1.1', 5555, True, 'foo', 'bar') +A warning will be emitted if the proxy is specified but ``python-socks`` is not installed. .. __: https://github.com/romis2012/python-socks#installation -.. __: https://github.com/Anorov/PySocks#installation -.. __: https://github.com/Anorov/PySocks#usage-1 Using MTProto Proxies diff --git a/telethon/client/telegrambaseclient.py b/telethon/client/telegrambaseclient.py index 1f2f98a0..9b449571 100644 --- a/telethon/client/telegrambaseclient.py +++ b/telethon/client/telegrambaseclient.py @@ -9,6 +9,7 @@ import time import typing import datetime import pathlib +import warnings from .. import utils, version, helpers, __name__ as __base_name__ from ..crypto import rsa @@ -19,6 +20,11 @@ from ..tl import functions, types from ..tl.alltlobjects import LAYER from .._updates import MessageBox, EntityCache as MbEntityCache, SessionState, ChannelState, Entity, EntityType +try: + import python_socks +except ImportError: + python_socks = None + DEFAULT_DC_ID = 2 DEFAULT_IPV4_IP = '149.154.167.51' DEFAULT_IPV6_IP = '2001:67c:4e8:f002::a' @@ -104,12 +110,12 @@ class TelegramBaseClient(abc.ABC): By default this is `False` as IPv6 support is not too widespread yet. - proxy (`tuple` | `list` | `dict`, optional): + proxy (`dict`, optional): An iterable consisting of the proxy info. If `connection` is one of `MTProxy`, then it should contain MTProxy credentials: - ``('hostname', port, 'secret')``. Otherwise, it's meant to store - function parameters for PySocks, like ``(type, 'hostname', port)``. - See https://github.com/Anorov/PySocks#usage-1 for more. + ``hostname, port, secret``. Otherwise, it's meant to store + function parameters for PySocks, like ``type, hostname, port``. + See https://github.com/romis2012/python-socks for more. local_addr (`str` | `tuple`, optional): Local host address (and port, optionally) used to bind the socket to locally. @@ -340,6 +346,9 @@ class TelegramBaseClient(abc.ABC): self._timeout = timeout self._auto_reconnect = auto_reconnect + if proxy and not python_socks: + warnings.warn('proxy argument will be ignored because python-socks is not installed') + assert isinstance(connection, type) self._connection = connection init_proxy = None if not issubclass(connection, TcpMTProxy) else \ diff --git a/telethon_examples/interactive_telegram_client.py b/telethon_examples/interactive_telegram_client.py index a132bdf0..c391a2d6 100644 --- a/telethon_examples/interactive_telegram_client.py +++ b/telethon_examples/interactive_telegram_client.py @@ -114,9 +114,6 @@ class InteractiveTelegramClient(TelegramClient): try: await self.connect() except IOError: - # We handle IOError and not ConnectionError because - # PySocks' errors do not subclass ConnectionError - # (so this will work with and without proxies). print('Initial connection failed. Retrying...') await self.connect() diff --git a/telethon_examples/print_messages.py b/telethon_examples/print_messages.py index 21aafc59..b5edb460 100644 --- a/telethon_examples/print_messages.py +++ b/telethon_examples/print_messages.py @@ -22,7 +22,7 @@ def get_env(name, message, cast=str): session = os.environ.get('TG_SESSION', 'printer') api_id = get_env('TG_API_ID', 'Enter your API ID: ', int) api_hash = get_env('TG_API_HASH', 'Enter your API hash: ') -proxy = None # https://github.com/Anorov/PySocks +proxy = None # https://github.com/romis2012/python-socks # Create and start the client so we can make requests (we don't here) client = TelegramClient(session, api_id, api_hash, proxy=proxy).start() diff --git a/telethon_examples/print_updates.py b/telethon_examples/print_updates.py index 48ade9d4..92bf869d 100755 --- a/telethon_examples/print_updates.py +++ b/telethon_examples/print_updates.py @@ -27,7 +27,7 @@ def get_env(name, message, cast=str): session = os.environ.get('TG_SESSION', 'printer') api_id = get_env('TG_API_ID', 'Enter your API ID: ', int) api_hash = get_env('TG_API_HASH', 'Enter your API hash: ') -proxy = None # https://github.com/Anorov/PySocks +proxy = None # https://github.com/romis2012/python-socks # This is our update handler. It is called when a new update arrives.