o
    [hc                  
   @   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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#dej$de%fddZ&dej'defddZ(dej'defddZ)dej'de*fddZ+de*dej,e*ef dej,e*e*f dej-e*e.f fddZ/e0d Z1de*dej-ej2e*ej,e*ef f fd!d"Z3G d#d$ d$Z4G d%d& d&e4Z5G d'd( d(e4Z6G d)d* d*e4Z7G d+d, d,e4Z8G d-d. d.Z9d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/home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/venv/lib/python3.10/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   s2   t jdk rt| tjr| j} t| tjst| S )zq
    Correctly determines if an object is a coroutine function,
    with a fix for partials on Python < 3.8.
    )      )sysversion_info
isinstance	functoolspartialfuncinspectiscoroutinefunction)r    r   r   r   iscoroutinefunction_or_partial!   s
   

r,   r)   c                    s,   t  dtdtdtddf fdd}|S )zi
    Takes a function or coroutine `func(request) -> response`,
    and returns an ASGI application.
    scopereceivesendr!   Nc                    sJ   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   app3   s   zrequest_response.<locals>.app)r,   r   r   r   r)   r4   r   r3   r   request_response,   s    r6   c                    s"   dt dtdtddf fdd}|S )zM
    Takes a coroutine `func(session)`, and returns an ASGI application.
    r-   r.   r/   r!   Nc                    s"   t | ||d} |I d H  d S r0   )r   )r-   r.   r/   sessionr)   r   r   r4   D   s   zwebsocket_session.<locals>.app)r   r   r   r5   r   r8   r   websocket_session>   s   r9   endpointc                 C   s"   t | s
t | r| jS | jjS N)r*   
isfunctionisclassr   	__class__)r:   r   r   r   get_nameK   s   r?   pathparam_convertorspath_paramsc                 C   s^   t | D ]$\}}d| d | v r*|| }||}| d| d |} || q| |fS )N{})listitemsZ	to_stringreplacepop)r@   rA   rB   keyvalue	convertorr   r   r   replace_paramsQ   s   

rL   z4{([a-zA-Z_][a-zA-Z0-9_]*)(:[a-zA-Z_][a-zA-Z0-9_]*)?}c           	      C   s   d}d}d}i }t | D ]O}|d\}}|d}|tv s'J 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idxrA   match
param_nameZconvertor_typerK   r   r   r   compile_pathc   s(   



rd   c                   @   sr   e Zd Zdedejeef fddZdedede	fddZ
ded	ed
eddfddZded	ed
eddfddZdS )	BaseRouter-   r!   c                 C      t  r;   NotImplementedError)selfr-   r   r   r   matches      zBaseRoute.matchesnamerB   c                 K   rf   r;   rg   )ri   rl   rB   r   r   r   url_path_for   rk   zBaseRoute.url_path_forr.   r/   Nc                    s   t  r;   rg   ri   r-   r.   r/   r   r   r   handle   s   zBaseRoute.handlec                    s   |  |\}}|tjkr8|d dkr$tddd}||||I dH  dS |d dkr6t }||||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)rj   r   r   r   r   updatero   )ri   r-   r.   r/   rb   child_scoper2   websocket_closer   r   r   __call__   s   

zBaseRoute.__call__)r   r   r   r   typingTupler   rj   rO   r   rm   r   r   ro   rz   r   r   r   r   re      s
    re   c                   @   s   e Zd Zdddddedejdeje deded	dfd
dZde	d	ej
ee	f fddZdeded	efddZde	deded	dfddZdejd	efddZdS )RouteNTmethodsrl   include_in_schemar@   r:   r   rl   r   r!   c                C   s   | ds	J d|| _|| _|d u rt|n|| _|| _|}t|tjr.|j	}t|tjs%t
|s8t
|rEt|| _|d u rDdg}n|| _|d u rPd | _ndd |D | _d| jv rc| jd t|\| _| _| _d S )N/ Routed paths must start with '/'GETc                 S   s   h | ]}|  qS r   )upper).0methodr   r   r   	<setcomp>   s    z!Route.__init__.<locals>.<setcomp>HEAD)
startswithr@   r:   r?   rl   r   r&   r'   r(   r)   r*   r<   ismethodr6   r4   r   addrd   r_   r`   rA   )ri   r@   r:   r   rl   r   Zendpoint_handlerr   r   r   __init__   s*   	

zRoute.__init__r-   c                 C   s   |d dkrN| j |d }|rN| }| D ]\}}| j| |||< qt|di }|| | j	|d}| j
rI|d | j
vrItj|fS tj|fS tji fS )Nrp   rq   r@   rB   r:   rB   r   )r_   rb   	groupdictrF   rA   convertdictgetrw   r:   r   r   r   r   r   ri   r-   rb   matched_paramsrI   rJ   rB   rx   r   r   r   rj      s   



zRoute.matchesrB   c                 K   Z   t | }t | j }|| jks||krt t| j| j|\}}|r'J t|ddS )Nrq   r@   protocolsetkeysrA   rl   r   rL   r`   r   ri   rl   rB   Zseen_paramsZexpected_paramsr@   remaining_paramsr   r   r   rm         
zRoute.url_path_forr.   r/   c                    sb   | j r%|d | j vr%d|v rtddtddd}||||I d H  d S | |||I d H  d S )Nr   r4   i  rt   zMethod Not Allowed)r   r	   r   r4   )ri   r-   r.   r/   r2   r   r   r   ro      s   
zRoute.handleotherc                 C   s.   t |to| j|jko| j|jko| j|jkS r;   )r&   r}   r@   r:   r   ri   r   r   r   r   __eq__   s   



zRoute.__eq__)r   r   r   rO   r{   CallableListboolr   r   r|   r   rj   r   rm   r   r   ro   Anyr   r   r   r   r   r}      s*    
$
r}   c                	   @   s   e Zd ZdddedejdeddfddZd	edeje	ef fd
dZ
dededefddZd	edededdfddZdejdefddZdS )WebSocketRouteNrl   r@   r:   rl   r!   c                C   sr   | ds	J d|| _|| _|d u rt|n|| _t|s$t|r*t|| _	n|| _	t
|\| _| _| _d S )Nr   r   )r   r@   r:   r?   rl   r*   r<   r   r9   r4   rd   r_   r`   rA   )ri   r@   r:   rl   r   r   r   r      s   zWebSocketRoute.__init__r-   c                 C   s   |d dkr?| j |d }|r?| }| D ]\}}| j| |||< qt|di }|| | j	|d}t
j|fS t
ji fS )Nrp   rv   r@   rB   r   )r_   rb   r   rF   rA   r   r   r   rw   r:   r   r   r   r   r   r   r   rj     s   


zWebSocketRoute.matchesrB   c                 K   r   )Nrv   r   r   r   r   r   r   rm     r   zWebSocketRoute.url_path_forr.   r/   c                       |  |||I d H  d S r;   r4   rn   r   r   r   ro   *     zWebSocketRoute.handler   c                 C   "   t |to| j|jko| j|jkS r;   )r&   r   r@   r:   r   r   r   r   r   -  
   


zWebSocketRoute.__eq__)r   r   r   rO   r{   r   r   r   r|   r   rj   r   rm   r   r   ro   r   r   r   r   r   r   r   r      s    
r   c                   @   s   e Zd Z			ddededeje deddf
ddZe	dej
e fd	d
Zdedejeef fddZdededefddZdedededdfddZdejdefddZdS )MountNr@   r4   routesrl   r!   c                 C   s~   |dks| dsJ d|d us|d usJ d|d| _|d ur'|| _nt|d| _|| _t| jd \| _| _| _	d S )NrN   r   r   z0Either 'app=...', or 'routes=' must be specified)r   z/{path:path})
r   rstripr@   r4   Routerrl   rd   r_   r`   rA   )ri   r@   r4   r   rl   r   r   r   r   6  s   zMount.__init__c                 C      t | jdd S Nr   getattrr4   ri   r   r   r   r   K     zMount.routesr-   c                 C   s   |d dv r`|d }| j |}|r`| }| D ]\}}| j| |||< qd|d }|d t|  }t|	di }	|	
| |	dd}
|	|	d|
|
| || jd	}tj|fS tji fS )
Nrp   rq   rv   r@   r   rB   	root_pathrN   app_root_path)rB   r   r   r@   r:   )r_   rb   r   rF   rA   r   rH   lenr   r   rw   r4   r   r   r   )ri   r-   r@   rb   r   rI   rJ   Zremaining_pathZmatched_pathrB   r   rx   r   r   r   rj   O  s(   



zMount.matchesrB   c           
   	   K   s(  | j d ur+|| j kr+d|v r+|d d|d< t| j| j|\}}|s(t|dS t | j d u s8|| j d r| j d u r@|}n|t| j d d  }|d}d|d< t| j| j|\}}|d urf||d< | j	pjg D ]%}z|j
|fi |}	t|dt|	 |	jdW   S  ty   Y qkw t )Nr@   r   )r@   rP   r   rN   r   )rl   rX   rL   r`   rA   r   r   r   r   r   rm   r   rO   r   r   )
ri   rl   rB   r@   r   remaining_nameZ
path_kwargZpath_prefixrouteurlr   r   r   rm   f  s:   




zMount.url_path_forr.   r/   c                    r   r;   r   rn   r   r   r   ro     r   zMount.handler   c                 C   r   r;   )r&   r   r@   r4   r   r   r   r   r     r   zMount.__eq__)NNN)r   r   r   rO   r   r{   Sequencere   r   propertyr   r   r   r|   r   rj   r   rm   r   r   ro   r   r   r   r   r   r   r   r   5  s*    
!r   c                	   @   s   e Zd ZddedededdfddZedeje	 fdd	Z
d
edejeef fddZdededefddZd
edededdfddZdejdefddZdS )HostNhostr4   rl   r!   c                 C   s*   || _ || _|| _t|\| _| _| _d S r;   )r   r4   rl   rd   
host_regexhost_formatrA   )ri   r   r4   rl   r   r   r   r     s   zHost.__init__c                 C   r   r   r   r   r   r   r   r     r   zHost.routesr-   c           
      C   s   |d dv rMt |d}|dddd }| j|}|rM| }| D ]\}}| j| |||< q&t	|di }|
| || jd	}	tj|	fS tji fS )
Nrp   r   r-   r   rN   rP   r   rB   )rB   r:   )r   r   splitr   rb   r   rF   rA   r   r   rw   r4   r   r   r   )
ri   r-   headersr   rb   r   rI   rJ   rB   rx   r   r   r   rj     s   



zHost.matchesrB   c           	   	   K   s   | j d ur(|| j kr(d|v r(|d}t| j| j|\}}|s%t||dS t | j d u s5|| j d ry| j d u r=|}n|t| j d d  }t| j| j|\}}| jpVg D ]!}z|j	|fi |}tt
||j|dW   S  tyx   Y qWw t )Nr@   )r@   r   rP   r   )r@   r   r   )rl   rH   rL   r   rA   r   r   r   r   rm   rO   r   r   )	ri   rl   rB   r@   r   r   r   r   r   r   r   r   rm     s.   



zHost.url_path_forr.   r/   c                    r   r;   r   rn   r   r   r   ro     r   zHost.handler   c                 C   r   r;   )r&   r   r   r4   r   r   r   r   r     r   zHost.__eq__r;   )r   r   r   rO   r   r   r   r{   r   re   r   r   r|   r   rj   r   rm   r   r   ro   r   r   r   r   r   r   r   r     s    r   c                   @   s  e Zd Z						d8deje dededejej dejej dejej	gej
f d	dfd
dZdededed	dfddZdeded	efddZd9ddZd9ddZdededed	dfddZdededed	dfddZdej	d	efddZd:d ed!eded	dfd"d#Zd:d$ed!eded	dfd%d&Z			d;d ed'ejd(eje ded)ed	dfd*d+Z	d:d ed'ejded	dfd,d-Z			d;d ed(eje ded)ed	ejf
d.d/Zd:d eded	ejfd0d1Zd2ed3ejd	dfd4d5Zd2ed	ejfd6d7Z dS )<r   NTr   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 r)g nt | _dtjdtj	f fdd}|d u rD| _
d S | _
d S )Nr4   r!   c                   s(      I d H  d V    I d H  d S r;   startupshutdownr   r   r   r   default_lifespan  s   z)Router.__init__.<locals>.default_lifespan)rE   r   r   	not_foundr   r   r   r{   r   AsyncGeneratorlifespan_context)ri   r   r   r   r   r   r   r   r   r   r   r     s   	zRouter.__init__r-   r.   r/   c                    s^   |d dkrt  }||||I d H  d S d|v rtddtddd}||||I d H  d S )Nrp   rv   r4   rs   rt   rr   )r   r	   r   )ri   r-   r.   r/   ry   r2   r   r   r   r     s   
zRouter.not_foundrl   rB   c              	   K   s<   | j D ]}z|j|fi |W   S  ty   Y qw t r;   )r   rm   r   )ri   rl   rB   r   r   r   r   rm     s   
zRouter.url_path_forc                    0   | j D ]}t|r| I dH  q|  qdS )z7
        Run any `.on_startup` event handlers.
        N)r   asyncior+   ri   handlerr   r   r   r         

zRouter.startupc                    r   )z8
        Run any `.on_shutdown` event handlers.
        N)r   r   r+   r   r   r   r   r   
  r   zRouter.shutdownc                    s   d}| d}| I dH  zLt| jr:| |2 z3 dH W }|s&J dd}|ddiI dH  | I dH  q6 n| |D ]}|sGJ dd}|ddiI dH  | I dH  q?W n tyr   |rqt }|d|d	I dH   w |dd
iI dH  dS )z{
        Handle ASGI lifespan messages, which allows us to manage application
        startup and shutdown events.
        Tr4   Nz(Lifespan context yielded multiple times.Frp   zlifespan.startup.completezlifespan.startup.failed)rp   messagezlifespan.shutdown.complete)r   r*   isasyncgenfunctionr   BaseException	traceback
format_exc)ri   r-   r.   r/   firstr4   itemexc_textr   r   r   r     s2   
zRouter.lifespanc                    s  |d dv s	J d|vr| |d< |d dkr#|  |||I dH  dS d}| jD ]-}||\}}|tjkrH|| ||||I dH   dS |tjkrU|du rU|}|}q(|durk|| ||||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 ]&}||	\}}|tjkrt|	d	}
tt|
d
}||||I dH   dS q| |||I dH  dS )z;
        The main entry point to the Router class.
        rp   )rq   rv   r   Zrouterr   Nrq   r@   r   r   )r   )r   r   rj   r   r   rw   ro   r   r   r   endswithr   r   r   r   rO   r   )ri   r-   r.   r/   r(   r   rb   rx   Zpartial_scopeZredirect_scopeZredirect_urlr2   r   r   r   rz   1  sH   






zRouter.__call__r   c                 C   s   t |to
| j|jkS r;   )r&   r   r   r   r   r   r   r   e  s   zRouter.__eq__r@   r4   c                 C      t |||d}| j| d S N)r4   rl   )r   r   append)ri   r@   r4   rl   r   r   r   r   mountj     zRouter.mountr   c                 C   r   r   )r   r   r   )ri   r   r4   rl   r   r   r   r   r   n  r   zRouter.hostr:   r   r   c                 C   s"   t |||||d}| j| d S )N)r:   r   rl   r   )r}   r   r   )ri   r@   r:   r   rl   r   r   r   r   r   	add_router  s   zRouter.add_routec                 C   r   )N)r:   rl   )r   r   r   )ri   r@   r:   rl   r   r   r   r   add_websocket_route  s   zRouter.add_websocket_routec                    s&   dt jdt jf fdd}|S )Nr)   r!   c                    s   j |  d | S )Nr~   )r   r8   r   r   rl   r@   ri   r   r   	decorator  s   zRouter.route.<locals>.decoratorr{   r   )ri   r@   r   rl   r   r   r   r   r   r     s   "
zRouter.routec                    s"   dt jdt jf fdd}|S )Nr)   r!   c                    s   j |  d | S )Nr   )r   r8   rl   r@   ri   r   r   r     s   z)Router.websocket_route.<locals>.decoratorr   )ri   r@   rl   r   r   r   r   websocket_route  s   zRouter.websocket_route
event_typer)   c                 C   s4   |dv sJ |dkr| j | d S | j| d S )Nr   r   )r   r   r   )ri   r   r)   r   r   r   add_event_handler  s   zRouter.add_event_handlerc                    s    dt jdt jf fdd}|S )Nr)   r!   c                    s     |  | S r;   )r   r8   r   ri   r   r   r     s   z"Router.on_event.<locals>.decoratorr   )ri   r   r   r   r   r   on_event  s   zRouter.on_event)NTNNNN)r!   Nr;   )NNT)!r   r   r   r{   r   re   r   r   r   r   r   r   r   r   r   r   rO   r   rm   r   r   r   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s    






4

	
r   ):r   r'   r*   rY   r$   r   r{   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   r6   r9   rO   r?   Dictr|   r   rL   r^   rU   Patternrd   re   r}   r   r   r   r   r   r   r   r   <module>   sV    


(U7]@