o
    ;iSg                  
   @   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 d dlm	Z	 zd dl
Z
W n ey9   dZ
Y nw d dl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m Z  ej!r}d dl"Z#dZ$G dd dej%Z%G dd dej&Z&dede'fddZ(de'defddZ)dedej*fddZ+dej*defddZ,dUd!d"Z-ded#e.de'fd$d%Z/de'd#e.defd&d'Z0G d(d) d)ej%Z1d*d+ Z2d,ej3e4ef d-ej5ej6 de7e4ef fd.d/Z8d0e4d1edej9fd2d3Z:d,e7e4ef de'fd4d5Z;d6e'de7e4ef fd7d8Z<d9e7e4ef d-ej5ej6 fd:d;Z=d6e'd<ej>d=d>fd?d@Z?	AdVdBe jdCe@dej6fdDdEZAdFe jBdeCej6 fdGdHZDdAdIdJejEdKe@dLe@dejFejG fdMdNZHdOeIde'fdPdQZJdOeIdRe4deKe'e'f fdSdTZLdS )W    N)	Parameter)Any)extract_traceback)config)synchronizer)api_pb2   )_Object)parameter_serde_registryschema_registry)cloudpickle)logger)DeserializationErrorExecutionErrorInvalidErrorSerializationError)Object   c                       $   e Zd Z fddZdd Z  ZS )Picklerc                       t  j|td d S N)protocolsuper__init__PICKLE_PROTOCOLselfbuf	__class__ H/home/ubuntu/.local/lib/python3.10/site-packages/modal/_serialization.pyr   $      zPickler.__init__c                 C   s   ddl m} t|trd}n.t|trd}n&t||r:t|}|j }tj	r3tj	|v r3|
tj	 d|j|ffS d S |jsGtd| d|j|| fS )Nr   )PartialFunction_oosyncCan't serialize object z which hasn't been hydrated.)modal.partial_functionr%   
isinstancer	   r   r   _translate_in__dict__copy_wrapped_attrpopr!   is_hydratedr   	object_id_get_metadata)r   objr%   flagimpl_object
attributesr"   r"   r#   persistent_id'   s   




zPickler.persistent_id__name__
__module____qualname__r   r8   __classcell__r"   r"   r    r#   r   #       r   c                       r   )	Unpicklerc                    s   || _ t | d S N)clientr   r   )r   rA   r   r    r"   r#   r   I   s   zUnpickler.__init__c           
      C   s   t |dkr&|\}}|dkr"|\}}||}|j| t|S td|\}}}	|dv r7t|| j	|	S |dv rCt
|| j	|	S td)N   r(   zUnknown serialization format)r'   ph)r&   _p_hzbad flag)len__new__r-   updater   _translate_outr   r   _new_hydratedrA   r	   r   )
r   pidobj_typeobj_data
impl_classr7   impl_instancer2   r5   handle_protor"   r"   r#   persistent_loadM   s   


zUnpickler.persistent_load)r:   r;   r<   r   rR   r=   r"   r"   r    r#   r?   H   s    r?   r4   returnc                 C   s   t  }t||  | S )zSSerializes object and replaces all references to the client class by a placeholder.)ioBytesIOr   dumpgetvalue)r4   r   r"   r"   r#   	serialized   s   rX   sc              
   C   s   ddl m} | rdnd}zt|t|  W S  ty8 } zdt|v r+td|td| d|d	}~w t	yP } ztd
|j
 d| d|d	}~w ty{ } z |dkridt| dt| d}nd}td| d| d|d	}~ww )zADeserializes object and replaces all client placeholders by self.r   )is_locallocalremotez$Can't get attribute '_make_function'zDeserialization failed due to a version mismatch between local and remote environments. Try changing the Python version in your Modal image to match your local Python version. z/Deserialization failed with an AttributeError, zj. This is probably because you have different versions of a library in your local and remote environments.Nz$Deserialization failed because the 'z!' module is not available in the z environment.: ()z (see above for details)z9Encountered an error when deserializing an object in the z environment.)_runtime.execution_contextrZ   r?   rT   rU   loadAttributeErrorstrr   ModuleNotFoundErrorname	Exceptiontype)rY   rA   rZ   envexcmorer"   r"   r#   deserializek   sF   
rl   c                 C   s  dd }| d u rt  S | d}|dkrRt jt jj| dd| d | dd| d	 | d
|| dg | dr@| d d nd | drL| d d nd ddS |dkrht jt jj| d| dddS |dkrt jt jj| d || dg | dddS |dkrt jt jj| d| dddS |dkrt jt jj|| dg | ddd S |d!krt jt j d"S |d#krt jt jj	| dd| dd$| d	 | d
|| dg | dr| d d nd | dr| d d nd | d%d&d'S |d(krt jt j
 d)S |d*kr+t jt jj| d+|| dg d,d-S |d.krBt jt jj| d/| d0d1d2S |d3krYt jt jj| d/| d0d1d4S |d5krlt jt jj| d6d7d8S |d9krt jt jj| d6| d:d;d<S td=| t  S )>Nc                 S   s   dd | D S )Nc                 S   s"   g | ]\}}||fD ]}|q
qS r"   r"   ).0kvrY   r"   r"   r#   
<listcomp>   s   " z<_serialize_asgi.<locals>.flatten_headers.<locals>.<listcomp>r"   r4   r"   r"   r#   flatten_headers   s   z(_serialize_asgi.<locals>.flatten_headersrh   httphttp_versionz1.1methodschemepathquery_stringheadersrA   r   r   )rt   ru   rv   rw   rx   ry   client_hostclient_port)rs   http.requestbody	more_body)r}   r~   )http_requesthttp.response.startstatustrailers)r   ry   r   )http_response_starthttp.response.body)http_response_bodyhttp.response.trailersmore_trailers)ry   r   )http_response_trailershttp.disconnect)http_disconnect	websocketwssubprotocols)rt   rv   rw   rx   ry   rz   r{   r   )r   websocket.connect)websocket_connectwebsocket.acceptsubprotocol)r   ry   )websocket_acceptwebsocket.receivebytestext)r   r   )websocket_receivewebsocket.send)websocket_sendwebsocket.disconnectcode)r   )websocket_disconnectwebsocket.closereason)r   r   )websocket_closez6skipping serialization of unknown ASGI message type %r)r   AsgigetHttpHttpRequestHttpResponseStartHttpResponseBodyHttpResponseTrailersHttpDisconnect	WebsocketWebsocketConnectWebsocketAcceptWebsocketReceiveWebsocketSendWebsocketDisconnectWebsocketCloser   debug)r4   rr   msg_typer"   r"   r#   _serialize_asgi   s   











r   asgic                 C   s  dd }|  d}|dkr=d| jj| jj| jj| jj| jj|| jjd| jdr4d| jj	| jj
fini dd	i iiS |d
krKd| jj| jjdS |dkr^d| jj|| jj| jjdS |dkrld| jj| jjdS |dkr|d	|| jj| jjdS |dkrddiS |dkrd| jj| jj| jj| jj|| jjd| jdrd| jj	| jj
fini dt| jjiS |dkrddiS |dkrd| jdr| jjnd || jjdS |dkrd | jd!r| jjnd | jd"r| jjd#S d d#S |d$krdd%i| jd!rd!| jjini | jd"rd"| jjiS i S |d&kr6d'| jd(r2| jjd*S d)d*S |d+krNd,| jd(rG| jjnd-| jj d.S |d u sUJ d S )/Nc                 S   s"   t t| d d d | dd d S )NrB   r   )listziprq   r"   r"   r#   unflatten_headers  s   "z,_deserialize_asgi.<locals>.unflatten_headersrh   rs   )rh   rt   ru   rv   rw   rx   ry   rz   rA   
extensionsr   r   r|   )rh   r}   r~   r   r   )rh   r   ry   r   r   r   r   )rh   ry   r   r   r   r   )rh   rt   rv   rw   rx   ry   r   r   r   r   r   r   )rh   r   ry   r   r   r   r   )rh   r   r   r   r   r   r   r   i  )rh   r   r   r   i  )rh   r   r   )!
WhichOneofrs   rt   ru   rv   rw   rx   ry   HasFieldrz   r{   r   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r"   r"   r#   _deserialize_asgi  s   

"	



	



r   api_pb2.DataFormat.ValueTypec                  C   s.   t dpd } | dkrtj}|S tj}|S )Npayload_formatpicklecbor)r   r   lowerr   DATA_FORMAT_CBORDATA_FORMAT_PICKLE)r   data_formatr"   r"   r#   get_preferred_payload_formate  s
   r   r   c                 C   s   |t jkr	t| S |t jkrt| jddS |t jkr)t| t js#J | jddS |t j	krlt
du r6tdzt
| W S  t
jyk   zt| j dt| j }W n tyb   tt| }Y nw td| dw td|)	z8Similar to serialize(), but supports other data formats.TdeterministicN:CBOR support requires the 'cbor2' package to be installed.r`   zCan not serialize type zq as cbor. If you need to use a custom data type, try to serialize it yourself e.g. by using pickle.dumps(my_data)Unknown data format )r   r   rX   DATA_FORMAT_ASGIr   SerializeToStringDATA_FORMAT_GENERATOR_DONEr+   GeneratorDoner   cbor2r   dumpsCBOREncodeTypeErrorrh   r;   r:   rg   rd   r   )r4   r   typenamer"   r"   r#   serialize_data_formatk  s.   




r   c                 C   sv   |t jkr
t| |S |t jkrtt j| S |t jkr"t j| S |t j	kr4t
d u r/tdt
| S td|)Nr   r   )r   r   rl   r   r   r   
FromStringr   r   r   r   r   loads)rY   r   rA   r"   r"   r#   deserialize_data_format  s   





r   c                       r   )ClsConstructorPicklerc                    r   r   r   r   r    r"   r#   r     r$   zClsConstructorPickler.__init__c                 C   s,   t |ttfr|jstd| ddS d S )Nr)   z which hasn't been created.T)r+   r	   r   r2   r   )r   r4   r"   r"   r#   r8     s
   z#ClsConstructorPickler.persistent_idr9   r"   r"   r    r#   r     r>   r   c              
   C   sN   t  }z
t|| W dS  tttjfy&   td|  dt| dw )NTzJOnly pickle-able types are allowed in remote class constructors: argument 	 of type r`   )	rT   rU   r   rV   rc   
ValueErrorr   PicklingErrorrh   )keyr4   r   r"   r"   r#   check_valid_cls_constructor_arg  s   r   python_paramsschemac                 C   sX   i | }|D ]#}|j r)|j| vr)|d}|du r!t|j dt||||j< q|S )aE  Apply any declared defaults from the provided schema, if values aren't provided in python_params

    Conceptually similar to inspect.BoundArguments.apply_defaults.

    Note: Apply this before serializing parameters in order to get consistent parameter
        pools regardless if a value is explicitly provided or not.
    default_oneofNz7 declared as having a default, but has no default value)has_defaultrf   r   r   getattr)r   r   resultschema_paramdefault_field_namer"   r"   r#   apply_defaults  s   

r   rf   python_valuec                 C   s   t |}| |_|S )zKMap to proto parameter representation using python runtime type information)r
   encoderf   )rf   r   structr"   r"   r#   encode_parameter_value  s   
r   c                 C   s>   g }|   D ]\}}|t|| qtj|djdd}|S )N)
parametersTr   )itemsappendr   r   ClassParameterSetr   )r   proto_params
param_namer   proto_bytesr"   r"   r#   serialize_proto_params  s
   r   serialized_paramsc                 C   s0   t j| }i }|jD ]
}t|||j< q|S r@   )r   r   r   r   r
   decoderf   )r   proto_structr   paramr"   r"   r#   deserialize_proto_params  s
   
r   payloadc                 C   s   |D ]+}|j | vrtd|j  | |j  }|dr$|jjr$|jj}n|j}t|| qdd |D }|  | }|rGtdd	| dS )zEnsure parameter payload conforms to the schema of a class

    Checks that:
    * All fields are specified (defaults are expected to already be applied on the payload)
    * No extra fields are specified
    * The type of each field is correct
    zMissing required parameter: 	full_typec                 S   s   h | ]}|j qS r"   )rf   )rm   rC   r"   r"   r#   	<setcomp>  s    z,validate_parameter_values.<locals>.<setcomp>zfThe following parameter names were provided but are not defined class modal.parameters for the class: z, N)
rf   r   r   r   	base_typerh   r
   validate_value_for_enum_typekeysjoin)r   r   
param_specr   type_enum_valueschema_fieldsnon_declared_fieldsr"   r"   r#   validate_parameter_values  s"   


r   function_def_clientzmodal.client._Clientc                 C   s  |j jtjjtjjfv r@zt| |\}}W ||fS  ty? } zd}zt| }W n	 t	y1   |w W Y d }~||fS d }~ww |j jtjj
krd}z	t| }W ||fS  tjjjy~ } zz	t| |\}}W n	 t	yp   |w W Y d }~||fS d }~ww td|j j )Nr"   z.Unknown class parameter serialization format: )class_parameter_infoformatr   ClassParameterInfo&PARAM_SERIALIZATION_FORMAT_UNSPECIFIED!PARAM_SERIALIZATION_FORMAT_PICKLErl   r   r   rg    PARAM_SERIALIZATION_FORMAT_PROTOgoogleprotobufmessageDecodeErrorr   )r   r   r   
param_argsparam_kwargsoriginal_excr"   r"   r#   deserialize_params  sH   



	
r  Fpython_signature_parameterinclude_legacy_parameter_fieldsc                 C   s   | j }t|}| jtju}tj| j||d}|rN|j	j
|_|rN|j
tjkr,| j|_|S |j
tjkr8| j|_|S |j
tjkrD| j|_|S |j
tjkrN| j|_|S )a*  Returns proto representation of Parameter as returned by inspect.signature()

    Setting include_legacy_parameter_fields makes the output backwards compatible with
    pre v0.74 clients looking at class parameter specifications, and should not be used
    when registering *function* schemas.
    )rf   r   r   )
annotationr   get_proto_generic_typedefaultr   emptyr   ClassParameterSpecrf   r   r   rh   PARAM_TYPE_INTint_defaultPARAM_TYPE_STRINGstring_defaultPARAM_TYPE_BYTESbytes_defaultPARAM_TYPE_BOOLbool_default)r  r  declared_typefull_proto_typer   
field_specr"   r"   r#   _signature_parameter_to_spec  s.   	

r   	signaturec                 C   s.   g }| j  D ]}t|dd}|| q|S )NT)r  )r   valuesr   r   )r!  modal_parametersr   r  r"   r"   r#   signature_to_parameter_specsC  s
   r$  )ignore_first_argumentcallableis_web_endpointr%  c          	   
   C   s   |rd S zt | }W n ty( } ztjd|  |d W Y d }~d S d }~ww t|j}g }t|j	
 D ]\}}|dkrC|rCq8|t| q8tjtjj||dS )Nz%Error getting signature for function )exc_infor   )schema_type	argumentsreturn_type)inspectr!  rg   r   r   r   r  return_annotation	enumerater   r"  r   r   r   FunctionSchemaFUNCTION_SCHEMA_V1)	r&  r'  r%  sigereturn_type_protor*  irC   r"   r"   r#   get_callable_schemaL  s(   r5  rj   c              
   C   s`   zt | W S  ty/ } zd|  dt|  d| }t| t t|W  Y d }~S d }~ww )NzFailed to serialize exception r   r]   )rX   rg   rh   r   infor   )rj   serialization_excerrr"   r"   r#   pickle_exceptionj  s   

r9  task_idc                 C   sT   d\}}zt | |\}}t|}t|}W ||fS  ty)   td Y ||fS w )N)    r;  z(Failed to serialize exception traceback.)r   rX   rg   r   r6  )rj   r:  serialized_tbtb_line_cachetb_dict
line_cacher"   r"   r#   pickle_tracebackt  s   
r@  )rS   r   )F)Mr,  rT   r   typingr   r   modal._tracebackr   modal.configr   r   ImportErrorgoogle.protobuf.messager  modal._utils.async_utilsr   modal_protor   _objectr	   _type_managerr
   r   _vendorr   r   	exceptionr   r   r   r   objectr   TYPE_CHECKINGmodal.clientmodalr   r   r?   r   rX   rl   r   r   r   r   intr   r   r   r   Mappingrd   Sequencer  dictr   ClassParameterValuer   r   r   r   Functionr  boolr   	Signaturer   r$  CallableOptionalr/  r5  BaseExceptionr9  tupler@  r"   r"   r"   r#   <module>   s   %'o
d


"	(
%


"
