U
    hw                     @   s:  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	ddl
mZmZmZ ddlmZ ddlmZ ddlmZmZmZmZ ddlmZmZmZ ddlmZmZ dd	lm Z  dd
l!m"Z"m#Z$m%Z%m&Z&m'Z'm(Z( dZ)dZ*dZ+dZ,ej-rddl.m/Z/ e0eZ1dZ2G dd dZ3G dd de j4Z5dS )    N   )versionhelpers__name__)rsa)markdown)MTProtoSender
ConnectionConnectionTcpFull
TcpMTProxy)SessionSQLiteSessionMemorySession)	functionstypes)LAYER)
MessageBoxEntityCacheSessionStateChannelStateEntity
EntityTypez149.154.167.51z2001:67c:4e8:f002::ai     )TelegramClient<   c                   @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )_ExportStatec                 C   s   d| _ d| _d| _d S )Nr   F)_n_zero_ts
_connectedself r!   F/tmp/pip-unpacked-wheel-c81u5j2r/telethon/client/telegrambaseclient.py__init__%   s    z_ExportState.__init__c                 C   s   |  j d7  _ d| _d S )Nr   T)r   r   r   r!   r!   r"   
add_borrow,   s    z_ExportState.add_borrowc                 C   s8   |  j d8  _ | j dks td| j dkr4t | _d S )Nr   r   z)returned sender more than it was borrowed)r   AssertionErrortimer   r   r!   r!   r"   
add_return0   s    
z_ExportState.add_returnc                 C   s"   | j dko | jo t | j tkS )Nr   )r   r   r&   r   _DISCONNECT_EXPORTED_AFTERr   r!   r!   r"   should_disconnect6   s
    
z_ExportState.should_disconnectc                 C   s   | j  S N)r   r   r!   r!   r"   need_connect;   s    z_ExportState.need_connectc                 C   s   |   stdd| _d S )Nz+marked as disconnected when it was borrowedF)r)   r%   r   r   r!   r!   r"   mark_disconnected>   s    z_ExportState.mark_disconnectedN)	r   
__module____qualname__r#   r$   r'   r)   r+   r,   r!   r!   r!   r"   r   $   s   r   c                   @   s  e Zd ZdZejZdZdZeddddddddddddddd	d	ddddd
ddde	e
deejeef eje
ef e	e	e	e	eee	ee
e
e
e
e
ejeje
ejf eee	dddZedejdddZedejdddZedd Zejdd ZdddddZdedddZdddd Zdejeef d!d"d#Zddd$d%Zddd&d'Z ddd(d)Z!ddd*d+Z"ddd,d-Z#d@ddd.d/Z$ddd0d1Z%ddd2d3Z&ddd4d5Z'ddd6d7Z(ddd8d9Z)e*j+dAddd:d;Z,e*j+ddd<d=Z-e*j+ddd>d?Z.dS )BTelegramBaseClienta.  
    This is the abstract base class for the client. It defines some
    basic stuff like connecting, switching data center, etc, and
    leaves the `__call__` unimplemented.

    Arguments
        session (`str` | `telethon.sessions.abstract.Session`, `None`):
            The file name of the session file to be used if a string is
            given (it may be a full path), or the Session instance to be
            used otherwise. If it's `None`, the session will not be saved,
            and you should call :meth:`.log_out()` when you're done.

            Note that if you pass a string it will be a file in the current
            working directory, although you can also pass absolute paths.

            The session file contains enough information for you to login
            without re-sending the code, so if you have to enter the code
            more than once, maybe you're changing the working directory,
            renaming or removing the file, or using random names.

        api_id (`int` | `str`):
            The API ID you obtained from https://my.telegram.org.

        api_hash (`str`):
            The API hash you obtained from https://my.telegram.org.

        connection (`telethon.network.connection.common.Connection`, optional):
            The connection instance to be used when creating a new connection
            to the servers. It **must** be a type.

            Defaults to `telethon.network.connection.tcpfull.ConnectionTcpFull`.

        use_ipv6 (`bool`, optional):
            Whether to connect to the servers through IPv6 or not.
            By default this is `False` as IPv6 support is not
            too widespread yet.

        proxy (`tuple` | `list` | `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.

        local_addr (`str` | `tuple`, optional):
            Local host address (and port, optionally) used to bind the socket to locally.
            You only need to use this if you have multiple network cards and
            want to use a specific one.

        timeout (`int` | `float`, optional):
            The timeout in seconds to be used when connecting.
            This is **not** the timeout to be used when ``await``'ing for
            invoked requests, and you should use ``asyncio.wait`` or
            ``asyncio.wait_for`` for that.

        request_retries (`int` | `None`, optional):
            How many times a request should be retried. Request are retried
            when Telegram is having internal issues (due to either
            ``errors.ServerError`` or ``errors.RpcCallFailError``),
            when there is a ``errors.FloodWaitError`` less than
            `flood_sleep_threshold`, or when there's a migrate error.

            May take a negative or `None` value for infinite retries, but
            this is not recommended, since some requests can always trigger
            a call fail (such as searching for messages).

        connection_retries (`int` | `None`, optional):
            How many times the reconnection should retry, either on the
            initial connection or when Telegram disconnects us. May be
            set to a negative or `None` value for infinite retries, but
            this is not recommended, since the program can get stuck in an
            infinite loop.

        retry_delay (`int` | `float`, optional):
            The delay in seconds to sleep between automatic reconnections.

        auto_reconnect (`bool`, optional):
            Whether reconnection should be retried `connection_retries`
            times automatically if Telegram disconnects us or not.

        sequential_updates (`bool`, optional):
            By default every incoming update will create a new task, so
            you can handle several updates in parallel. Some scripts need
            the order in which updates are processed to be sequential, and
            this setting allows them to do so.

            If set to `True`, incoming updates will be put in a queue
            and processed sequentially. This means your event handlers
            should *not* perform long-running operations since new
            updates are put inside of an unbounded queue.

        flood_sleep_threshold (`int` | `float`, optional):
            The threshold below which the library should automatically
            sleep on flood wait and slow mode wait errors (inclusive). For instance, if a
            ``FloodWaitError`` for 17s occurs and `flood_sleep_threshold`
            is 20s, the library will ``sleep`` automatically. If the error
            was for 21s, it would ``raise FloodWaitError`` instead. Values
            larger than a day (like ``float('inf')``) will be changed to a day.

        raise_last_call_error (`bool`, optional):
            When API calls fail in a way that causes Telethon to retry
            automatically, should the RPC error of the last attempt be raised
            instead of a generic ValueError. This is mostly useful for
            detecting when Telegram has internal issues.

        device_model (`str`, optional):
            "Device model" to be sent when creating the initial connection.
            Defaults to 'PC (n)bit' derived from ``platform.uname().machine``, or its direct value if unknown.

        system_version (`str`, optional):
            "System version" to be sent when creating the initial connection.
            Defaults to ``platform.uname().release`` stripped of everything ahead of -.

        app_version (`str`, optional):
            "App version" to be sent when creating the initial connection.
            Defaults to `telethon.version.__version__`.

        lang_code (`str`, optional):
            "Language code" to be sent when creating the initial connection.
            Defaults to ``'en'``.

        system_lang_code (`str`, optional):
            "System lang code"  to be sent when creating the initial connection.
            Defaults to `lang_code`.

        loop (`asyncio.AbstractEventLoop`, optional):
            Asyncio event loop to use. Defaults to `asyncio.get_running_loop()`.
            This argument is ignored.

        base_logger (`str` | `logging.Logger`, optional):
            Base logger name or instance to use.
            If a `str` is given, it'll be passed to `logging.getLogger()`. If a
            `logging.Logger` is given, it'll be used directly. If something
            else or nothing is given, the default logger will be used.

        receive_updates (`bool`, optional):
            Whether the client will receive updates or not. By default, updates
            will be received from Telegram as they occur.

            Turning this off means that Telegram will not send updates at all
            so event handlers, conversations, and QR login will not work.
            However, certain scripts don't need updates, so this will reduce
            the amount of bandwidth used.

        entity_cache_limit (`int`, optional):
            How many users, chats and channels to keep in the in-memory cache
            at most. This limit is checked against when processing updates.

            When this limit is reached or exceeded, all entities that are not
            required for update handling will be flushed to the session file.

            Note that this implies that there is a lower bound to the amount
            of entities that must be kept in memory.

            Setting this limit too low will cause the library to attempt to
            flush entities to the session file even if no entities can be
            removed from the in-memory cache, which will degrade performance.
    NF
      r   Tr   eni  )
connectionuse_ipv6proxy
local_addrtimeoutrequest_retriesconnection_retriesretry_delayauto_reconnectsequential_updatesflood_sleep_thresholdraise_last_call_errordevice_modelsystem_versionapp_version	lang_codesystem_lang_codeloopbase_loggerreceive_updatescatch_upentity_cache_limitr   z(typing.Union[str, pathlib.Path, Session]ztyping.Type[Connection])r    sessionapi_idapi_hashr3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   c                    sf  |r|st d|| _t tr,t  nt tjs<t G  fdddt}| | _	t|tt
jfrztt|}W q tk
r   dd l}|d t }Y qX n"|d krt }nt|tstd|jrd|jk|kr|t| jrtntt |  || _|| _t|| _|| _tt | j!dd sBtd	"| j!j#j$|d k	r|d
krjd|krjtdn|dkrd|krtd|| _%|	| _&|
| _'|pd| _(|| _)|| _*|| _+|| _,t|t-st.|| _/t0|t1sd nt2j3|4| }t56 }|j7dkrd}n|j7dkrd}n|j7}t89dd|j:}t;j<| j|pJ|pJd|pX|pXd|pb| j=||dd |d	| _>i | _?i | _@tAB | _Ci | _Dd | _Ed | _Fd | _Gd | _HtII | _J| | _K|| _LtM | _Nd | _Og | _PtQRtM| _Si | _TtU| _Vi | _Wd | _Xd | _Yi | _Z|| _[tA\ | _]t^| j	d | __t` | _a|| _btc| jjd| j	| j'| j(| j,| j+| je| j]| jfd	| _gd S )Nz\Your API ID or Hash cannot be empty or None. Refer to telethon.rtfd.io for more information.c                       s   e Zd Z fddZdS )z-TelegramBaseClient.__init__.<locals>._Loggersc                    s&   | dr|jdddd } |S )Nz	telethon..r   )maxsplit)
startswithsplitgetChild)r    keyrE   r!   r"   __missing__  s    
z9TelegramBaseClient.__init__.<locals>._Loggers.__missing__N)r   r-   r.   rS   r!   rR   r!   r"   _Loggers  s   rT   r   zThe sqlite3 module is not available under this Python installation and no custom session instance was given; using MemorySession.
You will need to re-login every time unless you use another session storagez6The given session must be a str or a Session instance.:Zsock_connectzEvent loop of type {} lacks `sock_connect`, which is needed to use proxies.

Change the event loop in use to use proxies:
# https://github.com/LonamiWebs/Telethon/issues/1337
import asyncio
asyncio.set_event_loop(asyncio.SelectorEventLoop())Fz<A local IPv6 address must only be used with `use_ipv6=True`.Tz<`use_ipv6=True` must only be used with a local IPv6 address.)x86_64ZAMD64zPC 64bit)i386i686x86zPC 32bitz-.+ Unknownz1.0)	rJ   r?   r@   rA   rB   rC   Z	lang_packqueryr5   Z
messagebox)loggersretriesdelayr;   connect_timeoutZauth_key_callbackZupdates_queueZauto_reconnect_callback)h
ValueError	_use_ipv6
isinstancestrlogging	getLoggerLogger	_base_logdict_logpathlibPathr   ImportErrorwarningswarnr   r   	TypeErrorserver_addressset_dcDEFAULT_DC_IDDEFAULT_IPV6_IPDEFAULT_IPV4_IPDEFAULT_PORTsaver=   rI   intrJ   rK   callablegetattrrD   format	__class__r   Z_raise_last_call_errorZ_request_retriesZ_connection_retriesZ_retry_delay_proxy_local_addr_timeoutZ_auto_reconnecttyper%   _connection
issubclassr   r   InputClientProxyaddress_infoplatformunamemachineresubreleaser   ZInitConnectionRequest__version___init_requestZ_flood_waited_requests_borrowed_sendersasyncioLock_borrow_sender_lock_exported_sessions_loopZ_updates_error_updates_handle_keepalive_handler&   Z_last_request_no_updatesZ_sequential_updatesset_event_handler_tasksZ_authorizedZ_event_builderscollectionsdefaultdictZ_conversationsZ_albumsr   Z_parse_modeZ_phone_code_hashZ_phoneZ_tosZ_megagroup_cache	_catch_upQueueZ_updates_queuer   _message_boxMbEntityCache_mb_entity_cacheZ_entity_cache_limitr   auth_key_auth_key_callback_handle_auto_reconnect_sender) r    rI   rJ   rK   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rT   rn   
init_proxysystemZdefault_device_modelZdefault_system_versionr!   rR   r"   r#      s    



	




	
zTelegramBaseClient.__init__)r    returnc                 C   s   t  S )a  
        Property with the ``asyncio`` event loop used by this client.

        Example
            .. code-block:: python

                # Download media in the background
                task = client.loop.create_task(message.download_media())

                # Do some work
                ...

                # Join the task (wait for it to complete)
                await task
        )r   get_running_loopr   r!   r!   r"   rD     s    zTelegramBaseClient.loopc                 C   s   | j jS )aK  
        Property with a ``Future`` that resolves upon disconnection.

        Example
            .. code-block:: python

                # Wait for a disconnection to occur
                try:
                    await client.disconnected
                except OSError:
                    print('Error on disconnect')
        )r   disconnectedr   r!   r!   r"   r     s    zTelegramBaseClient.disconnectedc                 C   s   | j S r*   )_flood_sleep_thresholdr   r!   r!   r"   r=     s    z(TelegramBaseClient.flood_sleep_thresholdc                 C   s   t |pdd| _d S )Nr   iQ )minr   )r    valuer!   r!   r"   r=     s    c           
   
      sZ  | j dkrtd| jdkr(t | _n| jt kr>td| j| j| j j	| j j
| j j| j| j| jdI dH sxdS | jj| j _| j   z0| j dj}| j |}| j|d|j W n tk
r   Y nX | jrtdddddddd}g }| j  D ]N\}}|dkr:tddd|j|jt|j |jd}n|t||j q | j !|| |D ]^}z| j |j"}W n* tk
r   | jt# $d|j" Y nX | j%t&t'j(|j"|j qbt)j*+ | j,_-| j,}| j.rt)/|}| j0t)1t2|I dH  | j 3 r2| 4 I dH }	|	r2| 5|	I dH  | j67| 8 | _9| j67| : | _;dS )a  
        Connects to Telegram.

        .. note::

            Connect means connect and nothing else, and only one low-level
            request is made to notify Telegram about which layer we will be
            using.

            Before Telegram sends you updates, you need to make a high-level
            request, like `client.get_me() <telethon.client.users.UserMethods.get_me>`,
            as described in https://core.telegram.org/api/updates.

        Example
            .. code-block:: python

                try:
                    await client.connect()
                except OSError:
                    print('Failed to connect')
        Nz:TelegramClient instance cannot be reused after logging outzQThe asyncio event loop must not change after connection (see the FAQ for details)r]   r5   r6   r   Fz9No access_hash in cache for channel %s, will not catch up)<rI   ra   r   r   r   RuntimeErrorr   connectr   rq   portdc_idrj   r}   r~   r   rw   Zget_input_entityZaccess_hashr   Zset_self_userr   r   Zget_update_statesptsZqtsrx   date	timestampseqappendr   r   load
channel_idr   warningputr   r   ZCHANNELr   helpGetConfigRequestr   r\   r   ZInvokeWithoutUpdatesRequestsendInvokeWithLayerRequestr   Zis_emptyZget_meZ	_on_loginrD   create_task_update_loopr   Z_keepalive_loopr   )
r    self_idZ	self_usersscsZ	entity_idstateentityreqmer!   r!   r"   r     sf    


	

(
 

zTelegramBaseClient.connectc                 C   s   t | dd}|o| S )a  
        Returns `True` if the user has connected.

        This method is **not** asynchronous (don't use ``await`` on it).

        Example
            .. code-block:: python

                while client.is_connected():
                    await asyncio.sleep(1)
        r   N)rz   is_connected)r    senderr!   r!   r"   r   `  s    zTelegramBaseClient.is_connectedr   c                 C   sN   | j  r t| j |  S z| j |   W n tk
rH   Y nX dS )a
  
        Disconnects from Telegram.

        If the event loop is already running, this method returns a
        coroutine that you should await on your own code; otherwise
        the loop is ran until said coroutine completes.

        Event handlers which are currently running will be cancelled before
        this function returns (in order to properly clean-up their tasks).
        In particular, this means that using ``disconnect`` in a handler
        will cause code after the ``disconnect`` to never run. If this is
        needed, consider spawning a separate task to do the remaining work.

        Example
            .. code-block:: python

                # You don't need to use this if you used "with client"
                await client.disconnect()
        N)rD   Z
is_runningr   Zshieldr   _disconnect_coroZrun_until_completer   r   r!   r!   r"   
disconnecto  s    
zTelegramBaseClient.disconnect)r    r5   c                 C   sl   t | jtsdntj| j| }|| j_|| _t	| j
dd}|rht|trb|d |_|d |_n||_dS )a  
        Changes the proxy which will be used on next (re)connection.

        Method has no immediate effects if the client is currently connected.

        The new proxy will take it's effect on the next reconnection attempt:
            - on a call `await client.connect()` (after complete disconnect)
            - on auto-reconnect attempt (e.g, after previous connection was lost)
        Nr   r   r   )r   r   r   r   r   r   r   r5   r}   rz   r   rc   _ipZ_port)r    r5   r   r3   r!   r!   r"   	set_proxy  s    


zTelegramBaseClient.set_proxyc                 C   s   | j  }| jtjd dd |D g  | j jrZ| jtjd td| j jgg  | j	
 \}}| jdtjjf |ddi tj }| D ](\}}| j|tjj|d|ddd qd S )Nc                 S   s   g | ]}|  qS r!   )Z_as_input_peer).0er!   r!   r"   
<listcomp>  s     z@TelegramBaseClient._save_states_and_entities.<locals>.<listcomp>r   unread_count)r   )r   Zget_all_entitiesrI   Zprocess_entitiesr   ZcontactsZResolvedPeerr   ZInputPeerUserr   Zsession_stateZset_update_stateZupdatesStatedatetimenowitems)r    entitiesr   r   r   r   r   r!   r!   r"   _save_states_and_entities  s    
"& 
z,TelegramBaseClient._save_states_and_entitiesc              
      s   | j d krd S |  I d H  | j4 I d H 8 | j D ]\}}| I d H  d|_q6| j  W 5 Q I d H R X | jr| jD ]}|	  qzt
| jI d H  | j  |   | j   d S )NF)rI   _disconnectr   r   valuesr   r   clearr   cancelr   waitr   close)r    r   r   Ztaskr!   r!   r"   r     s    



z#TelegramBaseClient._disconnect_coroc                    s4   | j  I dH  tj| jt | j| jdI dH  dS )a9  
        Disconnect only, without closing the session. Used in reconnections
        to different data centers, where we don't want to close the session
        file; user disconnects however should close it since it means that
        their job with the client is complete and we should clean it up all.
        N)Zupdates_handleZkeepalive_handle)r   r   r   Z_cancelrj   r   r   r   r   r!   r!   r"   r     s
    zTelegramBaseClient._disconnectc                    sp   | j t d| | |I dH }| j|j|j|j d| j	j
_d| j_
| j  |  I dH  |  I dH S )zU
        Permanently switches the current connection to the new data center.
        z"Reconnecting to new data center %sN)rj   r   info_get_dcrI   rr   id
ip_addressr   r   r   rQ   rw   r   r   )r    Znew_dcdcr!   r!   r"   
_switch_dc  s    

zTelegramBaseClient._switch_dcc                 C   s   || j _| j   dS )z
        Callback from the sender whenever it needed to generate a
        new authorization key. This means we are not authorized.
        N)rI   r   rw   )r    r   r!   r!   r"   r     s    z%TelegramBaseClient._auth_key_callbackc                    s  j }|js"tj I dH |_ rjjsjtj I dH |_|jjD ]}|jkrJt	j
|jdd qJz t fdd|jjD W S  tk
r   jt d j z"t fdd|jjD W  Y S  tk
r   td d	  d
Y nX Y nX dS )z/Gets the Data Center (DC) associated to 'dc_id'NF)oldc                 3   s:   | ]2}|j krt|jjkrt|j kr|V  qd S r*   )r   boolZipv6rb   cdnr   r   r   r   r    r!   r"   	<genexpr>  s
   
 z-TelegramBaseClient._get_dc.<locals>.<genexpr>zOFailed to get DC %s (cdn = %s) with use_ipv6 = %s; retrying ignoring IPv6 checkc                 3   s*   | ]"}|j krt|j kr|V  qd S r*   )r   r   r   r   )r   r   r!   r"   r   %  s   
 zFailed to get DC z (cdn = ))r|   _configr   r   r   _cdn_configZGetCdnConfigRequestZpublic_keysr   r   Zadd_keyZ
public_keynextZ
dc_optionsStopIterationrj   r   r   rb   ra   )r    r   r   clspkr!   r   r"   r     s2    



  zTelegramBaseClient._get_dcc              
      s   |  |I dH }td| jd}|| j|j|j|j| j| j| j	dI dH  | jt
 d| | tj|I dH }tjj|j|jd| j_tt| j}||I dH  |S )z
        Creates a new exported `MTProtoSender` for the given `dc_id` and
        returns it. This method should be used by `_borrow_exported_sender`.
        N)r]   r   z,Exporting auth for new borrowed sender in %s)r   bytes)r   r   rj   r   r   r   r   r   r}   r~   r   r   r   authZExportAuthorizationRequestZImportAuthorizationRequestr   r   r\   r   r   r   )r    r   r   r   r   r   r!   r!   r"   _create_exported_sender,  s     z*TelegramBaseClient._create_exported_senderc                    s   | j 4 I dH  | jt d| | j|d\}}|dkrht }| |I dH }||_||f| j|< nF|	 r| 
|I dH }|| j|j|j|j| j| j| jdI dH  |  |W  5 Q I dH R  S Q I dH R X dS )a'  
        Borrows a connected `MTProtoSender` for the given `dc_id`.
        If it's not cached, creates a new one if it doesn't exist yet,
        and imports a freshly exported authorization key for it to be usable.

        Once its job is over it should be `_return_exported_sender`.
        NzBorrowing sender for dc_id %d)NNr   )r   rj   r   debugr   getr   r   r   r+   r   r   r   r   r   r   r}   r~   r$   )r    r   r   r   r   r!   r!   r"   _borrow_exported_senderH  s(    	z*TelegramBaseClient._borrow_exported_senderc              
      sP   | j 4 I dH 2 | jt d|j | j|j \}}|  W 5 Q I dH R X dS )z
        Returns a borrowed exported sender. If all borrows have
        been returned, the sender is cleanly disconnected.
        Nz&Returning borrowed sender for dc_id %d)r   rj   r   r   r   r   r'   )r    r   r   _r!   r!   r"   _return_exported_senderh  s    z*TelegramBaseClient._return_exported_senderc              
      sl   | j 4 I dH N | j D ]<\}\}}| r| jt d| | I dH  |  qW 5 Q I dH R X dS )zN
        Cleans-up all unused exported senders by disconnecting them.
        Nz'Disconnecting borrowed sender for DC %d)	r   r   r   r)   rj   r   r   r   r,   )r    r   r   r   r!   r!   r"   _clean_exported_sendersr  s    
 z*TelegramBaseClient._clean_exported_sendersc              
      s   | j |j}|sR| j|jddI dH }| j }||j|j|j	 || j |j< | j
t d | j|| j| j| j| j| jd}| jj|_|j| j|j|j	|j| j
| j| jdI dH  |S )z1Similar to ._borrow_exported_client, but for CDNsT)r   NzCreating new CDN client)r5   r7   rD   r   )r   r   r   r   rI   clonerr   r   r   r   rj   r   r   r|   rJ   rK   r}   r   rD   r   r   r   r   rq   r~   )r    Zcdn_redirectrI   r   clientr!   r!   r"   _get_cdn_client  s2    
  

z"TelegramBaseClient._get_cdn_clientc                 C   s   t dS )a  
        Invokes (sends) one or more MTProtoRequests and returns (receives)
        their result.

        Args:
            request (`TLObject` | `list`):
                The request or requests to be invoked.

            ordered (`bool`, optional):
                Whether the requests (if more than one was given) should be
                executed sequentially on the server. They run in arbitrary
                order by default.

            flood_sleep_threshold (`int` | `None`, optional):
                The flood sleep threshold to use for this request. This overrides
                the default value stored in
                `client.flood_sleep_threshold <telethon.client.telegrambaseclient.TelegramBaseClient.flood_sleep_threshold>`

        Returns:
            The result of the request (often a `TLObject`) or a list of
            results if more than one request was given.
        NNotImplementedError)r    requestZorderedr!   r!   r"   __call__  s    zTelegramBaseClient.__call__c                 C   s   t d S r*   r   r   r!   r!   r"   r     s    zTelegramBaseClient._update_loopc                    s   t d S r*   r   r   r!   r!   r"   r     s    z)TelegramBaseClient._handle_auto_reconnect)F)F)/r   r-   r.   __doc__r   r   r   r   r
   rx   rd   r   typingUniontupleri   r   ZAbstractEventLoopre   rg   r#   propertyrD   ZFuturer   r=   setterr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   abcabstractmethodr   r   r   r!   r!   r!   r"   r/   D   s    !
 k

Y%" 
 r/   )6r  r   r   r   re   r   r&   r   r   rk   rZ   r   r   r   Z__base_name__Zcryptor   
extensionsr   networkr   r	   r
   r   sessionsr   r   r   tlr   r   Ztl.alltlobjectsr   Z_updatesr   r   r   r   r   r   r   rs   ru   rt   rv   TYPE_CHECKINGZtelegramclientr   rf   rh   r(   r   ABCr/   r!   r!   r!   r"   <module>   s6    
 