a
    ((ac                     @   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 d dlm	Z	 d dl
mZ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mZ d d	lmZmZmZmZ d d
lmZmZ G dd de Z!G dd deZ"ej#e$dddZ%ej&edddZ'ej&edddZ(ej&e)dddZ*e)ej+e)ef ej+e)e)f ej,e)e-f dddZ.e/dZ0e)ej,ej1e)ej+e)ef f ddd Z2G d!d" d"Z3G d#d$ d$e3Z4G d%d& d&e3Z5G d'd( d(e3Z6G d)d* d*e3Z7G d+d, d,Z8dS )-    N)Enum)run_in_threadpool)CONVERTOR_TYPES	Convertor)URLHeadersURLPath)HTTPException)Request)PlainTextResponseRedirectResponse)ASGIAppReceiveScopeSend)	WebSocketWebSocketClosec                   @   s   e Zd ZdZdS )NoMatchFoundz}
    Raised by `.url_for(name, **path_params)` and `.url_path_for(name, **path_params)`
    if no matching route exists.
    N)__name__
__module____qualname____doc__ r   r   X/Users/bob/PycharmProjects/fastapi/venv/lib/python3.9/site-packages/starlette/routing.pyr      s   r   c                   @   s   e Zd ZdZdZdZdS )Matchr         N)r   r   r   NONEPARTIALFULLr   r   r   r   r      s   r   )objreturnc                 C   s   t | tjr| j} q t| S )z~
    Correctly determines if an object is a coroutine function,
    including those wrapped in functools.partial objects.
    )
isinstance	functoolspartialfuncinspectiscoroutinefunction)r    r   r   r   iscoroutinefunction_or_partial    s    r(   r%   r!   c                    s&   t  tttdd fdd}|S )zi
    Takes a function or coroutine `func(request) -> response`,
    and returns an ASGI application.
    Nscopereceivesendr!   c                    sH   t | ||d}r" |I d H }nt |I d H }|| ||I d H  d S N)r,   r-   )r
   r   )r+   r,   r-   requestresponser%   Zis_coroutiner   r   app1   s
    zrequest_response.<locals>.app)r(   r   r   r   r%   r2   r   r1   r   request_response*   s    r4   c                    s   t ttdd fdd}|S )zM
    Takes a coroutine `func(session)`, and returns an ASGI application.
    Nr*   c                    s    t | ||d} |I d H  d S r.   )r   )r+   r,   r-   sessionr%   r   r   r2   B   s    zwebsocket_session.<locals>.app)r   r   r   r3   r   r6   r   websocket_session<   s    r7   )endpointr!   c                 C   s"   t | st | r| jS | jjS N)r&   
isfunctionisclassr   	__class__)r8   r   r   r   get_nameI   s    r=   )pathparam_convertorspath_paramsr!   c                 C   s^   t | D ]H\}}d| d | v r|| }||}| d| d |} || q| |fS )N{})listitemsZ	to_stringreplacepop)r>   r?   r@   keyvalue	convertorr   r   r   replace_paramsO   s    
rJ   z4{([a-zA-Z_][a-zA-Z0-9_]*)(:[a-zA-Z_][a-zA-Z0-9_]*)?})r>   r!   c           	      C   s   d}d}d}i }t | D ]}|d\}}|d}|tv sNJ d| dt| }|t| ||  7 }|d| d	|j d
7 }|| ||  7 }|d| 7 }|||< |	 }q|t| |d d 7 }|| |d 7 }t
|||fS )z
    Given a path string, like: "/{username:str}", return a three-tuple
    of (regex, format, {param_name:convertor}).

    regex:      "/(?P<username>[^/]+)"
    format:     "/{username}"
    convertors: {"username": StringConvertor()}
    ^ r   str:zUnknown path convertor ''z(?P<>)z{%s}N$)PARAM_REGEXfinditergroupslstripr   reescapestartregexendcompile)	r>   
path_regexpath_formatidxr?   match
param_nameZconvertor_typerI   r   r   r   compile_patha   s*    


rb   c                   @   s`   e Zd Zeejeef dddZeee	dddZ
eeeddd	d
ZeeeddddZdS )	BaseRouter+   r!   c                 C   s
   t  d S r9   NotImplementedError)selfr+   r   r   r   matches   s    zBaseRoute.matchesnamer@   r!   c                 K   s
   t  d S r9   re   )rg   rj   r@   r   r   r   url_path_for   s    zBaseRoute.url_path_forNr*   c                    s
   t  d S r9   re   rg   r+   r,   r-   r   r   r   handle   s    zBaseRoute.handlec                    s   |  |\}}|tjkrl|d dkrDtddd}||||I dH  n$|d dkrht }||||I dH  dS || | |||I dH  dS )z
        A route may be used in isolation as a stand-alone ASGI app.
        This is a somewhat contrived case, as they'll almost always be used
        within a Router, but could be useful for some tooling and minimal apps.
        typehttp	Not Found  status_codeN	websocket)rh   r   r   r   r   updaterm   )rg   r+   r,   r-   r`   child_scoper0   websocket_closer   r   r   __call__   s    

zBaseRoute.__call__)r   r   r   r   typingTupler   rh   rM   r   rk   r   r   rm   rx   r   r   r   r   rc      s   rc   c                   @   s   e Zd Zddddeejeje eeddddZe	ej
ee	f ddd	Zeeed
ddZe	eeddddZejedddZdS )RouteNTmethodsrj   include_in_schemar>   r8   r}   rj   r~   r!   c                C   s   | dsJ d|| _|| _|d u r.t|n|| _|| _|}t|tjrR|j	}q>t
|sft
|rt|| _|d u rdg}n|| _|d u rd | _n&dd |D | _d| jv r| jd t|\| _| _| _d S )N/ Routed paths must start with '/'GETc                 S   s   h | ]}|  qS r   )upper).0methodr   r   r   	<setcomp>       z!Route.__init__.<locals>.<setcomp>HEAD)
startswithr>   r8   r=   rj   r~   r"   r#   r$   r%   r&   r:   ismethodr4   r2   r}   addrb   r]   r^   r?   )rg   r>   r8   r}   rj   r~   Zendpoint_handlerr   r   r   __init__   s&    	

zRoute.__init__rd   c                 C   s   |d dkr| j |d }|r| }| D ]\}}| j| |||< q0t|di }|| | j	|d}| j
r|d | j
vrtj|fS tj|fS tji fS )Nrn   ro   r>   r@   r8   r@   r   )r]   r`   	groupdictrD   r?   convertdictgetru   r8   r}   r   r   r   r   rg   r+   r`   matched_paramsrG   rH   r@   rv   r   r   r   rh      s    


zRoute.matchesri   c                 K   sZ   t | }t | j }|| jks,||kr2t t| j| j|\}}|rNJ t|ddS )Nro   r>   protocolsetkeysr?   rj   r   rJ   r^   r   rg   rj   r@   Zseen_paramsZexpected_paramsr>   remaining_paramsr   r   r   rk      s    
zRoute.url_path_forr*   c                    s`   | j rH|d | j vrHd|v r(tddntddd}||||I d H  n| |||I d H  d S )Nr   r2   i  rr   zMethod Not Allowed)r}   r	   r   r2   )rg   r+   r,   r-   r0   r   r   r   rm      s    zRoute.handleotherr!   c                 C   s.   t |to,| j|jko,| j|jko,| j|jkS r9   )r"   r{   r>   r8   r}   rg   r   r   r   r   __eq__   s    



zRoute.__eq__)r   r   r   rM   ry   CallableListboolr   r   rz   r   rh   r   rk   r   r   rm   Anyr   r   r   r   r   r{      s   $
r{   c                   @   sz   e Zd ZddeejeddddZeeje	ef dddZ
eeed	d
dZeeeddddZejedddZdS )WebSocketRouteNrj   r>   r8   rj   r!   c                C   sr   | dsJ d|| _|| _|d u r.t|n|| _t|sHt|rTt|| _	n|| _	t
|\| _| _| _d S )Nr   r   )r   r>   r8   r=   rj   r&   r:   r   r7   r2   rb   r]   r^   r?   )rg   r>   r8   rj   r   r   r   r      s    zWebSocketRoute.__init__rd   c                 C   s   |d dkr~| j |d }|r~| }| D ]\}}| j| |||< q0t|di }|| | j	|d}t
j|fS t
ji fS )Nrn   rt   r>   r@   r   )r]   r`   r   rD   r?   r   r   r   ru   r8   r   r   r   r   r   r   r   rh     s    

zWebSocketRoute.matchesri   c                 K   sZ   t | }t | j }|| jks,||kr2t t| j| j|\}}|rNJ t|ddS )Nrt   r   r   r   r   r   r   rk     s    
zWebSocketRoute.url_path_forr*   c                    s   |  |||I d H  d S r9   r2   rl   r   r   r   rm   (  s    zWebSocketRoute.handler   c                 C   s"   t |to | j|jko | j|jkS r9   )r"   r   r>   r8   r   r   r   r   r   +  s
    


zWebSocketRoute.__eq__)r   r   r   rM   ry   r   r   r   rz   r   rh   r   rk   r   r   rm   r   r   r   r   r   r   r   r      s   r   c                   @   s   e Zd Zdeeeje eddddZe	ej
e dddZeejeef dd	d
ZeeedddZeeeddddZejedddZdS )MountN)r>   r2   routesrj   r!   c                 C   s~   |dks| dsJ d|d us2|d us2J d|d| _|d urN|| _nt|d| _|| _t| jd \| _| _| _	d S )NrL   r   r   z0Either 'app=...', or 'routes=' must be specified)r   z/{path:path})
r   rstripr>   r2   Routerrj   rb   r]   r^   r?   )rg   r>   r2   r   rj   r   r   r   r   4  s    zMount.__init__r!   c                 C   s   t | jdd S Nr   getattrr2   rg   r   r   r   r   I  s    zMount.routesrd   c                 C   s   |d dv r|d }| j |}|r| }| D ]\}}| j| |||< q4d|d }|d t|  }t|	di }	|	
| |	dd}
|	|	d|
|
| || jd	}tj|fS tji fS )
Nrn   ro   rt   r>   r   r@   	root_pathrL   app_root_path)r@   r   r   r>   r8   )r]   r`   r   rD   r?   r   rF   lenr   r   ru   r2   r   r   r   )rg   r+   r>   r`   r   rG   rH   Zremaining_pathZmatched_pathr@   r   rv   r   r   r   rh   M  s(    


zMount.matchesri   c           
   	   K   s.  | j d urR|| j krRd|v rR|d d|d< t| j| j|\}}|sPt|dS n| j d u sn|| j d r$| j d u r~|}n|t| j d d  }|d}d|d< t| j| j|\}}|d ur||d< | j	pg D ]N}z4|j
|fi |}	t|dt|	 |	jdW   S  ty    Y q0 qt d S )Nr>   r   )r>   rN   r   rL   r   )rj   rV   rJ   r^   r?   r   r   r   r   r   rk   r   rM   r   r   )
rg   rj   r@   r>   r   remaining_nameZ
path_kwargZpath_prefixrouteurlr   r   r   rk   d  s6    



zMount.url_path_forr*   c                    s   |  |||I d H  d S r9   r   rl   r   r   r   rm     s    zMount.handler   c                 C   s"   t |to | j|jko | j|jkS r9   )r"   r   r>   r2   r   r   r   r   r     s
    


zMount.__eq__)NNN)r   r   r   rM   r   ry   Sequencerc   r   propertyr   r   r   rz   r   rh   r   rk   r   r   rm   r   r   r   r   r   r   r   r   3  s       !r   c                   @   s   e Zd ZdeeeddddZeeje	 dddZ
eejeef dd	d
ZeeedddZeeeddddZejedddZdS )HostNhostr2   rj   r!   c                 C   s*   || _ || _|| _t|\| _| _| _d S r9   )r   r2   rj   rb   
host_regexhost_formatr?   )rg   r   r2   rj   r   r   r   r     s    zHost.__init__r   c                 C   s   t | jdd S r   r   r   r   r   r   r     s    zHost.routesrd   c           
      C   s   |d dv rt |d}|dddd }| j|}|r| }| D ]\}}| j| |||< qLt	|di }|
| || jd	}	tj|	fS tji fS )
Nrn   r   r+   r   rL   rN   r   r@   )r@   r8   )r   r   splitr   r`   r   rD   r?   r   r   ru   r2   r   r   r   )
rg   r+   headersr   r`   r   rG   rH   r@   rv   r   r   r   rh     s    


zHost.matchesri   c           	   	   K   s   | j d urL|| j krLd|v rL|d}t| j| j|\}}|st||dS n| j d u sf|| j d r| j d u rv|}n|t| j d d  }t| j| j|\}}| jpg D ]D}z,|j	|fi |}tt
||j|dW   S  ty   Y q0 qt d S )Nr>   )r>   r   rN   r   )r>   r   r   )rj   rF   rJ   r   r?   r   r   r   r   rk   rM   r   r   )	rg   rj   r@   r>   r   r   r   r   r   r   r   r   rk     s*    



zHost.url_path_forr*   c                    s   |  |||I d H  d S r9   r   rl   r   r   r   rm     s    zHost.handler   c                 C   s"   t |to | j|jko | j|jkS r9   )r"   r   r   r2   r   r   r   r   r     s
    


zHost.__eq__)N)r   r   r   rM   r   r   r   ry   r   rc   r   r   rz   r   rh   r   rk   r   r   rm   r   r   r   r   r   r   r   r     s   r   c                	   @   s  e Zd Zd0eje eeejej ejej ejej	gej
f ddddZeeeddddZeeed	d
dZddddZddddZeeeddddZeeeddddZej	edddZd1eeeddddZd2eeeddddZd3eejeje eedddd Zd4eejedd!d"d#Zd5eeje eeejd$d%d&Zd6eeejd'd(d)Zeejdd*d+d,Zeejd-d.d/Z dS )7r   NT)r   redirect_slashesdefault
on_startupon_shutdownlifespanr!   c                    s   |d u rg nt | _| _|d u r* jn| _|d u r<g nt | _|d u rRg nt | _tjtj	d fdd}|d u r|n| _
d S )N)r2   r!   c                   s&      I d H  d V    I d H  d S r9   startupshutdownr   r   r   r   default_lifespan  s    z)Router.__init__.<locals>.default_lifespan)rC   r   r   	not_foundr   r   r   ry   r   AsyncGeneratorlifespan_context)rg   r   r   r   r   r   r   r   r   r   r   r     s    	zRouter.__init__r*   c                    s^   |d dkr(t  }||||I d H  d S d|v r<tddntddd}||||I d H  d S )Nrn   rt   r2   rq   rr   rp   )r   r	   r   )rg   r+   r,   r-   rw   r0   r   r   r   r     s    zRouter.not_foundri   c              	   K   sB   | j D ]0}z|j|fi |W   S  ty4   Y q0 qt d S r9   )r   rk   r   )rg   rj   r@   r   r   r   r   rk     s    
zRouter.url_path_forr   c                    s.   | j D ]"}t|r"| I dH  q|  qdS )z7
        Run any `.on_startup` event handlers.
        N)r   asyncior'   rg   handlerr   r   r   r     s    

zRouter.startupc                    s.   | j D ]"}t|r"| I dH  q|  qdS )z8
        Run any `.on_shutdown` event handlers.
        N)r   r   r'   r   r   r   r   r     s    

zRouter.shutdownc                    s   d}| d}| I dH  zt| jrr| |2 z:3 dH W }|sJJ dd}|ddiI dH  | I dH  q26 n>| |D ]2}|sJ dd}|ddiI dH  | I dH  q|W n4 ty   |rt }|d|d	I dH   Y n0 |dd
iI dH  dS )z{
        Handle ASGI lifespan messages, which allows us to manage application
        startup and shutdown events.
        Tr2   Nz(Lifespan context yielded multiple times.Frn   zlifespan.startup.completezlifespan.startup.failed)rn   messagezlifespan.shutdown.complete)r   r&   isasyncgenfunctionr   BaseException	traceback
format_exc)rg   r+   r,   r-   firstr2   itemexc_textr   r   r   r     s*    
zRouter.lifespanc                    s  |d dv sJ d|vr | |d< |d dkrD|  |||I dH  dS d}| jD ]Z}||\}}|tjkr|| ||||I dH   dS |tjkrN|du rN|}|}qN|dur|| ||||I dH  dS |d dkr| jr|d dkrt	|}	|d 
dr$|	d d|	d< n|	d d |	d< | jD ]P}||	\}}|tjkr:t|	d	}
tt|
d
}||||I dH   dS q:| |||I dH  dS )z;
        The main entry point to the Router class.
        rn   )ro   rt   r   Zrouterr   Nro   r>   r   r   )r   )r   r   rh   r   r   ru   rm   r   r   r   endswithr   r   r   r   rM   r   )rg   r+   r,   r-   r$   r   r`   rv   Zpartial_scopeZredirect_scopeZredirect_urlr0   r   r   r   rx   /  sB    



$


zRouter.__call__r   c                 C   s   t |to| j|jkS r9   )r"   r   r   r   r   r   r   r   c  s    zRouter.__eq__)r>   r2   rj   r!   c                 C   s   t |||d}| j| d S N)r2   rj   )r   r   append)rg   r>   r2   rj   r   r   r   r   mounth  s    zRouter.mountr   c                 C   s   t |||d}| j| d S r   )r   r   r   )rg   r   r2   rj   r   r   r   r   r   l  s    zRouter.hostr   c                 C   s"   t |||||d}| j| d S )N)r8   r}   rj   r~   )r{   r   r   )rg   r>   r8   r}   rj   r~   r   r   r   r   	add_routep  s    zRouter.add_router   c                 C   s   t |||d}| j| d S )N)r8   rj   )r   r   r   )rg   r>   r8   rj   r   r   r   r   add_websocket_route  s    zRouter.add_websocket_route)r>   r}   rj   r~   r!   c                    s$   t jt jd fdd}|S )Nr)   c                    s   j |  d | S )Nr|   )r   r6   r~   r}   rj   r>   rg   r   r   	decorator  s    zRouter.route.<locals>.decoratorry   r   )rg   r>   r}   rj   r~   r   r   r   r   r     s     
zRouter.route)r>   rj   r!   c                    s    t jt jd fdd}|S )Nr)   c                    s   j |  d | S )Nr   )r   r6   rj   r>   rg   r   r   r     s    z)Router.websocket_route.<locals>.decoratorr   )rg   r>   rj   r   r   r   r   websocket_route  s    zRouter.websocket_route)
event_typer%   r!   c                 C   s2   |dv sJ |dkr"| j | n| j| d S )Nr   r   )r   r   r   )rg   r   r%   r   r   r   add_event_handler  s    zRouter.add_event_handler)r   r!   c                    s   t jt jd fdd}|S )Nr)   c                    s     |  | S r9   )r   r6   r   rg   r   r   r     s    z"Router.on_event.<locals>.decoratorr   )rg   r   r   r   r   r   on_event  s    zRouter.on_event)NTNNNN)N)N)NNT)N)NNT)N)!r   r   r   ry   r   rc   r   r   r   r   r   r   r   r   r   r   rM   r   rk   r   r   r   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     sj         



4    	   r   )9r   r#   r&   rW   r   ry   enumr   Zstarlette.concurrencyr   Zstarlette.convertorsr   r   Zstarlette.datastructuresr   r   r   Zstarlette.exceptionsr	   Zstarlette.requestsr
   Zstarlette.responsesr   r   Zstarlette.typesr   r   r   r   Zstarlette.websocketsr   r   	Exceptionr   r   r   r   r(   r   r4   r7   rM   r=   Dictrz   r   rJ   r\   rS   Patternrb   rc   r{   r   r   r   r   r   r   r   r   <module>   sF   

(U7]@