o
    NK&hd{                     @   s   d dl 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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! d dl"m#Z# ee!gee!e$ee!f f f Z%G dd deedZ&dS )    )NodeVisitorReturnparse)Iterable)suppress)	getsource	signature)dedent)AnyCallableOptionalUnioncast)Route)	SanicMeta)HTTP_METHODS)RESPONSE_MAPPING)	BaseMixin)FutureRouteFutureStatic)RouteHandler)HashableDictc                #   @   sR  e Zd Zd:ddZdedee fddZ														
	d;dede	e
e  de	eeee f  de	e dede	eeeef  de	e dedede	ee  dedededede	e dedef"ddZedhdddddd
ddf	dedede
e de	eeee f  de	e de	eeeef  de	e dedede	e dededefdd Z							
	d<dede	eeee f  de	e de	eeeef  de	e dedede	e dedefd!d"Z						
	d=dede	eeee f  de	e dede	eeeef  de	e dede	e dedefd#d$Z						
	d=dede	eeee f  de	e dede	eeeef  de	e dede	e dedefd%d&Z							
	d<dede	eeee f  de	e de	eeeef  de	e dedede	e dedefd'd(Z							
	d<dede	eeee f  de	e de	eeeef  de	e dedede	e dedefd)d*Z						
	d=dede	eeee f  de	e de	eeeef  de	e dede	e dedefd+d,Z						
	d>dede	eeee f  de	e de	eeeef  de	e dedede	e dedefd-d.Z								
	d?dede	eeee f  de	e de	ee  de	eeeef  de	e dedede	e defd/d0Z						
	d@dede	eeee f  de	e de	eeeef  de	e dede	e defd1d2Zdefd3d4Zd5d6 Zd7e eef de!fd8d9Z"dS )A
RouteMixinreturnNc                 O   s   t  | _t  | _d S N)set_future_routes_future_statics)selfargskwargs r!   F/var/www/html/venv/lib/python3.10/site-packages/sanic/mixins/routes.py__init__   s   zRouteMixin.__init__routec                 C   s   t r   )NotImplementedError)r   r$   r!   r!   r"   _apply_route#   s   zRouteMixin._apply_routeFT/vurimethodshoststrict_slashesstreamversionnameignore_bodyapplysubprotocols	websocketunquotestaticversion_prefixerror_format
ctx_kwargsc                    sz    dsstdrd 
du rj
s s tdh| 	
fdd}|S )a  Decorate a function to be registered as a route.

        Args:
            uri (str): Path of the URL.
            methods (Optional[Iterable[str]]): List or tuple of
                methods allowed.
            host (Optional[Union[str, List[str]]]): The host, if required.
            strict_slashes (Optional[bool]): Whether to apply strict slashes
                to the route.
            stream (bool): Whether to allow the request to stream its body.
            version (Optional[Union[int, str, float]]): Route specific
                versioning.
            name (Optional[str]): User-defined route name for url_for.
            ignore_body (bool): Whether the handler should ignore request
                body (e.g. `GET` requests).
            apply (bool): Apply middleware to the route.
            subprotocols (Optional[List[str]]): List of subprotocols.
            websocket (bool): Enable WebSocket support.
            unquote (bool): Unquote special characters in the URL path.
            static (bool): Enable static route.
            version_prefix (str): URL path that should be before the version
                 value; default: `"/v"`.
            error_format (Optional[str]): Error format for the route.
            ctx_kwargs (Any): Keyword arguments that begin with a `ctx_*`
                prefix will be appended to the route context (`route.ctx`).

        Returns:
            RouteWrapper: Tuple of routes, decorated function.

        Examples:
            Using the method to define a GET endpoint:

            ```python
            @app.route("/hello")
            async def hello(request: Request):
                return text("Hello, World!")
            ```

            Adding context kwargs to the route:

            ```python
            @app.route("/greet", ctx_name="World")
            async def greet(request: Request):
                name = request.route.ctx.name
                return text(f"Hello, {name}!")
            ```
        /routerNGETc                    s  t | tr	| \}} | t trtgnr5t ts5ztW n ty4   td w t tr?tn	t trHtrNdkrS	| t
| rZd ntdd D 
	}tdd}|rttfddj_j| tt| j }rt|d	k r| j}td
| d|s| j}td| ds	r	| _ rňj||d r|| fS | S )Nz:Expected either string or Iterable of host strings, not %sautoc                 S   s   g | ]}|  qS r!   )upper).0xr!   r!   r"   
<listcomp>   s    z7RouteMixin.route.<locals>.decorator.<locals>.<listcomp>_allow_route_overwriteFc                    s
   | j  kS r   r(   )r>   rA   r!   r"   <lambda>   s   
 z5RouteMixin.route.<locals>.decorator.<locals>.<lambda>   z8Required parameter `request` and/or `ws` missing in the z	() route?z,Required parameter `request` missing in the )	overwrite)
isinstancetuplegenerate_namestr	frozenset	TypeError
ValueErrorlistr   _determine_error_formatr   getattrfilterr   addr   
parameterskeyslen__name__	is_streamr&   )handler_r$   rD   r   handler_namer0   r6   r*   r/   r)   r.   route_contextr   r4   r,   r+   r1   r3   r(   r-   r5   r2   r!   r"   	decoratorv   s   





z#RouteMixin.route.<locals>.decorator)
startswithhasattrr+   rI   _build_route_context)r   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r[   r!   rY   r"   r$   &   s   E

,]zRouteMixin.router:   rV   c                 K   s   t |dr(t }tD ]}t|d}t|| d}|r'|| t |dr'd}q
|du r/| j}| jd||||||||	|
|d
|| |S )a  A helper method to register class-based view or functions as a handler to the application url routes.

        Args:
            handler (RouteHandler): Function or class-based view used as a route handler.
            uri (str): Path of the URL.
            methods (Iterable[str]): List or tuple of methods allowed; these are overridden if using an HTTPMethodView.
            host (Optional[Union[str, List[str]]]): Hostname or hostnames to match for this route.
            strict_slashes (Optional[bool]): If set, a route's slashes will be strict. E.g. `/foo` will not match `/foo/`.
            version (Optional[Union[int, str, float]]): Version of the API for this route.
            name (Optional[str]): User-defined route name for `url_for`.
            stream (bool): Boolean specifying if the handler is a stream handler.
            version_prefix (str): URL path that should be before the version value; default: ``/v``.
            error_format (Optional[str]): Custom error format string.
            unquote (bool): Boolean specifying if the handler requires unquoting.
            ctx_kwargs (Any): Keyword arguments that begin with a `ctx_*` prefix will be appended to the route context (``route.ctx``). See below for examples.

        Returns:
            RouteHandler: The route handler.

        Examples:
            ```python
            from sanic import Sanic, text

            app = Sanic("test")

            async def handler(request):
                return text("OK")

            app.add_route(handler, "/test", methods=["GET", "POST"])
            ```

            You can use `ctx_kwargs` to add custom context to the route. This
            can often be useful when wanting to add metadata to a route that
            can be used by other parts of the application (like middleware).

            ```python
            from sanic import Sanic, text

            app = Sanic("test")

            async def handler(request):
                return text("OK")

            async def custom_middleware(request):
                if request.route.ctx.monitor:
                    do_some_monitoring()

            app.add_route(handler, "/test", methods=["GET", "POST"], ctx_monitor=True)
            app.register_middleware(custom_middleware)
        
view_classNrU   T)
r(   r)   r*   r+   r,   r-   r.   r5   r6   r3   r!   )r]   r   r   rN   lowerrP   r+   r$   )r   rV   r(   r)   r*   r+   r-   r.   r,   r5   r6   r3   r7   methodr_   _handlerr!   r!   r"   	add_route   s:   
B


zRouteMixin.add_routec	           
      K   0   t t| j|ftdh|||||||d|	S )a0  Decorate a function handler to create a route definition using the **GET** HTTP method.

        Args:
            uri (str): URL to be tagged to GET method of HTTP.
            host (Optional[Union[str, List[str]]]): Host IP or FQDN for
                the service to use.
            strict_slashes (Optional[bool]): Instruct Sanic to check if the
                request URLs need to terminate with a `/`.
            version (Optional[Union[int, str, float]]): API Version.
            name (Optional[str]): Unique name that can be used to identify
                the route.
            ignore_body (bool): Whether the handler should ignore request
                body. This means the body of the request, if sent, will not
                be consumed. In that instance, you will see a warning in
                the logs. Defaults to `True`, meaning do not consume the body.
            version_prefix (str): URL path that should be before the version
                value. Defaults to `"/v"`.
            error_format (Optional[str]): Custom error format string.
            **ctx_kwargs (Any): Keyword arguments that begin with a
                `ctx_* prefix` will be appended to the route
                context (`route.ctx`).

        Returns:
            RouteHandler: Object decorated with route method.
        r:   r)   r*   r+   r-   r.   r/   r5   r6   r   r   r$   rI   
r   r(   r*   r+   r-   r.   r/   r5   r6   r7   r!   r!   r"   get5  "   %
zRouteMixin.getc	           
      K   rd   )ao  Decorate a function handler to create a route definition using the **POST** HTTP method.

        Args:
            uri (str): URL to be tagged to POST method of HTTP.
            host (Optional[Union[str, List[str]]]): Host IP or FQDN for
                the service to use.
            strict_slashes (Optional[bool]): Instruct Sanic to check if the
                request URLs need to terminate with a `/`.
            stream (bool): Whether or not to stream the request body.
                Defaults to `False`.
            version (Optional[Union[int, str, float]]): API Version.
            name (Optional[str]): Unique name that can be used to identify
                the route.
            version_prefix (str): URL path that should be before the version
                value. Defaults to `"/v"`.
            error_format (Optional[str]): Custom error format string.
            **ctx_kwargs (Any): Keyword arguments that begin with a
                `ctx_*` prefix will be appended to the route
                context (`route.ctx`).

        Returns:
            RouteHandler: Object decorated with route method.
        POSTr)   r*   r+   r,   r-   r.   r5   r6   rf   
r   r(   r*   r+   r,   r-   r.   r5   r6   r7   r!   r!   r"   postj  "   #
zRouteMixin.postc	           
      K   rd   )am  Decorate a function handler to create a route definition using the **PUT** HTTP method.

        Args:
            uri (str): URL to be tagged to PUT method of HTTP.
            host (Optional[Union[str, List[str]]]): Host IP or FQDN for
                the service to use.
            strict_slashes (Optional[bool]): Instruct Sanic to check if the
                request URLs need to terminate with a `/`.
            stream (bool): Whether or not to stream the request body.
                Defaults to `False`.
            version (Optional[Union[int, str, float]]): API Version.
            name (Optional[str]): Unique name that can be used to identify
                the route.
            version_prefix (str): URL path that should be before the version
                value. Defaults to `"/v"`.
            error_format (Optional[str]): Custom error format string.
            **ctx_kwargs (Any): Keyword arguments that begin with a
                `ctx_*` prefix will be appended to the route
                context (`route.ctx`).

        Returns:
            RouteHandler: Object decorated with route method.
        PUTrk   rf   rl   r!   r!   r"   put  rn   zRouteMixin.putc	           
      K   rd   )a2  Decorate a function handler to create a route definition using the **HEAD** HTTP method.

        Args:
            uri (str): URL to be tagged to HEAD method of HTTP.
            host (Optional[Union[str, List[str]]]): Host IP or FQDN for
                the service to use.
            strict_slashes (Optional[bool]): Instruct Sanic to check if the
                request URLs need to terminate with a `/`.
            version (Optional[Union[int, str, float]]): API Version.
            name (Optional[str]): Unique name that can be used to identify
                the route.
            ignore_body (bool): Whether the handler should ignore request
                body. This means the body of the request, if sent, will not
                be consumed. In that instance, you will see a warning in
                the logs. Defaults to `True`, meaning do not consume the body.
            version_prefix (str): URL path that should be before the version
                value. Defaults to `"/v"`.
            error_format (Optional[str]): Custom error format string.
            **ctx_kwargs (Any): Keyword arguments that begin with a
                `ctx_*` prefix will be appended to the route
                context (`route.ctx`).

        Returns:
            RouteHandler: Object decorated with route method.
        HEADre   rf   rg   r!   r!   r"   head  ri   zRouteMixin.headc	           
      K   rd   )a8  Decorate a function handler to create a route definition using the **OPTIONS** HTTP method.

        Args:
            uri (str): URL to be tagged to OPTIONS method of HTTP.
            host (Optional[Union[str, List[str]]]): Host IP or FQDN for
                the service to use.
            strict_slashes (Optional[bool]): Instruct Sanic to check if the
                request URLs need to terminate with a `/`.
            version (Optional[Union[int, str, float]]): API Version.
            name (Optional[str]): Unique name that can be used to identify
                the route.
            ignore_body (bool): Whether the handler should ignore request
                body. This means the body of the request, if sent, will not
                be consumed. In that instance, you will see a warning in
                the logs. Defaults to `True`, meaning do not consume the body.
            version_prefix (str): URL path that should be before the version
                value. Defaults to `"/v"`.
            error_format (Optional[str]): Custom error format string.
            **ctx_kwargs (Any): Keyword arguments that begin with a
                `ctx_*` prefix will be appended to the route
                context (`route.ctx`).

        Returns:
            RouteHandler: Object decorated with route method.
        OPTIONSre   rf   rg   r!   r!   r"   options  ri   zRouteMixin.optionsc	           
      K   rd   )a  Decorate a function handler to create a route definition using the **PATCH** HTTP method.

        Args:
            uri (str): URL to be tagged to PATCH method of HTTP.
            host (Optional[Union[str, List[str]]]): Host IP or FQDN for
                the service to use.
            strict_slashes (Optional[bool]): Instruct Sanic to check if the
                request URLs need to terminate with a `/`.
            stream (bool): Set to `True` if full request streaming is needed,
                `False` otherwise. Defaults to `False`.
            version (Optional[Union[int, str, float]]): API Version.
            name (Optional[str]): Unique name that can be used to identify
                the route.
            version_prefix (str): URL path that should be before the version
                value. Defaults to `"/v"`.
            error_format (Optional[str]): Custom error format string.
            **ctx_kwargs (Any): Keyword arguments that begin with a
                `ctx_*` prefix will be appended to the route
                context (`route.ctx`).

        Returns:
            RouteHandler: Object decorated with route method.
        PATCHrk   rf   rl   r!   r!   r"   patch:  rn   zRouteMixin.patchc	           
      K   rd   )as  Decorate a function handler to create a route definition using the **DELETE** HTTP method.

        Args:
            uri (str): URL to be tagged to the DELETE method of HTTP.
            host (Optional[Union[str, List[str]]]): Host IP or FQDN for the
                service to use.
            strict_slashes (Optional[bool]): Instruct Sanic to check if the
                request URLs need to terminate with a */*.
            version (Optional[Union[int, str, float]]): API Version.
            name (Optional[str]): Unique name that can be used to identify
                the Route.
            ignore_body (bool): Whether or not to ignore the body in the
                request. Defaults to `False`.
            version_prefix (str): URL path that should be before the version
                value. Defaults to `"/v"`.
            error_format (Optional[str]): Custom error format string.
            **ctx_kwargs (Any): Keyword arguments that begin with a `ctx_*`
                prefix will be appended to the route context (`route.ctx`).

        Returns:
            RouteHandler: Object decorated with route method.
        DELETEre   rf   rg   r!   r!   r"   deletem  s"   "
zRouteMixin.deletec
                 K   s(   | j d||d|||||d||	d|
S )a  Decorate a function to be registered as a websocket route.

        Args:
            uri (str): Path of the URL.
            host (Optional[Union[str, List[str]]]): Host IP or FQDN details.
            strict_slashes (Optional[bool]): If the API endpoint needs to
                terminate with a `"/"` or not.
            subprotocols (Optional[List[str]]): Optional list of str with
                supported subprotocols.
            version (Optional[Union[int, str, float]]): WebSocket
                protocol version.
            name (Optional[str]): A unique name assigned to the URL so that
                it can be used with url_for.
            apply (bool): If set to False, it doesn't apply the route to the
                app. Default is `True`.
            version_prefix (str): URL path that should be before the version
                value. Defaults to `"/v"`.
            error_format (Optional[str]): Custom error format string.
            **ctx_kwargs (Any): Keyword arguments that begin with
                a `ctx_* prefix` will be appended to the route
                context (`route.ctx`).

        Returns:
            tuple: Tuple of routes, decorated function.
        NT)r(   r*   r)   r+   r-   r.   r0   r1   r2   r5   r6   r!   )r$   )r   r(   r*   r+   r1   r-   r.   r0   r5   r6   r7   r!   r!   r"   r2     s   &zRouteMixin.websocketc
                 K   s&   | j d||||||||	d|
|S )az  A helper method to register a function as a websocket route.

        Args:
            handler (Callable): A callable function or instance of a class
                that can handle the websocket request.
            uri (str): URL path that will be mapped to the websocket handler.
            host (Optional[Union[str, List[str]]]): Host IP or FQDN details.
            strict_slashes (Optional[bool]): If the API endpoint needs to
                terminate with a `"/"` or not.
            subprotocols (Optional[List[str]]): Subprotocols to be used with
                websocket handshake.
            version (Optional[Union[int, str, float]]): Versioning information.
            name (Optional[str]): A unique name assigned to the URL.
            version_prefix (str): URL path before the version value.
                Defaults to `"/v"`.
            error_format (Optional[str]): Format for error handling.
            **ctx_kwargs (Any): Keyword arguments beginning with `ctx_*`
                prefix will be appended to the route context (`route.ctx`).

        Returns:
            Callable: Object passed as the handler.
        )r(   r*   r+   r1   r-   r.   r5   r6   Nr!   )r2   )r   rV   r(   r*   r+   r1   r-   r.   r5   r6   r7   r!   r!   r"   add_websocket_route  s   #	
zRouteMixin.add_websocket_routec                 C   st   t tt+ tt|}t|}| |}t|dkr(tt	|W  d    S W d    dS 1 s3w   Y  dS )N    )
r   OSErrorrJ   r	   r   r   _get_response_typesrS   nextiter)r   rV   srctreehttp_response_typesr!   r!   r"   rM     s   


z"RouteMixin._determine_error_formatc                    s*   t   G  fdddt}| |  S )Nc                       s"   e Zd Zdedef fddZdS )z;RouteMixin._get_response_types.<locals>.HttpResponseVisitornoder   c                    sx   t t. |jjjg}|jjr|dd |jjD 7 }|D ]}|tv r) t|  qW d    d S 1 s5w   Y  d S )Nc                 S   s   g | ]
}|j d kr|jqS )content_type)argvalue)r=   kr!   r!   r"   r?     s
    
z\RouteMixin._get_response_types.<locals>.HttpResponseVisitor.visit_Return.<locals>.<listcomp>)r   AttributeErrorr   funcidkeywordsr   rP   )r   r   checkschecktypesr!   r"   visit_Return  s   
"zHRouteMixin._get_response_types.<locals>.HttpResponseVisitor.visit_ReturnN)rT   
__module____qualname__r   r
   r   r!   r   r!   r"   HttpResponseVisitor  s    r   )r   r   visit)r   r   r   r!   r   r"   r}     s   zRouteMixin._get_response_typesrawc                    sB    fddi    D } rd   }td| t|S )Nc                    s*   i | ]}| d r|d d |qS )ctx_r{   )r\   replacepop)r=   keyr   r!   r"   
<dictcomp>'  s    z3RouteMixin._build_route_context.<locals>.<dictcomp>z, zUnexpected keyword arguments: )rR   joinrJ   r   )r   r   r7   unexpected_argumentsr!   r   r"   r^   &  s   

zRouteMixin._build_route_context)r   N)NNNFNNFTNFFFr'   N)NNNNTr'   N)NNFNNr'   N)NNNNFr'   N)NNNNNTr'   N)NNNNNr'   N)#rT   r   r   r#   r   rL   r   r&   rH   r   r   r   boolintfloatr
   RouteWrapperr$   rI   r   rc   rh   rm   rp   rr   rt   rv   rx   r2   ry   rM   r}   dictr   r^   r!   r!   r!   r"   r      s   

	


 4	

c	

8	

6	

6	

8	

8	

6	

5
	

9	

/r   )	metaclassN)'astr   r   r   collections.abcr   
contextlibr   inspectr   r   textwrapr	   typingr
   r   r   r   r   sanic_routing.router   sanic.base.metar   sanic.constantsr   sanic.errorpagesr   sanic.mixins.baser   sanic.models.futuresr   r   sanic.models.handler_typesr   sanic.typesr   rF   r   r   r!   r!   r!   r"   <module>   s$    