o
    ;i:                  
   @   s  U 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mZmZmZmZ d dlZd dlmZ d dlmZ d dlmZ d dlmZ d dlmZmZ d d	lmZ d
dl m!Z! d
dl"m#Z# d
dl$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/m0Z0m1Z1 e+2dZ3e4e5d< e3d Z6e4e5d< de7dee8e9e9f  de9de:e9e9f fddZ;edZ<ee9e=f Z>ee
e9e>f e	e8e9e>f  f Z?ededZ@ededZAG d d! d!ZBe&eBZCdS )"    N)AsyncGenerator
CollectionMapping)AnyClassVarOptionalTypeVarUnion)	empty_pb2)Message)asynccontextmanager)synchronizer)api_pb2modal_api_grpc)__version__   )print_server_warnings)async_utils)TaskContextsynchronize_api)_AuthTokenManager)ConnectionManager)_check_config
_is_remoteconfiglogger)	AuthErrorClientClosedheartbeat_intervalHEARTBEAT_INTERVALg?HEARTBEAT_TIMEOUTclient_typecredentialsversionreturnc                 C   s   t  }|jdkrdt  d }}n|j|j}}ddd |||jfD }dtjj	tjj
tjjf }|t| |tjt  tj|d}|r\| tjkr\|\}	}
||	|
d	 |S )
NDarwinmacOSr   -c                 s   s    | ]	}| d dV  qdS )r'   _N)replace).0s r,   @/home/ubuntu/.local/lib/python3.10/site-packages/modal/client.py	<genexpr>'   s    z _get_metadata.<locals>.<genexpr>z%d.%d.%d)zx-modal-client-versionzx-modal-client-typezx-modal-python-versionzx-modal-nodezx-modal-platform)zx-modal-token-idzx-modal-token-secret)platformunamesystemmac_verreleasejoinmachinesysversion_infomajorminormicrostrurllibparsequotenoder   CLIENT_TYPE_CLIENTupdate)r!   r"   r#   r0   r1   r3   platform_strpython_versionmetadatatoken_idtoken_secretr,   r,   r-   _get_metadata    s(   

rG   
ReturnTypeRequestType)boundResponseTypec                   @   s|  e Zd ZU dZeed   ed< dZeeej	  ed< e
ed< dZeej ed< dZeej ed< dZee ed< dZeed	< dZee ed
< ded< efdedddeeeef  defddZdefddZedefddZedejfddZdedejfddZdd ZdGdefddZ d d! Z!d"d# Z"d$d% Z#e$e%dede&d& fd'd(Z'e$dHdId)d*Z(e$d+ed,edd fd-d.Z)e$dedeeef ddfd/d0Z*e$d1ed  fd2d3Z+d4ede,eeef  fd5d6Z-d7efd8d9Z.d:d; Z/dede0j1j2fd<d=Z3e4j5ddd>d?e0j1j6e7e8f d@e9dAee: dBee; de9f
dCdDZ<e4j5d?e0j1j=e7e8f d@e9dBee; de&e9df fdEdFZ>dS )J_ClientN_client_from_env_client_from_env_lock_cancellation_context _cancellation_context_event_loop_stub_auth_token_managerF_snapshotted_connection_managerzapi_pb2.ClientType.ValueTyper!   
server_urlr"   r#   c                 C   s:   || _ || _|| _|| _d| _d| _d| _d| _d| _dS )zjmdmd:hidden
        The Modal client object is not intended to be instantiated directly by users.
        FN)	rU   r!   _credentialsr#   _closedrQ   rR   rS   
_owner_pid)selfrU   r!   r"   r#   r,   r,   r-   __init__P   s   

z_Client.__init__r$   c                 C   s   | j S N)rW   rY   r,   r,   r-   	is_closedd   s   z_Client.is_closedc                 C   s   t j| jj}|dv S )z3Returns True if the server URL points to localhost.>   ::1	127.0.0.1
172.21.0.1	localhost)r<   r=   urlparserU   hostname)rY   rc   r,   r,   r-   _is_localhostg   s   z_Client._is_localhostc                 C   s   | j sJ | j S )a\  mdmd:hidden
        The default stub. Stubs can safely be used across forks / client snapshots.

        This is useful if you want to make requests to the default Modal server in us-east, for example
        control plane requests.

        This is equivalent to client.get_stub(default_server_url), but it's cached, so it's a bit faster.
        )rQ   r\   r,   r,   r-   stubm   s   

z_Client.stubc                    s   t j| |I dH S )aU  mdmd:hidden
        Get a stub for a specific server URL. Stubs can safely be used across forks / client snapshots.

        This is useful if you want to make requests to a regional Modal server, for example low-latency
        function calls in us-west.

        This function is O(n) where n is the number of RPCs in ModalClient.
        N)r   ModalClientModal_createrY   rU   r,   r,   r-   get_stubz   s   	z_Client.get_stubc                    s   d| _ | jd u sJ t| j| j| j}tdd| _t	 | _
| j I d H  t| |d| _| | jI d H | _t| j| _t | _d S )NFg      ?)grace)clientrD   )rW   rQ   rG   r!   rV   r#   r   rO   asyncioget_running_looprP   
__aenter__r   rT   ri   rU   r   re   rR   osgetpidrX   )rY   rD   r,   r,   r-   _open   s   
z_Client._openprep_for_restorec                    sf   t dt|  d d| _t| dr| jd d d I d H  | jr'| j  |r,d| _	| 
d  d S )NClient (z
): closingTrO   )r   debugidrW   hasattrrO   	__aexit__rT   closerS   set_env_client)rY   rr   r,   r,   r-   _close   s   

z_Client._closec                    s<   t dt|  d | jt I dH }t|j dS )zaConnect to server and retrieve version information; raise appropriate error for various failures.rs   z): StartingN)	r   rt   ru   re   ClientHellor
   Emptyr   server_warnings)rY   respr,   r,   r-   hello   s   z_Client.helloc                    s   |   I d H  | S r[   )rq   r\   r,   r,   r-   rn      s   z_Client.__aenter__c                    s   |   I d H  d S r[   )rz   )rY   exc_typeexctbr,   r,   r-   rw      s   z_Client.__aexit__)rL   Nc                 C  sV   t d | |tjdd}z| I dH  |V  W | I dH  dS | I dH  w )zdmdmd:hidden
        Create a connection with no credentials; to be used for token creation.
        z.Client: Starting client without authenticationN)r"   )r   rt   r   r@   rq   rz   )clsrU   rk   r,   r,   r-   	anonymous   s   
"z_Client.anonymousc           	   	      s  t   |r	|}nt}| jdu rt | _| j4 I dH b | jr-| jW  d  I dH  S |d }|d }t rG|s<|rAtd t	j
}d}n|rS|rSt	j}||f}ntd|d }t|||}| I dH  t|  || _|W  d  I dH  S 1 I dH sw   Y  dS )zqmdmd:hidden
        Singleton that is instantiated from the Modal config and reused on subsequent calls.
        NrE   rF   zzModal tokens provided by MODAL_TOKEN_ID and MODAL_TOKEN_SECRET (or through the config file) are ignored inside containers.zToken missing. Could not authenticate client. If you have token credentials, see modal.com/docs/reference/modal.config for setup help. If you are a new user, register an account at modal.com, then run `modal token new`.rU   )r   r   rN   rl   LockrM   r   warningswarnr   CLIENT_TYPE_CONTAINERr@   r   rL   rq   r   on_shutdownrz   )	r   _override_configcrE   rF   r!   r"   rU   rk   r,   r,   r-   from_env   sB   


0z_Client.from_envrE   rF   c                    sJ   t   td }tj}||f}t|||}| I dH  t|  |S )aB  
        Constructor based on token credentials; useful for managing Modal on behalf of third-party users.

        **Usage:**

        ```python notest
        client = modal.Client.from_credentials("my_token_id", "my_token_secret")

        modal.Sandbox.create("echo", "hi", client=client, app=app)
        ```
        rU   N)	r   r   r   r@   rL   rq   r   r   rz   )r   rE   rF   rU   r!   r"   rk   r,   r,   r-   from_credentials   s   z_Client.from_credentialsc              	      sX   | |t j|4 I dH }| I dH  W d  I dH  dS 1 I dH s%w   Y  dS )zzmdmd:hidden
        Check whether can the client can connect to this server with these credentials; raise if not.
        N)r   r@   r   )r   rU   r"   rk   r,   r,   r-   verify  s   .z_Client.verifyrk   c                 C   s
   || _ dS )zmdmd:hiddenN)rM   )r   rk   r,   r,   r-   ry   	  s   
z_Client.set_env_clientinput_plane_regionc                    s0   | j sJ d| j  I d H }d|fd|fgS )Nz3Client must have an instance of auth token manager.zx-modal-input-plane-regionzx-modal-auth-token)rR   	get_token)rY   r   tokenr,   r,   r-   get_input_plane_metadata  s   z _Client.get_input_plane_metadatareadable_methodc                    s   |   r|  tt| t }|| jkr>z| j|}|	| |I dH W S  tj
y=   |   r<tt| d w td| d |I dH S )aR  Runs coroutine wrapped in a task that's part of the client's task context

        * Raises ClientClosed in case the client is closed while the coroutine is executed
        * Logs warning if call is made outside of the event loop that the client is running in,
          and execute without the cancellation context in that case
        NzRPC request to z made outside of task context)r]   rx   r   ru   rl   rm   rP   rO   create_taskset_nameCancelledErrorr   warning)rY   coror   current_event_looprequest_taskr,   r,   r-   _call_safely  s"   


z_Client._call_safelyc                    sL   | j r"| j t kr$d | _d | _d | _ | d  |  I d H  d S d S d S r[   )rX   ro   rp   rT   rQ   ry   rq   r\   r,   r,   r-   _reset_on_pid_change5  s   
z_Client._reset_on_pid_changec                    s,   |   I d H  | jsJ | j|I d H S r[   )r   rT   get_or_create_channelrh   r,   r,   r-   _get_channelA  s   
z_Client._get_channeltimeoutrD   grpclib_methodrequestr   rD   c                   s$   ||||d}|  ||jI d H S )Nr   )r   name)rY   r   r   r   rD   r   r,   r,   r-   _call_unaryH  s   	z_Client._call_unaryc             
   C  s   |j |d}| | |j dI d H }z2| |j|dd|j dI d H  	 z| | |j dI d H V  W n	 tyE   Y nw q*W n# tyk } z|t	|||j
I d H }|s` W Y d }~d S d }~ww |d d d I d H  d S )N)rD   z.openT)endz.send_messager   z.recv)openr   rn   r   send_message	__anext__StopAsyncIterationBaseExceptionrw   type__traceback__)rY   r   r   rD   stream_contextstreamr   did_handle_exceptionr,   r,   r-   _call_streamT  s*   $$z_Client._call_stream)Fr[   )r$   rL   )?__name__
__module____qualname__rM   r   r   __annotations__rN   rl   r   r   rP   AbstractEventLooprQ   r   rf   rR   r   rS   boolrT   r   r   r;   tuplerZ   r]   propertyrd   re   ri   rq   rz   r   rn   rw   classmethodr   r   r   r   r   r   ry   listr   r   r   grpclibrk   Channelr   r   nowrapUnaryUnaryMethodrI   rK   r   float_MetadataLiker   UnaryStreamMethodr   r,   r,   r,   r-   rL   E   s   
 
0 
rL   )Drl   ro   r/   r6   urllib.parser<   r   collections.abcr   r   r   typingr   r   r   r   r	   grpclib.clientr   google.protobufr
   google.protobuf.messager   synchronicity.async_wrapr   modal._utils.async_utilsr   modal_protor   r   modal_versionr   
_tracebackr   _utilsr   _utils.async_utilsr   r   _utils.auth_token_managerr   _utils.grpc_utilsr   r   r   r   r   	exceptionr   r   getr   r   r   r    intr   r;   dictrG   rH   bytes_Valuer   rI   rK   rL   Clientr,   r,   r,   r-   <module>   sD   
.   *