o
    ;io                     @   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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 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 d d
l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,m-Z- d dl.m/Z/ d dl0m1Z1 ej2rd dlZd dlZd dl'Zd dl3m4Z4 eG dd dZ5dededeedef  ddfddZ6e
deddde7e8e5f ded fddZ9d d! Z:d"d# Z;ddd$e1jfd%d&Z<G d'd( d(ed)Z=d*ed+e1j>ddfd,d-Z?ddd$e1jfd.d/Z@dOd0d1ZAeG d2d3 d3e=ZBG d4d5 d5ZCeG d6d7 d7eCe=ZDeG d8d9 d9eCe=ZEd:ejFjGd;eHedf d<e7e8ef dejfd=d>ZId$e1jd?eedef  de=fd@dAZJd$e1jdBeeK dejLeKejFjMejNjOf fdCdDZPd$e1jdEe1jQdFe8dGdHdBeeK de=fdIdJZRd$e1jdEe1jQdGdHdBeeK de=f
dKdLZSd$e1jde(fdMdNZTdS )P    N)ABCMetaabstractmethod)contextmanager)	dataclass)AnyCallable	GeneratorOptionalSequence)Function)	_Function)_find_callables_for_obj_PartialFunctionFlags)UserCodeEventLoop)synchronizer)LocalFunctionErrorcallable_has_non_self_paramsis_asyncis_global_object)_App)logger)ExecutionErrorInvalidError)_FlashContainerEntry)api_pb2)LifespanManagerc                   @   sJ   e Zd ZU edef ed< eed< eed< ed ed< dZe	d ed	< dS )
FinalizedFunction.callabler   is_generatorzapi_pb2.DataFormat.ValueTypesupported_output_formatsNr   lifespan_manager)
__name__
__module____qualname__r   r   __annotations__boolr
   r    r	    r&   r&   T/home/ubuntu/.local/lib/python3.10/site-packages/modal/_runtime/user_code_imports.pyr   ,   s   
 r   
event_loopcontainer_io_managerfuncs.returnc                 C   sd   |  $ |D ]}t|rdnd}|| }t|r| | qW d   dS 1 s+w   Y  dS )zJCall function(s), can be sync or async, but any return values are ignored.NNNr&   N)handle_user_exceptionr   inspectiscoroutinerun)r(   r)   r*   funcargsresr&   r&   r'   call_lifecycle_functions5   s   


"r4   6modal._runtime.container_io_manager.ContainerIOManagerfinalized_functionsr,   c                 c   sd   g }zr|  D ],}|jr4|| |j  |  | |j  W d    n1 s/w   Y  qd V  W z2|  D ]!}|jr_|  | |j  W d    n1 sZw   Y  q>W |D ]}|	  qcd S |D ]}|	  qnw z1|  D ]!}|jr|  | |j  W d    n1 sw   Y  q{W |D ]}|	  qw |D ]}|	  qw N)
valuesr    appendcreate_taskbackground_taskr-   r0   lifespan_startuplifespan_shutdowncancel)r(   r)   r6   lifespan_background_tasksfinalized_functiontaskr&   r&   r'   lifecycle_asgiD   sN   







rB   c                  C   s(   t  t jt j} t  t jt j}| |fS r7   )signalSIGINTSIG_IGNSIGUSR1int_handlerusr1_handlerr&   r&   r'   disable_signalsa   s   rJ   c                 C   s8   | d ur|d urt  t j|  t  t j| d S d S d S r7   )rC   rD   rF   rG   r&   r&   r'   try_enable_signalsg   s   rK   function_defc                 C   s   |  dd |jD  d S )Nc                 S   s   g | ]}|j r|jqS r&   )allow_background_commits	volume_id).0vr&   r&   r'   
<listcomp>p   s    z!volume_commit.<locals>.<listcomp>)volume_commitvolume_mountsr)   rL   r&   r&   r'   rR   m   s   rR   c                
   @   s   e Zd ZU dZeed< ded< eed  ed< ej	ed< e
dej	d	d
deedf fddZeded	d
ded fddZeded	d
ded fddZeded	d
deeedf ddf fddZdS )Servicea  Common interface for singular functions and class-based "services"

    There are differences in the importing/finalization logic, and this
    "protocol"/abc basically defines a common interface for the two types
    of "Services" after the point of import.
    user_cls_instancemodal.app._Appappmodal._object._Objectservice_depsrL   fun_defr)   r5   r+   r   c                 C   s   d S r7   r&   selfr[   r)   r&   r&   r'   get_finalized_functions      zService.get_finalized_functionsr(   r,   c                 c       d V  d S r7   r&   r]   r(   r)   r&   r&   r'   lifecycle_presnapshot      
zService.lifecycle_presnapshotc                 c   r`   r7   r&   ra   r&   r&   r'   lifecycle_postsnapshot   rc   zService.lifecycle_postsnapshotNc                 c   sP   d\}}z|  ||j t|| j t| | ||J |  | | j|}W d   n1 s4w   Y  t||| z
|V  W t \}}nt \}}w W d   n1 s[w   Y  W d   n1 sjw   Y  W d   n1 syw   Y  W zt	|| j W t
|| dS t
|| w zt	|| j W t
|| w t
|| w )a  
        Manages the lifecycle of the user code:
        1. Runs pre-snapshot 'enter' methods
        2. Calls maybe_snapshot(container_io_manager, function_def)
        3. Creates breakpoint wrapper
        4. Runs post-snapshot 'enter' methods
        5. Initializes finalized functions (and ASGI/WSGI lifespan)
        6. Yield finalized_functions for execution
        7. Handles cleanup (lifespan shutdown, 'exit' methods)
        )NNN)rb   maybe_snapshotrL   create_breakpoint_wrapperrd   r-   r^   rB   rJ   rR   rK   )r]   r(   r)   rH   rI   r6   r&   r&   r'   execution_context   s4   
zService.execution_context)r!   r"   r#   __doc__r   r$   r	   r
   r   r   r   dictstrr^   r   r   r   rb   rd   rg   r&   r&   r&   r'   rU   s   sL   
 

rU   )	metaclassuser_defined_callablewebhook_configc                 C   s   ddl m} |jtjkr||  |S |jtjkr ||  |S |jtjkr3||	| |j
|j|S |jtjkrY|   |d}|j}|j}|j|||d |||||S td|j )Nr   )asgis   eth0)timeoutzUnrecognized web endpoint type )modal._runtimern   typer   WEBHOOK_TYPE_ASGI_APPasgi_app_wrapperWEBHOOK_TYPE_WSGI_APPwsgi_app_wrapperWEBHOOK_TYPE_FUNCTIONmagic_fastapi_appmethodweb_endpoint_docsWEBHOOK_TYPE_WEB_SERVERget_ip_addressweb_server_portweb_server_startup_timeoutwait_for_web_serverweb_server_proxyr   )rl   rm   r)   rn   hostportstartup_timeoutr&   r&   r'   construct_webhook_callable   s$   
r   c                 C   s*   |j rtjddkr|   d S d S d S )NMODAL_ENABLE_SNAP_RESTORE1)is_checkpointing_functionosenvirongetmemory_snapshotrT   r&   r&   r'   re      s   re   c                    s    fdd}|t _d S )Nc                     sD    j dd dd l} t }|d ur|j}|  | d S td)NT)from_breakpointr   zNo current frame found)interactpdbr.   currentframef_backPdb	set_traceRuntimeError)r   current_frameframer)   r&   r'   breakpoint_wrapper   s   z5create_breakpoint_wrapper.<locals>.breakpoint_wrapper)sysbreakpointhook)r)   r   r&   r   r'   rf      s   
rf   c                   @   sh   e Zd ZU ejjed< eed  ed< dZ	e
jed< edef ed< de
jd	d
deedf fddZdS )ImportedFunctionrX   rY   rZ   NrL   ._user_defined_callabler[   r)   r5   r+   r   c                 C   s|   t | j}|jtjjk}|j}|js$dt| j|||j	p tj
tjgdiS t| j|j|\}}dt||dd|j	p:tjgdiS )N r   r   r   r   Tr   r    r   r   r   )get_is_asyncr   function_typer   r   FUNCTION_TYPE_GENERATORrm   rq   r   r   DATA_FORMAT_PICKLEDATA_FORMAT_CBORr   DATA_FORMAT_ASGI)r]   r[   r)   r   r   rm   web_callabler    r&   r&   r'   r^     s.   


z(ImportedFunction.get_finalized_functions)r!   r"   r#   modalrX   r   r$   r	   r
   rV   r   r   r   r   ri   rj   r^   r&   r&   r&   r'   r     s   
 

r   c                   @   sP   e Zd ZU dZeed< ejed< ede	ddfddZ
ede	ddfd	d
ZdS )_LifecycleManagerzLifecycle manager for class-based services (Cls and Server).

    Handles pre snapshot, post snapshot, and exit lifecycle handling
    rV   rL   r(   r)   r5   c                 c   s6    | j jst| jtj}t||t|  d V  d S r7   )	rL   is_auto_snapshotr   rV   r   ENTER_PRE_SNAPSHOTr4   listr8   )r]   r(   r)   pre_snapshot_methodsr&   r&   r'   rb   ?  s   
z'_LifecycleManager.lifecycle_presnapshotc                 c   s    t | jj}| jjs t| jtj}t||t	|
  |  z%d V  W | jjsD|  t| jtj}t||t	|
  |  d S d S | jjsd|  t| jtj}t||t	|
  |  w w r7   )r   rL   http_configr   r   rV   r   ENTER_POST_SNAPSHOTr4   r   r8   enterstopEXITclose)r]   r(   r)   flash_entrypost_snapshot_methodsexit_methodsr&   r&   r'   rd   M  s*   
z(_LifecycleManager.lifecycle_postsnapshotN)r!   r"   r#   rh   r   r$   r   r   r   r   rb   rd   r&   r&   r&   r'   r   6  s    
 
r   c                   @   sh   e Zd ZU eed< ded< eed  ed< eedf ed< e	j
ed< d	e	j
d
ddeedf fddZdS )ImportedClassrV   rW   rX   rY   rZ   z(modal._partial_function._PartialFunction_partial_functionsrL   r[   r)   r5   r+   r   c                 C   s   i }| j  D ]V\}}|j}|sJ t|}|jj}|jj}	|j| }
|| j	}|	r1|	j
tjkrCt||t||
jp?tjtjgd}nt||	|\}}t||dd|
jpVtjgd}|||< q|S )Nr   Tr   )r   itemsraw_fr   paramsr   rm   method_definitions__get__rV   rq   r   WEBHOOK_TYPE_UNSPECIFIEDr   r%   r   r   r   r   r   )r]   r[   r)   r6   method_name_partial	user_funcr   r   rm   
method_def
bound_funcr@   r   r    r&   r&   r'   r^   n  s:   



z%ImportedClass.get_finalized_functionsN)r!   r"   r#   r   r$   r	   r
   ri   rj   r   r   r^   r&   r&   r&   r'   r   e  s   
 

r   c                   @   sX   e Zd ZU eed< ded< eed  ed< ejed< dejdd	d
e	e
df fddZdS )ImportedServerrV   rW   rX   rY   rZ   rL   r[   r)   r5   r+   r   c                 C   s   i S r7   r&   r\   r&   r&   r'   r^     r_   z&ImportedServer.get_finalized_functionsN)r!   r"   r#   r   r$   r	   r
   r   r   ri   rj   r^   r&   r&   r&   r'   r     s   
 

r   _clsr2   kwargsc                 C   s6   t tjjt| }||i |}d|_| }|S )a  Returns instance of the underlying class to be used as the `self`

    For the time being, this is an instance of the underlying user defined type, with
    some extra attributes like parameter values and _modal_functions set, allowing
    its methods to be used as modal Function objects with .remote() and .local() etc.

    TODO: Could possibly change this to use an Obj to clean up the data model? would invalidate isinstance checks though
    T)	typingcastr   clsClsr   _translate_out_entered_cached_user_cls_instance)r   r2   r   r   	modal_objrV   r&   r&   r'   get_user_class_instance  s
   	r   ser_func           
      C   s   d}|dur|}t | }nNt| j}| jp| j}t|s!td|d}t	|dkr3t
d| t||}t|trUt|}	|	jdd}|	 }|	jsQJ |	j}n|}t | }t||| |dS )	aH  Imports a function dynamically, and locates the app.

    This is somewhat complex because we're dealing with 3 quite different type of functions:
    1. Functions defined in global scope and decorated in global scope (Function objects)
    2. Functions defined in global scope but decorated elsewhere (these will be raw callables)
    3. Serialized functions

    In addition, we also need to handle
    * Normal functions
    * Methods on classes (in which case we need to instantiate the object)

    This helper also handles web endpoints, ASGI/WSGI servers, and HTTP servers.

    In order to locate the app, we try two things:
    * If the function is a Function, we can get the app directly from it
    * Otherwise, use the app name and look it up from a global list of apps: this
      typically only happens in case 2 above, or in sometimes for case 3

    Note that `import_function` is *not* synchronized, because we need it to run on the main
    thread. This is so that any user code running in global scope (which executes as a part of
    the import) runs on the right thread.
    Nz8Attempted to load a function defined in a function scope.   zInvalid function qualname Tonly_explicit_mounts)rX   rZ   rL   r   )get_active_app_fallback	importlibimport_modulemodule_nameimplementation_namefunction_namer   r   splitlenr   getattr
isinstancer   r   _translate_indeps	get_raw_f_appr   )
rL   r   rZ   rl   
active_appmodule	qual_namepartsf	_functionr&   r&   r'   import_single_function_service  s4   





r   ser_user_clsc                 C   s   | j tjjkr|d usJ |}|S t| j}| j}t|s"t	d|
d}t|dksAt|dkr9|d dksAtd| d| jrFJ |d }t||}|S )	Nz5Attempted to load a class defined in a function scoper   r      *z6Internal error: Invalid 'service function' identifier z. Please contact Modal supportr   )definition_typer   r   DEFINITION_TYPE_SERIALIZEDr   r   r   r   r   r   r   r   r   use_method_namer   )rL   r   cls_or_user_clsr   r   r   cls_namer&   r&   r'   _get_cls_or_user_cls  s"   
$


r   service_function_hydration_dataclass_idclientzmodal.client.Clientc                 C   s   t t jttjjf t| |}t|tjjr0t tjj	t
|}| }	|	jdd}
|	j}n.d}
t| }t dt
|}tjjj|j||jdd}tjj	|||}|||t  | }t|||}t|||
|| dS )z}
    This imports a full class to be able to execute any @method or webhook decorated methods.

    See import_function.
    Tr   Nmodal.client._Clientis_another_app)rV   rX   rZ   r   rL   )r   r   Unionrq   r   r   r   r   r   _Clsr   r   _get_class_service_functionr   rX   r   
_functionsr   _new_hydrated	object_idfunction_handle_metadata
from_local_hydrater   ClassHandleMetadata_get_partial_functionsr   r   )rL   r   r   r   r   cls_args
cls_kwargsr   r   class_service_functionrZ   r   _client_service_functionmethod_partialsrV   r&   r&   r'   import_class_service  s:   r  c                 C   s   t t jttjjf t| |}t|tjjr1t tj	j
t|}| }|jdd}| }n%d}t| }t dt|}	tjjj|j|	|jdd}
tj	j
|||
}| }t| ||| dS )z]
    This imports a class as a server to server HTTP requests.

    See import_function.
    Tr   Nr   r   )rV   rX   rZ   rL   )r   r   r   rq   r   serverServerr   r   _server_Serverr   r   _get_service_functionr   _get_appr   r   r   r   r   r   _from_local_get_user_clsr   )rL   r   r   r   r   r
  server_service_functionrZ   r   r  r  user_clsr&   r&   r'   import_server_serviceQ  s4   
r  c                 C   sn   | j pd }tj|g }t|dkr|d }|S t|dkr4|d ur)d| d}nd}td| d t S )Nr   r   zapp with the same name ('z')zunnamed appzYou have more than one zJ. It's recommended to name all your Apps uniquely when using multiple apps)app_namer   	_all_appsr   r   r   warning)rL   r  matching_appsr   warning_sub_messager&   r&   r'   r     s   

r   )r)   r5   )Ur   r.   r   rC   r   r   abcr   r   
contextlibr   dataclassesr   r   r   r   r	   r
   modal._objectr   #modal._runtime.container_io_manager	modal.clsmodal.serverr   modal._functionsr   modal._partial_functionr   r   #modal._runtime.user_code_event_loopr   modal._utils.async_utilsr   modal._utils.function_utilsr   r   r   r   r   	modal.appr   modal.configr   modal.exceptionr   r   modal.experimental.flashr   modal_protor   TYPE_CHECKINGmodal._runtime.asgir   r   r4   ri   rj   rB   rJ   rK   rR   rU   WebhookConfigr   re   rf   r   r   r   r   r   r   tupler   r   rq   r   r   r  r	  r   Objectr  r  r   r&   r&   r&   r'   <module>   s   


R
(

0/30
E

9
2