U
    e*                     @  s  d dl mZ d dlZd dlZd dlZejdkr<d dlmZ nd dlmZ d dlm	Z	m
Z
 d dl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mZm Z m!Z! d dl"m#Z# ej$dddZ%edZ&G dd dZ'dS )    )annotationsN)   
   )	ParamSpec)StateURLPath)
Middleware_MiddlewareClass)BaseHTTPMiddleware)ServerErrorMiddleware)ExceptionMiddleware)Request)Response)	BaseRouteRouter)ASGIAppExceptionHandlerLifespanReceiveScopeSend)	WebSocketAppType	Starlette)boundPc                   @  sf  e Zd ZdZdSdddddd	d	d
dd	ddZddddZeddddZddddddZdddddd d!Z	dd"d#d$d%Z
dTddd&dd'd(d)ZdUddd&dd*d+d,Zd-d.d/dd0d1d2Zd3d4dd5d6d7Zdd"dd8d9d:ZdVdd<d=d>ddd?d@dAZdWddBd&ddCdDdEZd3d"dFdGdHZdXddId&dd"dJdKdLZdYdd&d"dMdNdOZdd"dPdQdRZdS )Zr   aC  
    Creates an application instance.

    **Parameters:**

    * **debug** - Boolean indicating if debug tracebacks should be returned on errors.
    * **routes** - A list of routes to serve incoming HTTP and WebSocket requests.
    * **middleware** - A list of middleware to run for every request. A starlette
    application will always automatically include two middleware classes.
    `ServerErrorMiddleware` is added as the very outermost middleware, to handle
    any uncaught errors occurring anywhere in the entire stack.
    `ExceptionMiddleware` is added as the very innermost middleware, to deal
    with handled exception cases occurring in the routing or endpoints.
    * **exception_handlers** - A mapping of either integer status codes,
    or exception class types onto callables which handle the exceptions.
    Exception handler callables should be of the form
    `handler(request, exc) -> response` and may be either standard functions, or
    async functions.
    * **on_startup** - A list of callables to run on application startup.
    Startup handler callables do not take any arguments, and may be either
    standard functions, or async functions.
    * **on_shutdown** - A list of callables to run on application shutdown.
    Shutdown handler callables do not take any arguments, and may be either
    standard functions, or async functions.
    * **lifespan** - A lifespan context function, which can be used to perform
    startup and shutdown tasks. This is a newer style that replaces the
    `on_startup` and `on_shutdown` handlers. Use one or the other, not both.
    FNr   boolz!typing.Sequence[BaseRoute] | Nonez"typing.Sequence[Middleware] | Nonez3typing.Mapping[typing.Any, ExceptionHandler] | Nonez7typing.Sequence[typing.Callable[[], typing.Any]] | NonezLifespan[AppType] | NoneNone)	selfdebugroutes
middlewareexception_handlers
on_startupon_shutdownlifespanreturnc                 C  sv   |d ks |d kr|d ks t d|| _t | _t||||d| _|d krLi nt|| _|d krbg nt|| _	d | _
d S )Nz>Use either 'lifespan' or 'on_startup'/'on_shutdown', not both.)r#   r$   r%   )AssertionErrorr   r   stater   routerdictr"   listuser_middlewaremiddleware_stack)r   r   r    r!   r"   r#   r$   r%    r.   :/tmp/pip-unpacked-wheel-2mv5qoba/starlette/applications.py__init__9   s&       zStarlette.__init__r   )r&   c                 C  s   | j }d }i }| j D ]"\}}|dtfkr2|}q|||< qtt||dg| j tt||dg }| j}t	|D ]\}}	}
||	d|i|
}qp|S )Ni  )handlerr   )handlersr   app)
r   r"   items	Exceptionr   r   r,   r   r)   reversed)r   r   Zerror_handlerr"   keyvaluer!   r3   clsargskwargsr.   r.   r/   build_middleware_stackT   s.    
  
z Starlette.build_middleware_stackzlist[BaseRoute]c                 C  s   | j jS N)r)   r    r   r.   r.   r/   r    p   s    zStarlette.routesstrz
typing.Anyr   )namepath_paramsr&   c                K  s   | j j|f|S r=   )r)   url_path_for)r   r@   rA   r.   r.   r/   rB   t   s    zStarlette.url_path_forr   r   r   )scopereceivesendr&   c                   s4   | |d< | j d kr|  | _ |  |||I d H  d S )Nr3   )r-   r<   )r   rC   rD   rE   r.   r.   r/   __call__w   s    

zStarlette.__call__typing.Callable)
event_typer&   c                 C  s   | j |S r=   )r)   on_event)r   rH   r.   r.   r/   rI   }   s    zStarlette.on_eventz
str | None)pathr3   r@   r&   c                 C  s   | j j|||d d S N)r3   r@   )r)   mount)r   rJ   r3   r@   r.   r.   r/   rL      s    zStarlette.mount)hostr3   r@   r&   c                 C  s   | j j|||d d S rK   )r)   rM   )r   rM   r3   r@   r.   r.   r/   rM      s    zStarlette.hostz typing.Type[_MiddlewareClass[P]]zP.argszP.kwargs)middleware_classr:   r;   r&   c                 O  s0   | j d k	rtd| jdt|f|| d S )Nz6Cannot add middleware after an application has startedr   )r-   RuntimeErrorr,   insertr   )r   rN   r:   r;   r.   r.   r/   add_middleware   s    
zStarlette.add_middlewarezint | typing.Type[Exception]r   )exc_class_or_status_coder1   r&   c                 C  s   || j |< d S r=   )r"   )r   rR   r1   r.   r.   r/   add_exception_handler   s    zStarlette.add_exception_handler)rH   funcr&   c                 C  s   | j || d S r=   )r)   add_event_handler)r   rH   rT   r.   r.   r/   rU      s    zStarlette.add_event_handlerTzAtyping.Callable[[Request], typing.Awaitable[Response] | Response]z!typing.Optional[typing.List[str]]ztyping.Optional[str])rJ   routemethodsr@   include_in_schemar&   c                 C  s   | j j|||||d d S N)rW   r@   rX   r)   	add_route)r   rJ   rV   rW   r@   rX   r.   r.   r/   r[      s        zStarlette.add_routez4typing.Callable[[WebSocket], typing.Awaitable[None]])rJ   rV   r@   r&   c                 C  s   | j j|||d d S N)r@   r)   add_websocket_route)r   rJ   rV   r@   r.   r.   r/   r^      s    zStarlette.add_websocket_route)rR   r&   c                   s&   t dt ddd fdd}|S )NzThe `exception_handler` decorator is deprecated, and will be removed in version 1.0.0. Refer to https://www.starlette.io/exceptions/ for the recommended approach.rG   rT   r&   c                   s     |  | S r=   )rS   rT   rR   r   r.   r/   	decorator   s    z.Starlette.exception_handler.<locals>.decoratorwarningswarnDeprecationWarning)r   rR   rb   r.   ra   r/   exception_handler   s    zStarlette.exception_handlerzlist[str] | None)rJ   rW   r@   rX   r&   c                   s,   t dt ddd fdd}|S )z
        We no longer document this decorator style API, and its usage is discouraged.
        Instead you should use the following approach:

        >>> routes = [Route(path, endpoint=...), ...]
        >>> app = Starlette(routes=routes)
        zThe `route` decorator is deprecated, and will be removed in version 1.0.0. Refer to https://www.starlette.io/routing/ for the recommended approach.rG   r_   c                   s   j j|  d | S rY   rZ   r`   rX   rW   r@   rJ   r   r.   r/   rb      s    z"Starlette.route.<locals>.decoratorrc   )r   rJ   rW   r@   rX   rb   r.   rh   r/   rV      s    
zStarlette.route)rJ   r@   r&   c                   s(   t dt ddd fdd}|S )a  
        We no longer document this decorator style API, and its usage is discouraged.
        Instead you should use the following approach:

        >>> routes = [WebSocketRoute(path, endpoint=...), ...]
        >>> app = Starlette(routes=routes)
        zThe `websocket_route` decorator is deprecated, and will be removed in version 1.0.0. Refer to https://www.starlette.io/routing/#websocket-routing for the recommended approach.rG   r_   c                   s   j j|  d | S r\   r]   r`   r@   rJ   r   r.   r/   rb      s    z,Starlette.websocket_route.<locals>.decoratorrc   )r   rJ   r@   rb   r.   ri   r/   websocket_route   s    zStarlette.websocket_route)middleware_typer&   c                   s4   t dt |dkstdddd fdd}|S )z
        We no longer document this decorator style API, and its usage is discouraged.
        Instead you should use the following approach:

        >>> middleware = [Middleware(...), ...]
        >>> app = Starlette(middleware=middleware)
        zThe `middleware` decorator is deprecated, and will be removed in version 1.0.0. Refer to https://www.starlette.io/middleware/#using-middleware for recommended approach.httpz/Currently only middleware("http") is supported.rG   r_   c                   s    j t| d | S )N)dispatch)rQ   r
   r`   r>   r.   r/   rb     s    z'Starlette.middleware.<locals>.decorator)rd   re   rf   r'   )r   rk   rb   r.   r>   r/   r!      s    zStarlette.middleware)FNNNNNN)N)N)NNT)N)NNT)N)__name__
__module____qualname____doc__r0   r<   propertyr    rB   rF   rI   rL   rM   rQ   rS   rU   r[   r^   rg   rV   rj   r!   r.   r.   r.   r/   r      sB           
        )(
__future__r   systypingrd   version_infor   Ztyping_extensionsZstarlette.datastructuresr   r   Zstarlette.middlewarer   r	   Zstarlette.middleware.baser
   Zstarlette.middleware.errorsr   Zstarlette.middleware.exceptionsr   Zstarlette.requestsr   Zstarlette.responsesr   Zstarlette.routingr   r   Zstarlette.typesr   r   r   r   r   r   Zstarlette.websocketsr   TypeVarr   r   r   r.   r.   r.   r/   <module>   s&   
 