o
    ;i^                     @   s  d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlm	Z	m
Z
 d dlmZmZmZmZ d dlmZ d dlZd dlmZ d dlmZ d	d
lmZmZmZ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%m&Z&m'Z'm(Z(m)Z) d	dl*m+Z+m,Z,m-Z- ddl.m/Z/m0Z0m1Z1 ej2rd dl3Z4G dd deZ5G dd de'Z6dd Z7de8fddZ9dee:e8ef  deej; de<fddZ=de8fdd Z>d!ede<fd"d#Z?d$d% Z@d&ee< dd'fd(d)ZAG d*d+ d+ZBd!ed,ef de<fd-d.ZCd!ed,ef de<fd/d0ZD	dMd1ee8 d2ed3 d4ee8 deedf fd5d6ZEd7ZFd8ZGd9eHfd:d;ZIdMd<ejJd=eKfd>d?ZLd@eKdAeKdBedC de<fdDdEZMdddFdGedHdIdJeeK dBedC dejNf
dKdLZOdS )N    N)AsyncGenerator)Enum)PathPurePosixPath)AnyCallableLiteralOptional)StreamTerminatedError)api_pb2)ModalClientModal   )deserializedeserialize_data_formatget_preferred_payload_format	serializeserialize_data_formatsignature_to_parameter_specs)append_modal_tb)logger)DeserializationErrorExecutionErrorFunctionTimeoutErrorInternalErrorInternalFailureInvalidErrorRemoteErrorServiceError)ROOT_DIR_is_modal_path_Mount   )MAX_ASYNC_OBJECT_SIZE_BYTESblob_download blob_upload_with_r2_failure_infoc                   @   s   e Zd ZdZdZdZdZdS )FunctionInfoTypepackagefile
serializednotebookN)__name__
__module____qualname__PACKAGEFILE
SERIALIZEDNOTEBOOK r1   r1   O/home/ubuntu/.local/lib/python3.10/site-packages/modal/_utils/function_utils.pyr%   0   s
    r%   c                   @   s   e Zd ZdZdS )LocalFunctionErrorzSRaised if a function declared in a non-global scope is used in an impermissible wayN)r*   r+   r,   __doc__r1   r1   r1   r2   r3   7   s    r3   c                    s   t |   fdd}|S )Nc                    s2   t | }| kr
dS |jdkr|j jv rdS dS )NTz__init__.pyF)r   nameparentparents)filenamepathentrypoint_pathr1   r2   inner>   s   z6entrypoint_only_package_mount_condition.<locals>.inner)r   )entrypoint_filer<   r1   r:   r2   'entrypoint_only_package_mount_condition;   s   	r>   object_qual_namec                 C   s   d|  dvS )N<locals>.)split)r?   r1   r1   r2   is_global_objectJ   s   rC   experimental_optionshttp_configreturnc                 C   s   t | o| ddp|d uS )NflashF)boolget)rD   rE   r1   r1   r2   is_flash_objectN   s   rJ   c                 C   s:   d| v r|  dd }t| ddkS t|  ddkS )Nr@   z	<locals>.rA   r!   )rB   len)r?   restr1   r1   r2   is_method_fnR   s   rN   fc                 C   s   | j | jkS )zReturns True if this function is defined in global scope.

    Returns False if this function is locally scoped (including on a class).
    )r*   r,   rO   r1   r1   r2   is_top_level_function[   s   rQ   c                 C   sX   t | r| j} t | st | rdS t | st | r dS td|  dt|  )NTFz	Function z is a strange type )	inspectismethod__func__iscoroutinefunctionisasyncgenfunction
isfunctionisgeneratorfunctionRuntimeErrortype)functionr1   r1   r2   is_asyncc   s   
r\   is_generatorz'api_pb2.Function.FunctionType.ValueTypec                 C   s   | rt jjS t jjS N)r   FunctionFUNCTION_TYPE_GENERATORFUNCTION_TYPE_FUNCTION)r]   r1   r1   r2   get_function_typet   s   rb   c                
   @   sZ  e Zd ZU dZeedef  ed< eed< eed< ee	e  ed< ee ed< e
ed< ee ed	< eed
< dZee ed< d+ddZdd Z			d,deedef  dedee dee	 fddZdefddZdefddZdeeef fddZdeeef fdd Zdeeef fd!d"Zdejfd#d$Zdeeef fd%d&Zd'd( Zd)d* ZdS )-FunctionInfoa,  Utility that determines serialization/deserialization mechanisms for functions

    * Stored as file vs serialized
    * If serialized: how to serialize the function
    * If file: which module/function name should be used to retrieve

    Used for populating the definition of a remote function
    .raw_ffunction_nameimplementation_nameuser_clsmodule_name_type_file	_base_dirN_remote_dirrF   5modal_proto.api_pb2.Function.DefinitionType.ValueTypec                 C   s   |   r	tjjjS tjjjS r^   )is_serializedmodal_protor   r_   DEFINITION_TYPE_SERIALIZEDDEFINITION_TYPE_FILEselfr1   r1   r2   get_definition_type   s   

z FunctionInfo.get_definition_typec                 C   s   | j d u r| js
J dS dS )NTF)rd   rg   rr   r1   r1   r2   is_service_class   s   

zFunctionInfo.is_service_classFrO   r(   name_overridec           	         s  | _ | _|d u r|r|j d _n|r#|r#|j d|j  _n|j _|p+ j _|d ur7t|}nt|}t|dd r|st	j
|j _dd t|jjD } fdd|D }|std j  td	|  td
|  tdt|dkr|jtd |d  _|jj _tt|jdd   _d _tj  _!n@t"|dr|st	j
t#| _t$ j _t	j
% j _d _tj& _!nd  _t	j
d _d _|rtj' _!ntj( _! ) s|r|jn|j}t*|st+dd S d S )Nz.*rA   __package__c                 S   s   h | ]}t j|qS r1   )osr9   abspath).0pr1   r1   r2   	<setcomp>   s    z(FunctionInfo.__init__.<locals>.<setcomp>c                    s&   g | ]}t j| jf|kr|qS r1   )rx   r9   
commonpathrj   )rz   base_dirrr   r1   r2   
<listcomp>   s     z)FunctionInfo.__init__.<locals>.<listcomp>zModule files: zPackage paths: zBase dirs: z*Wasn't able to find the package directory!r!   )keyr   F__file__ TzYModal can only import functions defined in global scope unless they are `serialized=True`),rd   rg   r*   rf   r,   re   rR   	getmodulegetattrrx   r9   ry   r   rj   
__import__rw   __path__r   info	ExceptionrL   sortrk   __spec__r5   rh   r   r   rB   rl   _is_serializedr%   r-   ri   hasattrgetfilegetmodulenamedirnamer.   r/   r0   rn   rC   r3   )	rs   rO   r(   rv   rg   modulepackage_paths	base_dirsqualnamer1   rr   r2   __init__   sb   







zFunctionInfo.__init__c                 C      | j S r^   )r   rr   r1   r1   r2   rn         zFunctionInfo.is_serializedc                 C   sX   |   sJ | jrt| j}td| jj dt|  |S td| jj d dS )NzSerializing z
, size is z0Serializing function for class service function z	 as empty    )rn   rd   r   r   debugr,   rL   rg   )rs   serialized_bytesr1   r1   r2   serialized_function   s   
z FunctionInfo.serialized_functionc                    s*    j d ur fddt j D }|S i S )Nc                    s4   i | ]}t t j|s|d s|t j|qS )__)callabler   rg   
startswith)rz   attrrr   r1   r2   
<dictcomp>   s    z-FunctionInfo.get_cls_vars.<locals>.<dictcomp>)rg   dir)rs   cls_varsr1   rr   r2   get_cls_vars   s   

zFunctionInfo.get_cls_varsc                    s   dd l }dd l}|jd }|jd }| jj}t ||D ]}|j|kr,|j q|j|kr7|j q| 	   fdd D }|S )Nr   	LOAD_ATTR
STORE_ATTRc                    s   i | ]}|v r| | qS r1   r1   rz   kr   
f_attr_opsr1   r2   r     s    z2FunctionInfo.get_cls_var_attrs.<locals>.<dictcomp>)
disopcodeopmaprd   __code__setget_instructionsaddargvalr   )rs   r   r   r   r   codeinstrf_attrsr1   r   r2   get_cls_var_attrs  s   



zFunctionInfo.get_cls_var_attrsc                    sn   ddl m} | jd u ri S | j t dr'  jur' j t dr'  jus| j} fdd|D }|S )Nr   )_extract_code_globals__wrapped__c                    s"   i | ]}| j v r| j | qS r1   )__globals__r   funcr1   r2   r   !  s   " z,FunctionInfo.get_globals.<locals>.<dictcomp>)_vendor.cloudpickler   rd   r   r   r   )rs   r   f_globals_ref	f_globalsr1   r   r2   get_globals  s   

zFunctionInfo.get_globalsc                 C   s\   | j st S ddlm}m} || j stjtjjdS || j }t|}tjtjj|dS )Nr   ) _get_class_constructor_signature_use_annotation_parameters)format)r   schema)	rg   r   ClassParameterInfo	modal.clsr   r   !PARAM_SERIALIZATION_FORMAT_PICKLEr    PARAM_SERIALIZATION_FORMAT_PROTO)rs   r   r   	signatureparameter_specsr1   r1   r2   class_parameter_info$  s   

z!FunctionInfo.class_parameter_infoc                 C   s|   |   ri S | jtjkr| jdd }|t|iS | jtjkr<t	| j
}|j}t|j }t|s<|tj| j
|diS i S )a  
        Includes:
        * Implicit mount of the function itself (the module or package that the function is part of)

        Does not include:
        * Client mount
        * Explicit mounts added to the stub or function declaration
        * "Auto mounted" mounts, i.e. all mounts in sys.modules that are *not* installed in site-packages.
            These are typically local modules which are imported but not part of the running package

        rA   r   )remote_path)rn   ri   r%   r-   rh   rB   r    _from_local_python_packagesr.   r   rj   stemr   r5   r   _from_local_file)rs   top_level_packagemodule_filecontainer_module_namer   r1   r1   r2   get_entrypoint_mount9  s    

z!FunctionInfo.get_entrypoint_mountc                 C   r   r^   )re   rr   r1   r1   r2   get_tagb  r   zFunctionInfo.get_tagc                 C   sJ   t | j}|j D ]}|jt jjt jjfv rq|j	|j
u r" dS qdS )NFT)rR   r   rd   
parametersvalueskind	ParameterVAR_POSITIONALVAR_KEYWORDdefaultempty)rs   r   paramr1   r1   r2   
is_nullarye  s   zFunctionInfo.is_nullary)rF   rm   )FNN)r*   r+   r,   r4   r	   r   r   __annotations__strrZ   r%   rl   r   rt   ru   rH   r   rn   bytesr   dictr   r   r   r   r   r   r    r   r   r   r1   r1   r1   r2   rc   x   sD   
 	


O
)rc   .c                 C   s   t dd t| j D S )zReturn True if a callable (function, bound method, or unbound method) has parameters other than self.

    Used to ensure that @exit(), @asgi_app, and @wsgi_app functions don't have parameters.
    c                 s   s    | ]}|j d kV  qdS )rs   N)r5   )rz   r   r1   r1   r2   	<genexpr>u  s    z/callable_has_non_self_params.<locals>.<genexpr>)anyrR   r   r   r   rP   r1   r1   r2   callable_has_non_self_paramsp  s   r   c                 C   s:   t | j D ]}|jdkrq|jt jjkrq dS dS )zReturn True if a callable (function, bound method, or unbound method) has non-default parameters other than self.

    Used for deprecation of default parameters in @asgi_app and @wsgi_app functions.
    rs   TF)rR   r   r   r   r5   r   r   r   )rO   r   r1   r1   r2   (callable_has_non_self_non_default_paramsx  s   
r   function_call_idvariant)data_indata_outattempt_tokenc              
   C  s~  |s	|s	t d|du r| j}d}d}d}|dkr|j}n|dkr&|j}nt d| 	 tj||d
}	|r:||	_z3||	2 z*3 dH W }
|
j|krLq@|
j	rZt
|
j	| jI dH }n|
j}t||
j| }|
j}|V  q@6 W nN tttfy } z?|dkr|d8 }t|ttfrt| d| d|  t|d I dH  td|d }W Y d}~q-t|trW Y d}~q- d}~ww d}q.)z@Read from the `data_in` or `data_out` stream of a function call.zHfunction_call_id or attempt_token is required to read from a data streamNr   
   r!   r   r   zInvalid variant T)r   
last_indexz stream retrying with delay z
ms due to i  )
ValueErrorstubFunctionCallGetDataInFunctionCallGetDataOutr   FunctionCallGetDataRequestr   unary_streamindexdata_blob_idr#   datar   data_formatr   r   r
   
isinstancer   r   asynciosleepmin)clientr   r   r   r   r   retries_remainingdelay_msstub_fnreqchunkmessage_bytesmessageexcr1   r1   r2   _stream_function_call_data  s\   

r  g     K@   r  c                 C   sV   t | tr| jdkr|  jd7  _| S t | tr)dt| v r)| jd d }|f| _| S )zmdmd:hiddenz6attempted relative import with no known parent packagez

HINT: For relative imports to work, you might need to run your modal app as a module. Try:
- `python -m my_pkg.my_app` instead of `python my_pkg/my_app.py`
- `modal deploy my_pkg.my_app` instead of `modal deploy my_pkg/my_app.py`
zDCUDA error: no kernel image is available for execution on the devicer   aI  

HINT: This error usually indicates an outdated CUDA version. Older versions of torch (<=1.12)
come with CUDA 10.2 by default. If pinning to an older torch version, you can specify a CUDA version
manually, for example:
-  image.pip_install("torch==1.12.1+cu116", find_links="https://download.pytorch.org/whl/torch_stable.html")
)r   ImportErrormsgrY   r   args)r  r  r1   r1   r2   exc_with_hints  s   	r  resultr   c           	   
      s  |  ddkrt| j|I d H }n| j}| jtjjkr!t| j	| jtjj
kr-t| j	| jtjjkr|r|tjtjfv rzt||}W n: tyd } ztd| d d d | j  |jd }~w ty } ztd| d d | j  |d }~ww t|tstdt| | jrzt| j|}t| j|}t||| W t| ty   Y t|w t|t| j	zt|||W S  ty } z	td| d	|d }~ww )
N
data_oneofr   z;Could not deserialize remote exception due to local error:

zZThis can happen if your local environment does not have the remote exception definitions.
zHere is the remote traceback:
z'Got remote exception of incorrect type z+Could not deserialize result due to error:
zj
This can happen if your local environment does not have a module that was used to construct the result. 
)
WhichOneofr#   r   r   statusr   GenericResultGENERIC_STATUS_TIMEOUTr   	exceptionGENERIC_STATUS_INTERNAL_FAILUREr   GENERIC_STATUS_SUCCESSDATA_FORMAT_PICKLEDATA_FORMAT_UNSPECIFIEDr   r   r   	traceback	__cause__r   r   BaseExceptionrZ   serialized_tbtb_line_cacher   r  r   r   ModuleNotFoundError)	r  r   r   r   r   r  	deser_exctb_dict
line_cacher1   r1   r2   _process_result  s   



r  	num_bytesmax_object_size_bytesfunction_call_invocation_typez,api_pb2.FunctionCallInvocationType.ValueTypec                 C   s   | |kp|t jko| tkS )zD
    Determine if the input should be uploaded to blob storage.
    )r   #FUNCTION_CALL_INVOCATION_TYPE_ASYNCr"   )r  r  r   r1   r1   r2   should_upload  s   
r"  )idxr   r   r[   zmodal._functions._Functionr#  c                   s   |j }|j}|du rd}t }|jstd|jjptjg}	||	vr'|	d }t| |f|}
t	t
|
||rPt|
|I dH \}}}tjtj|||d|||dS tjtj|
||d|dS )zoSerialize function arguments and create a FunctionInput protobuf,
    uploading to blob storage if needed.
    Nr   zCAttempted to call function that has not been hydrated with metadata)args_blob_idr   method_name)inputr#  	r2_failedr2_throughput_bytes_s)r  r   r%  )r&  r#  )_use_method_name_max_object_size_bytesr   	_metadatar   supported_input_formatsr   r  _serialize_data_formatr"  rL   r$   FunctionPutInputsItemFunctionInput)r  kwargsr   r[   r#  r   r%  r  r   r,  args_serializedr$  r'  r(  r1   r1   r2   _create_input,  s@   r2  r^   )Pr   rR   rx   typingcollections.abcr   enumr   pathlibr   r   r   r   r   r	   grpclib.exceptionsr
   ro   r   modal_proto.modal_api_grpcr   _serializationr   r   r   r   r   r-  r   
_tracebackr   configr   r  r   r   r   r   r   r   r   r   mountr   r   r    
blob_utilsr"   r#   r$   TYPE_CHECKINGmodal._functionsmodalr%   r3   r>   r   rC   r   
HTTPConfigrH   rJ   rN   rQ   r\   rb   rc   r   r   r  OUTPUTS_TIMEOUTATTEMPT_TIMEOUT_GRACE_PERIODr  r  r  intr  r"  r.  r2  r1   r1   r1   r2   <module>   s    (
(	 y

=;
