o
    㥵iD                     @  s  d dl 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 d dlmZ d dlmZmZmZmZ dd	lmZmZmZ d
dlmZmZmZ d
dlmZmZ d
dlmZmZm Z m!Z! G dd de"Z#G dd de"Z$G dd dej%e! Z&G dd dej'ej%e! Z(d"d#ddZ)G dd dej*ee!  e(e! ej%e! Z+ej,dej-e dZ.G dd de/Z0G d d! d!e(e! ej%e! Z1dS )$    )annotationsN)deepcopy)reduce)compile_path)cached_property)LiteralSelfget_args
get_origin   )FFFsafe_issubclass   )	BaseRoute	HttpRouteSocketRoute)	RadixTree	RouteType)AsyncViewTypeMiddlewareTypeSyncViewTypeViewTypec                   @     e Zd ZdZdS )NoMatchFoundz@
    Raised by `.search(path)` if no matching route exists.
    N__name__
__module____qualname____doc__ r    r    G/home/ubuntu/.local/lib/python3.10/site-packages/kui/routing/routers.pyr          r   c                   @  r   )NoRouteFoundzP
    Raised by `.url_for(name, **path_params)` if no matching route exists.
    Nr   r    r    r    r!   r#      r"   r#   c                   @  s   e Zd ZdZd,ddZed-d	d
Zed.ddZdg ddddd/ddZdg ddddd0d d!Z	dg ddddd0d"d#Z
dg ddddd0d$d%Zdg ddddd0d&d'Zdg ddddd0d(d)Zdg ddddd0d*d+ZdS )1HttpRegisterz
    shortcut for `self << HttpRoute(path, endpoint, name)`

    example:
    ```python
        @routes.http("/path", name="endpoint-name")
        class Endpoint(HttpViewType): ...
    ```
    routesRouteRegisterMixin[ViewType]returnNonec                 C  s
   || _ d S N)_HttpRegister__routesselfr%   r    r    r!   __init__+      
zHttpRegister.__init__&typing.Callable[[str], MiddlewareType]c                 C  t   | j D ]-}tt|tr0t|d }|tkr ddlm} |  S |tkr.ddl	m} |  S t
qt
| jj d)Nr   r   )required_method must be used with ViewType)__orig_bases__r   r
   r$   r	   r   
asgi.viewsr1   r   
wsgi.viewsRuntimeError	__class__r   )r,   origin_basegeneric_typer1   r    r    r!   _required_method.      
	zHttpRegister._required_method typing.Type[HttpRoute[ViewType]]c                 C  r0   )Nr   r   )r   r2   )r3   r   r
   r$   r	   r   asgi.routingr   r   wsgi.routingr6   r7   r   )r,   r8   r9   r   r    r    r!   _http_route<   r;   zHttpRegister._http_route NnamemiddlewaressummarydescriptiontagsmethodstrpathrB   typing.Optional[str]rC   typing.Iterable[MiddlewareType]rD   
str | NonerE   rF   typing.Iterable[str] | None%typing.Callable[[ViewType], ViewType]c          	   	     s    d fdd}|S )zJ
        if method == "any", all request method would be allowed.
        endpointr   r'   c                   sN    |  }dkr|  }ttj|  j|K  _| S )Nany)r?   r:   upperr   operatormatmulr*   )rO   routerE   rG   rC   rB   rI   r,   rD   rF   r    r!   registerY   s   z4HttpRegister._register_with_method.<locals>.registerNrO   r   r'   r   r    )	r,   rG   rI   rB   rC   rD   rE   rF   rV   r    rU   r!   _register_with_methodJ   s   z"HttpRegister._register_with_methodc             	   C     | j d||||||dS )z
        shortcut for `self << HttpRoute(path, endpoint, name)`

        example:
        ```python
            @routes.http("/path", name="endpoint-name")
            class Endpoint(HttpViewType): ...
        ```
        rP   rA   rX   r,   rI   rB   rC   rD   rE   rF   r    r    r!   __call__g      zHttpRegister.__call__c             	   C  rY   )z
        shortcut for `self << HttpRoute(path, endpoint, name) @ required_method("GET")`

        example:
        ```python
            @routes.http.get("/path", name="endpoint-name")
            class Endpoint(HttpViewType): ...
        ```
        getrA   rZ   r[   r    r    r!   r^      r]   zHttpRegister.getc             	   C  rY   )z
        shortcut for `self << HttpRoute(path, endpoint, name) @ required_method("POST")`

        example:
        ```python
            @routes.http.post("/path", name="endpoint-name")
            class Endpoint(HttpViewType): ...
        ```
        postrA   rZ   r[   r    r    r!   r_      r]   zHttpRegister.postc             	   C  rY   )z
        shortcut for `self << HttpRoute(path, endpoint, name) @ required_method("PUT")`

        example:
        ```python
            @routes.http.put("/path", name="endpoint-name")
            class Endpoint(HttpViewType): ...
        ```
        putrA   rZ   r[   r    r    r!   r`      r]   zHttpRegister.putc             	   C  rY   )z
        shortcut for `self << HttpRoute(path, endpoint, name) @ required_method("PATCH")`

        example:
        ```python
            @routes.http.patch("/path", name="endpoint-name")
            class Endpoint(HttpViewType): ...
        ```
        patchrA   rZ   r[   r    r    r!   ra      r]   zHttpRegister.patchc             	   C  rY   )a  
        shortcut for `self << HttpRoute(path, endpoint, name) @ required_method("DELETE")`

        example:
        ```python
            @routes.http.delete("/path", name="endpoint-name")
            class Endpoint(HttpViewType): ...
        ```
        deleterA   rZ   r[   r    r    r!   rb      r]   zHttpRegister.delete)r%   r&   r'   r(   )r'   r/   )r'   r<   )rG   rH   rI   rH   rB   rJ   rC   rK   rD   rL   rE   rL   rF   rM   r'   rN   )rI   rH   rB   rJ   rC   rK   rD   rL   rE   rL   rF   rM   r'   rN   )r   r   r   r   r-   r   r:   r?   rX   r\   r^   r_   r`   ra   rb   r    r    r    r!   r$       sb    

!!!!!!r$   c                   @  sF   e Zd ZejdddZdd
dZedddZdg ddddZ	dS )RouteRegisterMixinr,   r   rT   BaseRoute[ViewType]r'   c                 C  s   t r)   )NotImplementedErrorr,   rT   r    r    r!   append  s   zRouteRegisterMixin.appendotherGtyping.Union[BaseRoute[ViewType], typing.Iterable[BaseRoute[ViewType]]]c                 C  sv   t |tr
| |S t |tjr9|D ]$}t |tr2t|ddr-|jr-t|dd |j |_|| | |> }q| S tS )z 
        self << routes
        	namespacer@   :)	
isinstancer   rg   typingIterablegetattrrB   extend_middlewaresNotImplemented)r,   rh   rT   _r    r    r!   
__lshift__  s   




zRouteRegisterMixin.__lshift__HttpRegister[ViewType]c                 C  sJ   | j D ]}tt|tr"t|d }G dd dt| }||   S qt)Nr   c                   @  s   e Zd ZdS )z.RouteRegisterMixin.http.<locals>._HttpRegisterN)r   r   r   r    r    r    r!   _HttpRegister5  s    ru   )r3   r   r
   rc   r	   r$   r6   )r,   r8   	view_typeru   r    r    r!   http/  s   
zRouteRegisterMixin.httpr@   )rB   rC   rI   rH   rB   rJ   rC   rK   rN   c                  s   d fdd}|S )z
        shortcut for `self << SocketRoute(path, endpoint, name)`

        example:
        ```python
            @routes.websocket("/path", name="endpoint-name")
            class Endpoint(SocketViewType): ...
        ```
        rO   r   r'   c                   s*   ddl m} ttj || > }| S )Nr   )r   )asgir   r   rR   rS   )rO   r   rr   rC   rB   rI   r,   r    r!   rV   L  s
   z.RouteRegisterMixin.websocket.<locals>.registerNrW   r    )r,   rI   rB   rC   rV   r    ry   r!   	websocket;  s   zRouteRegisterMixin.websocketNr,   r   rT   rd   r'   r   )r,   r   rh   ri   r'   r   )r'   rt   )rI   rH   rB   rJ   rC   rK   r'   rN   )
r   r   r   abcabstractmethodrg   rs   propertyrw   rz   r    r    r    r!   rc     s    
rc   rF   rM   c                   s   d fdd}|S )NrO   r   r'   c                   sF   | }t |r|j}n| }tt|dg t pg  }t|d| | S )N__docs_tags__)inspectismethod__func__listro   setattr)rO   stupid_type_checkerwall_tagsrF   r    r!   _set_tags_middlewareX  s   
z'_set_tags.<locals>._set_tags_middlewarerW   r    )rF   r   r    r   r!   	_set_tagsW  s   r   c                   @  s   e Zd Zddg g dd6ddZejd7ddZejd8ddZdd Zd9ddZd:d d!Zd;d#d$Z	d<d'd(Z
d<d)d*Zd=d.d/Zd>d2d3Zd>d4d5ZdS )?Routesr@   N)rj   rF   http_middlewaressocket_middlewaresiterableri   rj   rH   rF   rM   r   typing.Sequence[MiddlewareType]r   typing.Sequence[typing.Any]r'   r(   c                G  sF   || _ g | _t|| _| jt| t|| _|D ]}| |> }qd S r)   )rj   _listr   _http_middlewaresrg   r   _socket_middlewares)r,   rj   rF   r   r   r   rT   rr   r    r    r!   r-   k  s   



zRoutes.__init__indexintrd   c                 C     d S r)   r    r,   r   r    r    r!   __getitem__}     zRoutes.__getitem__slice typing.List[BaseRoute[ViewType]]c                 C  r   r)   r    r   r    r    r!   r     r   c                 C  s
   | j | S r)   )r   r   r    r    r!   r     r.   c                 C  s
   t | jS r)   )lenr   )r,   r    r    r!   __len__  r.   zRoutes.__len__r,   r   rT   c                 C  s   | j | | S r)   )r   rg   rf   r    r    r!   rg     s   zRoutes.appendrh   c                 C  s   t |tstS t||  S )z
        other // self
        )rl   rH   rq   Prefix)r,   rh   r    r    r!   __rfloordiv__  s   
zRoutes.__rfloordiv__r%   $typing.Iterable[BaseRoute[ViewType]]c                 C  s   t t  | > |> S )z
        self + routes
        r   r   r+   r    r    r!   __add__     zRoutes.__add__c                 C  s   t t  |> | > S )z
        routes + self
        r   r+   r    r    r!   __radd__  r   zRoutes.__radd__oobjectboolc                 C  s@   t |tjstS t|t| kott| |ttt	dd B S )Nc                 S  s   | |kS r)   r    )rr_r    r    r!   <lambda>  s    zRoutes.__eq__.<locals>.<lambda>)
rl   rm   Sequencerq   r   allzipr   mapr   )r,   r   r    r    r!   __eq__  s
   zRoutes.__eq__
middlewarer   c                 C  $   t | dkr
td| j| |S )a  
        append middleware in routes

        example:
        ```
            @routes.http_middleware
            def middleware(endpoint):
                async def wrapper():
                    return await endpoint()
                return wrapper
        ```
        r   %Can not append middleware after route)r   r6   r   rg   r,   r   r    r    r!   http_middleware     zRoutes.http_middlewarec                 C  r   )a  
        append middleware in routes

        example:
        ```
            @routes.socket_middleware
            def middleware(endpoint):
                async def wrapper():
                    await endpoint()
                return wrapper
        ```
        r   r   )r   r6   r   rg   r   r    r    r!   socket_middleware  r   zRoutes.socket_middleware)r   ri   rj   rH   rF   rM   r   r   r   r   r'   r(   )r   r   r'   rd   )r   r   r'   r   )r'   r   r{   )r,   r   rh   rH   r'   r   )r%   r   r'   r   )r   r   r'   r   )r   r   r'   r   )r   r   r   r-   rm   overloadr   r   rg   r   r   r   r   r   r   r    r    r    r!   r   f  s&    




	


r   _RouteSequence)boundc                   @  s    e Zd Zd
ddZdddZd	S )r   r'   r(   c                 O  s   |  dr
| drJ d S )N/)
startswithendswith)r,   argskwargsr    r    r!   r-     s   zPrefix.__init__rh   r   c                 C  s:   t |tjstS t|}|D ]}| |j |_qtt|S )z
        self // other
        )rl   rm   rn   rq   r   rI   castr   )r,   rh   resultrT   r    r    r!   __floordiv__  s   zPrefix.__floordiv__N)r'   r(   )rh   r   r'   r   )r   r   r   r-   r   r    r    r    r!   r     s    
r   c                   @  s>   e Zd Zg g fddd	ZdddZdddZi fd ddZdS )!Routerr%   r   r   r   r   r'   r(   c                 C  s@   t t  | _t t  | _i | _t|| _t|| _| | d S r)   )	r   r   	http_treewebsocket_treeroutes_mappingr   r   r   rs   )r,   r%   r   r   r    r    r!   r-     s   

zRouter.__init__r,   r   rT   rd   c                 C  s   t |tr|| j | j}nt |tr|| j | j}n	tdt	| |j
dkr/d|_
|j| jv r=td|j ||j
|j t|j
\}}|jrY|||jf| j|j< | S )Nz7Need type: `HttpRoute` or `SocketRoute`, but got type: r@   r   zDuplicate route name: )rl   r   _extend_middlewaresr   r   r   r   r   	TypeErrortyperI   rB   r   
ValueErrorrg   rO   r   )r,   rT   
radix_treepath_formatpath_convertorsr    r    r!   rg     s*   


zRouter.appendprotocolLiteral['http', 'websocket']rI   rH   Ktyping.Tuple[typing.Dict[str, typing.Any], typing.Callable[[], typing.Any]]c                   sr   |dkr| j }n|dkr| j}ntd||\}}|d u s#|d u r't||\} } fdd| D |fS )Nrw   rz   z+`protocol` must be in ('http', 'websocket')c                   s(   i | ]\}}| v r| |  |qS r    )	to_python.0rB   valueparam_convertorsr    r!   
<dictcomp>"  s
    z!Router.search.<locals>.<dictcomp>)r   r   r   searchr   items)r,   r   rI   r   rT   paramsrr   rO   r    r   r!   r     s   

zRouter.searchrB   path_paramstyping.Mapping[str, typing.Any]c                   sF   || j vrtd| d| j | \} }| fdd| D S )NzNo route with name 'z' existsc                   s    i | ]\}}| |  |qS r    )	to_stringr   r   r    r!   r   3  s    z"Router.url_for.<locals>.<dictcomp>)r   r#   
format_mapr   )r,   rB   r   r   rr   r    r   r!   url_for(  s   

zRouter.url_forN)r%   r   r   r   r   r   r'   r(   r{   )r   r   rI   rH   r'   r   )rB   rH   r   r   r'   rH   )r   r   r   r-   rg   r   r   r    r    r    r!   r     s    

r   r)   )rF   rM   )2
__future__r   r|   r   rR   rm   copyr   	functoolsr   baize.routingr   baize.utilsr   typing_extensionsr   r   r	   r
   utilsr   r   r   r%   r   r   r   treer   r   r   r   r   r   	Exceptionr   r#   Genericr$   ABCrc   r   r   r   TypeVarrn   r   rH   r   r   r    r    r    r!   <module>   s8     wA
j 