o
    ;iA'                  	   @   s   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 ddl	m
Z
mZmZ ddlmZ dd	lmZ dd
lmZ ejrCd dlZdedee dedee fddZG dd dZdS )    N)Optional   )	_Function)LoadContext)live_method)"_find_partial_methods_for_user_cls_PartialFunction_PartialFunctionFlags)_Clientis_parameter)InvalidErrorportproxy_regionsstartup_timeoutexit_grace_periodc                 C   sr   t | tr| dk s| dkrtd|dkrtd|d ur%|dk r%td|d ur1|dkr1td|s7td	d S )
Nr   i  z4Port must be a positive integer between 1 and 65535.r   z0The `startup_timeout` argument must be positive.z6The `exit_grace_period` argument must be non-negative.   z<The `exit_grace_period` argument must not exceed 25 seconds.z/The `proxy_regions` argument must be non-empty.)
isinstanceintr   )r   r   r   r    r   A/home/ubuntu/.local/lib/python3.10/site-packages/modal/_server.pyvalidate_http_server_config   s   r   c                   @   st  e Zd ZU dZdZee ed< eed< dZ	ed ed< defdd	Z
d0d
dZdefddZedddefddZedeeeef  fddZeddddddee dee dee dee ddf
ddZd1dee dd fddZedddddedd fd d!Zeddd"d#ed  d$ed%ed&ee dee dd fd'd(Zdefd)d*Zeddd+efd,d-Zed2d.d/ZdS )3_Serverab  Server runs an HTTP server started in an `@modal.enter` method.

    See [lifecycle hooks](https://modal.com/docs/guide/lifecycle-functions) for more information.

    Generally, you will not construct a Server directly.
    Instead, use the [`@app._experimental_server()`](https://modal.com/docs/reference/modal.App#server) decorator.

    ```python notest
    @app._experimental_server(port=8000, proxy_regions=["us-east", "us-west"])
    class MyServer:
        @modal.enter()
        def start_server(self):
            self.process = subprocess.Popen(["python3", "-m", "http.server", "8080"])
    ```
    N	_user_cls_service_functionmodal.app._App_appreturnc                 C   s   | j d usJ | j S Nr   selfr   r   r   _get_user_cls>   s   z_Server._get_user_clsc                 C   s   | j sJ | j S r   )r   r    r   r   r   _get_appB   s   
z_Server._get_appc                 C   s   | j S r   )r   r    r   r   r   _get_service_functionF   s   z_Server._get_service_functionwrapped_user_clstype | _PartialFunctionc                 C   s   t | tr| js
J | jS | S r   )r   r   user_cls)r%   r   r   r   _extract_user_clsI   s   

z_Server._extract_user_clsc                    s8   dt dt fdd  fdd|   I d H pg D S )Nurlr   c                 S   s   |  dd dS )N.zmodal-)splitremoveprefix)r)   r   r   r   _extract_region_from_urlU   s   z2_Server.get_urls.<locals>._extract_region_from_urlc                    s   i | ]} ||qS r   r   ).0r)   r.   r   r   
<dictcomp>X   s    z$_Server.get_urls.<locals>.<dictcomp>)strr$   _experimental_get_flash_urlsr    r   r0   r   get_urlsS   s
   
z_Server.get_urls)min_containersmax_containersbuffer_containersscaledown_windowr5   r6   r7   r8   c                   s   |   j||||dI dH S )a  Override the current autoscaler behavior for this Server.

        Unspecified parameters will retain their current value.

        Examples:
        ```python notest
        server = modal.Server.from_name("my-app", "Server")

        # Always have at least 2 containers running, with an extra buffer of 2 containers
        server.update_autoscaler(min_containers=2, buffer_containers=1)

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

        )r5   r6   r8   r7   N)r$   update_autoscaler)r!   r5   r6   r7   r8   r   r   r   r9   ]   s   z_Server.update_autoscalerclientc                    s   |   }||I d H  | S r   )r$   hydrate)r!   r:   service_functionr   r   r   r;   ~   s   z_Server.hydrateappr<   c                 C   s&   t | }t  }||_||_||_|S )z.Create a Server from a local class definition.)r   r(   r   r   r   )r%   r=   r<   r'   serverr   r   r   _from_local   s   

z_Server._from_local)environment_namer:   clsapp_namenamer@   c                C   s(   t ||d}t }tj|||d|_|S )aB  Reference a Server 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 notest
        server = modal.Server.from_name("other-app", "Server")
        ```
        )r:   r@   )load_context_overrides)r   r   r   
_from_namer   )rA   rB   rC   r@   r:   rD   r>   r   r   r   	from_name   s   z_Server.from_namec                 C   s
   | j duS )z<Returns True if this Server has local source code available.Nr   r    r   r   r   	_is_local   s   
z_Server._is_localenable_memory_snapshotc                 C   s  t | }t|stddd |j D }|r#td|j dt	|t
js3t	|t
js3tdt	|t
j rDtd|j dt	|t
jrP|sPtdt| tr| jt
j@ rdtd|j d	| jt
j@ rstd|j d
| jt
j@ rtd|j dd S d S )NzBThe @app._experimental_server() decorator must be used on a class.c                 S   s   i | ]\}}t |r||qS r   r   )r/   kvr   r   r   r1      s    zA_Server._validate_wrapped_user_cls_decorators.<locals>.<dictcomp>Server class zG cannot use modal.parameter(). Servers do not support parameterization.z=Server class must have an @modal.enter() to setup the server.zW cannot have `@modal.method()` decorated functions. Servers only expose HTTP endpoints.z\Server must have `enable_memory_snapshot=True` to use `snap=True` on `@modal.enter` methods.z_ cannot be decorated with `@modal.concurrent()`. Please use `target_concurrency` param instead.z` cannot have @modal.experimental.http_server() decorator. Servers already expose HTTP endpoints.zW cannot be decorated with `@modal.web_server()`. Servers already expose HTTP endpoints.)r   r(   inspectisclass	TypeError__dict__itemsr   __name__r   r	   ENTER_PRE_SNAPSHOTENTER_POST_SNAPSHOTCALLABLE_INTERFACEvaluesr   r   flags
CONCURRENTHTTP_WEB_INTERFACEWEB_INTERFACE)r%   rH   r'   paramsr   r   r   %_validate_wrapped_user_cls_decorators   sP   




z-_Server._validate_wrapped_user_cls_decoratorsc                 C   s,   t | }|jtjkrtd|j ddS )zAValidate that the server class doesn't have a custom constructor.rK   z[ cannot have a custom __init__ method. Use @modal.enter() for initialization logic instead.N)r   r(   __init__objectr   rQ   )r%   r'   r   r   r    _validate_construction_mechanism   s   
z(_Server._validate_construction_mechanism)r   r   r   )r%   r&   )rQ   
__module____qualname____doc__r   r   type__annotations__r   r   r"   r#   r$   staticmethodr(   r   dictr2   r4   r   r9   r
   r;   r?   classmethodrF   boolrG   r[   r^   r   r   r   r   r   )   s   
 
		 9r   )rL   typingr   
_functionsr   _load_contextr   _objectr   _partial_functionr   r   r	   r:   r
   rA   r   	exceptionr   TYPE_CHECKING	modal.appmodalr   listr2   r   r   r   r   r   r   <module>   s,   
