o
    ;ib                     @   s  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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 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 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,m-Z-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7m8Z8 ddl9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@ edZAejBrd dlCZDdeEdeFfddZGdeEdejHfd d!ZIe J G d"d# d#ZKd$d%d&ed'eLfd(d)ZMG d*d+ d+ZNe)eNZOG d,d% d%ed-d.ZPe)ePZQe)d$ePdej
ejR fd/d0ZSe)d$ePdeTeLejUf fd1d2ZVG d3d4 d4ZWeW ZXG d5d6 d6ZYd7edeFfd8d9ZZeXd:d;d<ed=eFdefd>d?Z[dS )@    N)
Collection)PurePosixPath)AnyCallableOptionalSequenceTypeVarUnion)Message)api_pb2   )	_Function_parse_retries)LoadContext)_Objectlive_method)_find_callables_for_obj"_find_partial_methods_for_user_cls_PartialFunction_PartialFunctionFlags)Resolver)%convert_fn_config_to_resources_config)check_valid_cls_constructor_arg)print_server_warnings)parameter_serde_registry)synchronize_apisynchronizer)deprecation_warningwarn_if_passing_namespace#warn_on_renamed_autoscaler_settings)validate_volumes)_Client)_CloudBucketMount)ExecutionErrorInvalidErrorNotFoundError)GPU_T)Retries)_Secret)_VolumeTuser_clsreturnc                 C   s.   t dd | j D }| jtjk}|o| S )Nc                 s   s    | ]}t |V  qd S Nis_parameter).0
cls_member r2   =/home/ubuntu/.local/lib/python3.10/site-packages/modal/cls.py	<genexpr>2   s    z-_use_annotation_parameters.<locals>.<genexpr>)any__dict__values__init__object)r+   has_parametershas_explicit_constructorr2   r2   r3   _use_annotation_parameters1   s   
r<   c                 C   s   t | s	t| S g }t|  D ]2\}}t| |rDt| |}t|rDi }t	|j
ts1|j
|d< tjd||tjjd|}|| qt|S )Ndefault)name
annotationkindr2   )r<   inspect	signaturetypingget_type_hintsitemshasattrgetattrr/   
isinstancer=   _NO_DEFAULT	ParameterPOSITIONAL_OR_KEYWORDappend	Signature)r+   constructor_parametersr>   annotation_valueparameter_specmaybe_defaultparamr2   r2   r3    _get_class_constructor_signature7   s(   





rS   c                   @   s"  e Zd ZU dZee ed< dZej	e
eef  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 ed< dZee ed	< dZee ed
< dZee ed< dZee ed< dZee ed< dZee ed< dZeej ed< dZee ed< dZej	e
ee f  ed< dddZ!dS )_ServiceOptionsr2   secretsvalidated_volumesN	resourcesretry_policymax_containersbuffer_containersscaledown_windowtimeout_secsmax_concurrent_inputstarget_concurrent_inputsbatch_max_sizebatch_wait_msscheduler_placementcloudcloud_bucket_mountsnew_optionsr,   c                    s   t | } fddt  D }t }|jr||j |d }r*|| ||_| D ]\}}|r=t	||| q1|S )zImplement protobuf-like MergeFrom semantics for this dataclass.

        This mostly exists to support "stacking" of `.with_options()` calls.
        Returns a new _ServiceOptions instance without modifying self.
        c                    s   i | ]
}|j t |j qS r2   )r>   rG   )r0   krd   r2   r3   
<dictcomp>l   s    z1_ServiceOptions.merge_options.<locals>.<dictcomp>rW   )
dataclassesreplacefieldsr   	ResourcesrW   	MergeFrompoprE   setattr)selfrd   mergednew_options_dictmerged_resourcesnew_resourceskeyvaluer2   rf   r3   merge_optionsb   s   

z_ServiceOptions.merge_options)rd   rT   r,   rT   )"__name__
__module____qualname__rU   r   r(   __annotations__rV   rC   r   tuplestrr)   rW   r   r   rk   rX   FunctionRetryPolicyrY   intrZ   r[   r\   r]   r^   r_   r`   ra   SchedulerPlacementrb   rc   r"   rv   r2   r2   r2   r3   rT   O   s"   
 rT   cls_Clsservice_functionmethod_namec           	   	      s   j sJ dtf fdddddtdtdtt ffd	d
} fdd}d j d d}tj|||d jd}j	rD|  
 r] j }ddlm} ||j jdd|_j |_ d|_j|_j|_|S )a&  Binds an "instance service function" to a specific method using metadata for that method

    This "dummy" _Function gets no unique object_id and isn't backend-backed at all, since all
    it does it forward invocations to the underlying instance_service_function with the specified method
    new_functionc                    s4   j sJ  j s
J  j }| jj| d S r-   )is_hydrated_method_metadata_hydrate	object_idclient)r   method_metadata)r   r   r   r2   r3   &hydrate_from_instance_service_function   s   


zE_bind_instance_method.<locals>.hydrate_from_instance_service_functionfunr   resolverload_contextexisting_object_idc                    s    |  d S r-   r2   r   r   r   r   )r   r2   r3   _load   s   z$_bind_instance_method.<locals>._loadc                     s(   g }  j s
|   j s|  | S r-   )r   rL   )unhydrated_deps)r   r   r2   r3   _deps   s   

z$_bind_instance_method.<locals>._depsMethod(.)T)depshydrate_lazilyload_context_overridesr   )FunctionInfo)r+   
serialized)_objr   r   r   r   r|   _name_from_loader_load_context_overridesr   	_is_local_method_partialsmodal._utils.function_utilsr   raw_f	_user_cls_info
_is_method_app_spec)	r   r   r   r   r   repr   partial_functionr   r2   )r   r   r   r   r3   _bind_instance_method}   s6   
"	

r   c                   @   s\  e Zd ZU dZded< eeef ed< eed< dZ	e
e ed< eedf ed	< eeef ed
< dZe
e ed< e
e ed< ddde
e de
e fddZd0ddZdeeef fddZdd Zdddddde
e de
e de
e de
e ddf
dd Zd!eddfd"d#Zd$d% Zd&d' Zedefd(d)Zejd*efd+d)Zejd,d- Zd.d/ ZdS )1_ObjzyAn instance of a `Cls`, i.e. `Cls("foo", 42)` returns an `Obj`.

    All this class does is to return `Function` objects.r   _cls
_functions_has_enteredN_user_cls_instance._args_kwargs_instance_service_function_optionsr   r+   optionsc           
      C   sd   t |D ]\}}t|d | q| D ]	\}}	t||	 q|| _d| _|| _|| _|| _|| _d S )Nr   F)		enumerater   rE   r   r   r   r   r   r   )
ro   r   r+   r   argskwargsiargrt   kwargr2   r2   r3   r8      s   
z_Obj.__init__r,   modal.functions._Functionc                 C   s4   | j s| jjs	J | jj| | j| j| j| _ | j S r-   )r   r   _class_service_function_bind_parametersr   r   r   ro   r2   r2   r3   _cached_service_function   s   z_Obj._cached_service_functionc                 C   s,   t | j}|j| ji | j}|  |jS r-   )rS   r   bindr   r   apply_defaults	arguments)ro   sig
bound_varsr2   r2   r3   _get_parameter_values   s   
z_Obj._get_parameter_valuesc                 C   st   t | js| j| ji | j}n|  }| j| j}|j| i }t| jt	
 D ]	}t| |||< q+||_|S r-   )r<   r   r   r   r   __new__r6   updater   r   interface_flagsrG   _modal_functions)ro   user_cls_instanceparam_valuesinstance_methodsr   r2   r2   r3   _new_user_cls_instance   s   
z_Obj._new_user_cls_instancemin_containersrY   r[   rZ   r   rY   r[   rZ   c                   s   |   j||||dI dH S )a)  Override the current autoscaler behavior for this Cls instance.

        Unspecified parameters will retain their current value, i.e. either the static value
        from the function decorator, or an override value from a previous call to this method.

        Subsequent deployments of the App containing this Cls will reset the autoscaler back to
        its static configuration.

        Note: When calling this method on a Cls that is defined locally, static type checkers will
        issue an error, because the object will appear to have the user-defined type.

        Examples:

        ```python notest
        Model = modal.Cls.from_name("my-app", "Model")
        model = Model()  # This method is called on an *instance* of the class

        # Always have at least 2 containers running, with an extra buffer when the Function is active
        model.update_autoscaler(min_containers=2, buffer_containers=1)

        # Limit this Function to avoid spinning up more than 5 containers
        f.update_autoscaler(max_containers=5)
        ```

        r   N)r   update_autoscaler)ro   r   rY   r[   rZ   r2   r2   r3   r     s   !z_Obj.update_autoscalerwarm_pool_sizec                    s*   t dddd |  j|dI dH  dS )a  mdmd:hidden
        Set the warm pool size for the class containers

        DEPRECATED: Please adapt your code to use the more general `update_autoscaler` method instead:

        ```python notest
        Model = modal.Cls.from_name("my-app", "Model")
        model = Model()  # This method is called on an *instance* of the class

        # Old pattern (deprecated)
        model.keep_warm(2)

        # New pattern
        model.update_autoscaler(min_containers=2)
        ```

        )     r   zwThe .keep_warm() method has been deprecated in favor of the more general .update_autoscaler(min_containers=...) method.T)show_source)r   N)r   r   r   )ro   r   r2   r2   r3   	keep_warm:  s   z_Obj.keep_warmc                 C   s   | j s|  | _ | j S )zdGet or construct the local object

        Used for .local() calls and getting attributes of classes)r   r   r   r2   r2   r3   _cached_user_cls_instanceT  s   
z_Obj._cached_user_cls_instancec                 C   sd   | j sJ | js0|  }t|dr|  tjtjfD ]}t||	 D ]}|  q$qd| _d S d S )N	__enter__T)
r   r   r   rF   r   r   ENTER_PRE_SNAPSHOTENTER_POST_SNAPSHOTr   r7   )ro   r   method_flagenter_methodr2   r2   r3   _enter]  s   


z_Obj._enterc                 C   s   | j S r-   r   r   r2   r2   r3   _enteredm  s   z_Obj._enteredvalc                 C   s
   || _ d S r-   r   )ro   r   r2   r2   r3   r   r     
c                    sF   | j s|  }t|dr| I d H  n	t|dr|  d| _d S )N
__aenter__r   T)r   r   rF   r   r   r   )ro   r   r2   r2   r3   _aenterv  s   


z_Obj._aenterc                    s   dt d ffdd jjsj r2   }r|S j r* }t|S td ddtdtf fd	d
}t	j
|djj d dfdddjjdS )Nr,   r   c                      sP   j  r j jvrdS nj jr j jvrdS ntdtj   S )zGets _Function object for method - either for a local or a hydrated remote class

            * If class is neither local or hydrated - raise exception (should never happen)
            * If attribute isn't a method - return None
            Nz`Class is neither hydrated or local - this is probably a bug in the Modal client. Contact support)r   r   r   r   r   r#   r   r   r2   )re   ro   r2   r3   _get_maybe_method  s   
z+_Obj.__getattr__.<locals>._get_maybe_methodzClass has no method `zj` and attributes (or undecorated methods) can't be accessed for remote classes (`Cls.from_name` instances)r   r   c                    s@     }|d u rt d d|||I d H  | | d S )NzClass has no method z@, and attributes can't be accessed for `Cls.from_name` instances)r%   load_hydrate_from_other)r   r   r   r   method_function)r   re   r2   r3   method_loader  s   
z'_Obj.__getattr__.<locals>.method_loaderr   r   r   c                      s    j gS r-   )r   r2   r   r2   r3   <lambda>  s    z"_Obj.__getattr__.<locals>.<lambda>Tr   r   r   r   )r   r   r   r   r   rG   r%   r   r   r   r   r   r   )ro   re   maybe_methodr   r   r2   )r   re   ro   r3   __getattr__  s$   





z_Obj.__getattr__)r,   r   ) rw   rx   ry   __doc__rz   dictr|   r   boolr   r   r   r{   r   rT   typer8   r   r   r   r~   r   r   r   r   propertyr   setterr   nowrapr   r   r2   r2   r2   r3   r      sZ   
 


	
(	
	r   c                &       s  e Zd ZU dZee ed< eed< dZed ed< ee	 ed< dZ
eee	ejf  ed< dZee ed	< dZeee	ef  ed
< ee	edef f ed< dd ZdW fddZdee	ef fddZdXddZdefddZde	fddZdefddZdee	 fddZedeee	  fdd Zd!e fd"d#Z!e"d$d% Z#e"d&dd'edd fd(d)Z$e%dddd*d+ed  d,e	d-e	d.ed/ee	 d0ed1 dd fd2d3Z&e'dddddi ddddddddddd4d5d d6ee(e)e*e)e)f f  d7ee(e+e*e+e+f f  d8e,d9eee	ee	 f  d:eee-  d;ee(e	e.f e(e/e0f f d<ee(e+e1f  d=ee+ d>ee+ d?ee+ d@ee+ dAee(e	e2e	 f  dBee	 dCee+ dDee+ dEee+ dd f$dFdGZ3ddHd5d dIe+dJee+ dd fdKdLZ4d5d dMe+dNe+dd fdOdPZ5e6j7de8fdQdRZ9dSdT Z:de;fdUdVZ<  Z=S )Yr   ac  
    Cls adds method pooling and [lifecycle hook](https://modal.com/docs/guide/lifecycle-functions) behavior
    to [modal.Function](https://modal.com/docs/reference/modal.Function).

    Generally, you will not construct a Cls directly.
    Instead, use the [`@app.cls()`](https://modal.com/docs/reference/modal.App#cls) decorator on the App object.
    r   r   Nmodal.app._Appr   r   r   r   r   .
_callablesc                 C   s$   d | _ d | _t | _i | _d | _d S r-   )r   r   rT   r   r   r   r   r2   r2   r3   _initialize_from_empty  s
   
z_Cls._initialize_from_emptyotherc                    sX   t  | |j| _|j| _|j| _|j| _|j| _|j| _|j| _|j	| _	|j
| _
d S r-   )super_initialize_from_otherr   r   r   r   r   r   r   r   r   )ro   r   	__class__r2   r3   r     s   z_Cls._initialize_from_otherr,   c                 C   s   | j stdt| j t S )Nz>You can only get the partial functions of a local Cls instance)r   AttributeErrorr   r   allr   r2   r2   r3   _get_partial_functions  s   z_Cls._get_partial_functionsc                 C      | j d usJ | j S r-   )r   r   r2   r2   r3   _get_app     z_Cls._get_appc                 C   r   r-   r   r   r2   r2   r3   _get_user_cls  r  z_Cls._get_user_clsc                 C   r   r-   )r   r   r2   r2   r3   	_get_name  r  z_Cls._get_namec                 C   r   r-   )r   r   r2   r2   r3   _get_class_service_function  r  z _Cls._get_class_service_functionc                 C   s
   | j  S r-   )r   keysr   r2   r2   r3   _get_method_names  r   z_Cls._get_method_namesc                    s   |    I dH S )z'URL of the flash service for the class.N)r  _experimental_get_flash_urlsr   r2   r2   r3   r  
  s   z!_Cls._experimental_get_flash_urlsmetadatac                 C   s`   t |tjsJ |  }|jsJ |jrt|jr|j}ni }|jD ]}|j||j	< q"|| _
d S r-   )rH   r   ClassHandleMetadatar  r   _method_handle_metadatalenmethodsfunction_handle_metadatafunction_namer   )ro   r	  class_service_functionr   methodr2   r2   r3   _hydrate_metadata  s   


z_Cls._hydrate_metadatac                    s   dd | j  D  | jtjk} r|rtd|r'tdd|  d| j d t| } 	 |	  }|r:td fd	d| D }| D ]!\}}zt
| W qI tyj } z
td
| d| d}~ww dS )mdmd:hiddenc                 S   s   i | ]\}}t |r||qS r2   r.   r0   re   vr2   r2   r3   rg   #      z8_Cls.validate_construction_mechanism.<locals>.<dictcomp>zgA class can't have both a custom __init__ constructor and dataclass-style modal.parameter() annotations)r         
z uses a non-default constructor (__init__) method.
Custom constructors will not be supported in a a future version of Modal.

To parameterize classes, use dataclass-style modal.parameter() declarations instead,
e.g.:


class z:
    model_name: str = modal.parameter()

More information on class parameterization can be found here: https://modal.com/docs/guide/parametrized-functions
z>All modal.parameter() specifications need to be type-annotatedc                    s   i | ]\}}| v r||qS r2   r2   )r0   re   tparamsr2   r3   rg   ?  r  zClass parameter 'z': N)r6   rE   r8   r9   r$   r   rw   rA   get_annotationsr  r   validate_parameter_type	TypeError)r+   has_custom_constructorannotationsmissing_annotationsannotated_paramsre   r  excr2   r  r3   validate_construction_mechanism   s8   
z$_Cls.validate_construction_mechanismappr  c           
   	      s   t |  t| t  }t| t }dd t| t  D }dtt f fdd}dddt	d	t
d
tt fdd}d| j d}t j||||jd}	||	_| |	_ |	_||	_||	_| j|	_|	S )r  c                 S   s"   i | ]\}}|j d ur||j qS r-   )r   )r0   re   pfr2   r2   r3   rg   S  s
    
z#_Cls.from_local.<locals>.<dictcomp>r,   c                      s    gS r-   r2   r2   r  r2   r3   r   Y  s   z_Cls.from_local.<locals>._depsro   r   r   r   r   c                    s@   t j|j|dd}|jj|I d H }| |j|j|j d S )NT)app_idexisting_class_idonly_class_function)	r   ClassCreateRequestr)  r   stubClassCreater   class_idhandle_metadata)ro   r   r   r   reqrespr2   r2   r3   r   \  s   z_Cls.from_local.<locals>._loadzCls(r   )r   r   )r   r%  r   r   r   r   rE   listr   r   r   r   r|   rw   r   _root_load_contextr   r   r   r   r   r   )
r+   r&  r  lifecycle_method_partialsmethod_partials	callablesr   r   r   r   r2   r(  r3   
from_localF  s&   

z_Cls.from_local)	namespaceenvironment_namer   r   app_namer>   r9  r:  r   r!   c             	      s   t |d dtdtdtdtt f fdd}|rd|nd	}d
 d| d}t||d}	| j||dd|	d}  d}
tj |
|	d| _	| _
| S )a3  Reference a Cls from a deployed App by its name.

        This is a lazy method that defers hydrating the local
        object with metadata from Modal servers until the first
        time it is actually used.

        ```python
        Model = modal.Cls.from_name("other-app", "Model")
        ```
        zmodal.Cls.from_namero   r   r   r   c                    s   t j |jdd}z|jj|I d H }W n* tyA } z|jr)d|j dnd}td d  d| d	| d
	d d }~ww t|j |	| j
|I d H  | |j|j|j d S )NT)r;  
object_tagr:  r+  z
 (in the 'z' environment) zLookup failed for Cls 'z' from the 'z' appz: r   )r   ClassGetRequestr:  r   r-  ClassGetr%   r   server_warningsr   r   r   r/  r0  )ro   r   r   r   requestresponser$  env_contextr;  r>   r2   r3   _load_remote  s,   
z$_Cls.from_name.<locals>._load_remotez, environment_name=r=  zCls.from_name(z, r   )r   r:  T)is_another_appr   r   z.*)r   )r   r   r   r   r   r|   r   r   
_from_namer   r   )r   r;  r>   r9  r:  r   rE  environment_repr   r   class_service_namer2   rD  r3   	from_namep  s8   

z_Cls.from_name)cpumemorygpuenvrU   volumesretriesrY   rZ   r[   timeoutregionrb   concurrency_limitcontainer_idle_timeoutallow_concurrent_inputsro   rK  rL  rM  rN  rU   rO  rP  rY   rZ   r[   rQ  rR  rb   rS  rT  rU  c                   s6  t |jrdj nd}|s|s|rt|||dd}nd}|dur(tdd t|}dd |D }d	d |D }|p=g }|rIg |t|}d}|r_t|t	rU|gnt
|}tj|d
}t|||||||	|
|||||d}j|  fdd}dd }tj|j dd|jdd}|  |_|S )a  Override the static Function configuration at runtime.

        This method will return a new instance of the cls that will autoscale independently of the
        original instance. Note that options cannot be "unset" with this method (i.e., if a GPU
        is configured in the `@app.cls()` decorator, passing `gpu=None` here will not create a
        CPU-only instance).

        **Usage:**

        You can use this method after looking up the Cls from a deployed App or if you have a
        direct reference to a Cls from another Function or local entrypoint on its App:

        ```python notest
        Model = modal.Cls.from_name("my_app", "Model")
        ModelUsingGPU = Model.with_options(gpu="A100")
        ModelUsingGPU().generate.remote(input_prompt)  # Run with an A100 GPU
        ```

        The method can be called multiple times to "stack" updates:

        ```python notest
        Model.with_options(gpu="A100").with_options(scaledown_window=300)  # Use an A100 with slow scaledown
        ```

        Note that container arguments (i.e. `volumes` and `secrets`) passed in subsequent calls
        will not be merged.
        zClass r=  N)rK  rL  rM  ephemeral_disk)r   r   	   zhThe `allow_concurrent_inputs` argument is deprecated; please use the `.with_concurrency` method instead.c                 S   "   g | ]\}}t |tr||fqS r2   )rH   r"   r  r2   r2   r3   
<listcomp>     " z%_Cls.with_options.<locals>.<listcomp>c                 S   rX  r2   )rH   r)   r  r2   r2   r3   rY    rZ  )regions)rU   rV   rc   rW   rX   rY   rZ   r[   r\   ra   rb   r]   r^   c                    .   j s||I d H  |   | _d S r-   r   r   r   r   new_clsr   r   r   combined_optionsro   r2   r3   _load_from_base  s
   

z*_Cls.with_options.<locals>._load_from_basec                   S      g S r-   r2   r2   r2   r2   r3   r   !     z _Cls.with_options.<locals>._depsz.with_options(...)Tr   rF  r   r   r   )r   r   rw   r   r   r    r(   	from_dictrH   r|   r3  r   r   rT   r   rv   r   r   r   r   r   )ro   rK  rL  rM  rN  rU   rO  rP  rY   rZ   r[   rQ  rR  rb   rS  rT  rU  rX   rW   rV   rc   "validated_volumes_no_cloud_bucketsra   r[  rd   rb  r   r_  r2   r`  r3   with_options  s`   1

z_Cls.with_options)target_inputs
max_inputsri  c                   b   t ||d}j|  fdd}dd }tj|j dd|jdd}|  |_|S )	a  Create an instance of the Cls with input concurrency enabled or overridden with new values.

        **Usage:**

        ```python notest
        Model = modal.Cls.from_name("my_app", "Model")
        ModelUsingGPU = Model.with_options(gpu="A100").with_concurrency(max_inputs=100)
        ModelUsingGPU().generate.remote(42)  # will run on an A100 GPU with input concurrency enabled
        ```
        )r]   r^   c                    r\  r-   r]  r^  r`  r2   r3   rb  >  
   

z._Cls.with_concurrency.<locals>._load_from_basec                   S   rc  r-   r2   r2   r2   r2   r3   r   E  rd  z$_Cls.with_concurrency.<locals>._depsz.with_concurrency(...)Tre  rT   r   rv   r   r   r   r   r   )ro   rj  ri  concurrency_optionsrb  r   r_  r2   r`  r3   with_concurrency0     

z_Cls.with_concurrencymax_batch_sizewait_msc                   rk  )	a  Create an instance of the Cls with dynamic batching enabled or overridden with new values.

        **Usage:**

        ```python notest
        Model = modal.Cls.from_name("my_app", "Model")
        ModelUsingGPU = Model.with_options(gpu="A100").with_batching(max_batch_size=100, batch_wait_ms=1000)
        ModelUsingGPU().generate.remote(42)  # will run on an A100 GPU with input concurrency enabled
        ```
        )r_   r`   c                    r\  r-   r]  r^  r`  r2   r3   rb  b  rl  z+_Cls.with_batching.<locals>._load_from_basec                   S   rc  r-   r2   r2   r2   r2   r3   r   i  rd  z!_Cls.with_batching.<locals>._depsz.with_batching(...)Tre  rm  )ro   rq  rr  batching_optionsrb  r   r_  r2   r`  r3   with_batchingT  rp  z_Cls.with_batchingc                 O   s   t | | j| j||S )z#This acts as the class constructor.)r   r   r   )ro   r   r   r2   r2   r3   __call__x  s   z_Cls.__call__c              	   C   sp   | j d urt| j |}t|tjjs|S dtdtdtdt	t
 fdd}tj|d| j d| d	d
d d| jdS )Nr   r   r   r   c                    s
   t d)NzYou can't access methods on a Cls directly - Did you forget to instantiate the class first?
e.g. instead of MyClass.method.remote(), do MyClass().method.remote())r   r   r2   r2   r3   error_loader  s   z&_Cls.__getattr__.<locals>.error_loaderzUnboundMethod(r   r   c                   S   rc  r-   r2   r2   r2   r2   r3   r     s    z"_Cls.__getattr__.<locals>.<lambda>Tr   )r   rG   rH   modalr   PartialFunctionr   r   r   r   r|   r   r   r   )ro   re   r  rv  r2   r2   r3   r     s(   

z_Cls.__getattr__c                 C   s
   | j d uS r-   r  r   r2   r2   r3   r     s   
z_Cls._is_local)r   r   )r,   r   )>rw   rx   ry   r   r   r   rz   rT   r   r|   r   r   r   FunctionHandleMetadatar   r   r   r   r   r   r   r   r   r   r  r  r  r   r  r   r3  r  r
   r  staticmethodr%  r8  classmethodrJ  r   r	   floatr{   r~   r&   r(   r   r)   r"   r'   r   rh  ro  rt  r   no_input_translationr   ru  r   r   r   __classcell__r2   r2   r   r3   r     s   
 

%)A
	
$}$$
cs)type_prefixc                    sF   |   I d H  |  }|j}|sJ |jj|jjkrtd|jjS )Nz@Can only get constructor args for strictly parameterized classes)hydrater  	_metadataclass_parameter_infoformat PARAM_SERIALIZATION_FORMAT_PROTOr$   schema)r   r   r	  r2   r2   r3   _get_constructor_args  s   r  c                    s.   |   I d H  | jsJ dd | j D S )Nc                 S   s   i | ]\}}||j qS r2   )function_schema)r0   r   r   r2   r2   r3   rg     s    z'_get_method_schemas.<locals>.<dictcomp>)r  r   rE   )r   r2   r2   r3   _get_method_schemas  s   
r  c                   @   s   e Zd Zdd ZdS )rI   c                 C   s   dS )Nzmodal.cls._NO_DEFAULT()r2   r   r2   r2   r3   __repr__  rd  z_NO_DEFAULT.__repr__N)rw   rx   ry   r  r2   r2   r2   r3   rI     s    rI   c                   @   s@   e Zd ZU eed< eed< dedefddZd	defddZdS )

_Parameterr=   initc                 C   s   || _ || _d S r-   r=   r  )ro   r=   r  r2   r2   r3   r8     s   
z_Parameter.__init__Nr,   c                 C   s    |r| j tu rtd| j S | S )Nz1field has no default value and no specified value)r=   _no_defaultr   )ro   objobj_typer2   r2   r3   __get__  s
   
z_Parameter.__get__r-   )rw   rx   ry   r   rz   r   r8   r  r2   r2   r2   r3   r    s
   
 r  pc                 C   s   t | to| jS r-   )rH   r  r  )r  r2   r2   r3   r/     s   r/   Tr  r=   r  c                 C   s   t | |dS )a  Used to specify options for modal.cls parameters, similar to dataclass.field for dataclasses
    ```
    class A:
        a: str = modal.parameter()

    ```

    If `init=False` is specified, the field is not considered a parameter for the
    Modal class and not used in the synthesized constructor. This can be used to
    optionally annotate the type of a field that's used internally, for example values
    being set by @enter lifecycle methods, without breaking type checkers, but it has
    no runtime effect on the class.
    r  )r  r  r2   r2   r3   	parameter  s   r  )\rh   rA   rC   collections.abcr   pathlibr   r   r   r   r   r   r	   google.protobuf.messager
   modal_protor   r   r   r   _load_contextr   _objectr   r   _partial_functionr   r   r   r   	_resolverr   
_resourcesr   _serializationr   
_tracebackr   _type_managerr   _utils.async_utilsr   r   _utils.deprecationr   r   r   _utils.mount_utilsr    r   r!   cloud_bucket_mountr"   	exceptionr#   r$   r%   rM  r&   rP  r'   secretr(   volumer)   r*   TYPE_CHECKING	modal.apprw  r   r   r<   rM   rS   	dataclassrT   r|   r   r   Objr   ClsClassParameterSpecr  r   FunctionSchemar  rI   r  r  r/   r  r2   r2   r2   r3   <module>   sj    -C     ^	"