a
    c	gv                     @  sD  d dl m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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mZ d dlZd dlZd dlZd dlmZmZ d dl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$ ej%dkr
d dl	m&Z& nd dl'm&Z& zd dl(Z(W n e)y>   e*dY n0 e	j+g e	j,ej-j. f Z/e	j+e e"ge	j0d f Z1e	j+e!ge1f Z2e	j+e!e e"ge	j0d f Z3e	j4e5e	j6e5e	j7e5 e8f f Z9dddddZ:G dd dZ;G dd de	j<Z=G dd de>Z?G dd de(j@e$ZAG dd dZBG dd de(jCZDG d d! d!e(jEZFdS )"    )annotationsN)Future)cached_property)GeneratorType)unquoteurljoin)ObjectReceiveStreamObjectSendStream)StapledObjectStream)is_async_callable)ASGIAppMessageReceiveScopeSend)WebSocketDisconnect)   
   )	TypeGuardzThe starlette.testclient module requires the httpx package to be installed.
You can install this with:
    $ pip install httpx
zASGI2App | ASGI3AppzTypeGuard[ASGI3App]appreturnc                 C  s   t | rt| dS t| S )N	__await__)inspectisclasshasattrr   r    r   W/var/www/html/llm_bihealth/app/venv/lib/python3.9/site-packages/starlette/testclient.py	_is_asgi34   s    

r   c                   @  s4   e Zd ZdZdddddZddd	dd
ddZdS )
_WrapASGI2z7
    Provide an ASGI3 interface onto an ASGI2 app.
    ASGI2AppNoner   c                 C  s
   || _ d S Nr   )selfr   r   r   r   __init__?   s    z_WrapASGI2.__init__r   r   r   )scopereceivesendr   c                   s   |  |}|||I d H  d S r#   r   )r$   r&   r'   r(   instancer   r   r   __call__B   s    
z_WrapASGI2.__call__N)__name__
__module____qualname____doc__r%   r*   r   r   r   r   r    :   s   r    c                   @  s   e Zd ZU ded< ded< dS )_AsyncBackendstrbackenddict[str, typing.Any]backend_optionsN)r+   r,   r-   __annotations__r   r   r   r   r/   G   s   
r/   c                   @  s   e Zd ZdddddZdS )_UpgradeWebSocketTestSessionr"   )sessionr   c                 C  s
   || _ d S r#   )r7   )r$   r7   r   r   r   r%   M   s    z_Upgrade.__init__N)r+   r,   r-   r%   r   r   r   r   r5   L   s   r5   c                   @  s   e Zd ZdZdS )WebSocketDenialResponsez
    A special case of `WebSocketDisconnect`, raised in the `TestClient` if the
    `WebSocket` is closed before being accepted with a `send_denial_response()`.
    N)r+   r,   r-   r.   r   r   r   r   r8   Q   s   r8   c                   @  s.  e Zd ZdddddddZd dd	d
ZeddddZddddZdddddZddddZ	ddddZ
dddddZdddddZdddddZd dd!d"d#Zd$dd!d%d&Zd<dd(dd)d*d+Zd=d.d/dd0d1d2Zddd3d4Zd dd5d6Zd$dd7d8Zd>d(dd9d:d;Zd-S )?r6   ASGI3Appr   _PortalFactoryTyper"   )r   r&   portal_factoryr   c                 C  s6   || _ || _d | _|| _t | _t | _d | _d S r#   )	r   r&   accepted_subprotocolr;   queueQueue_receive_queue_send_queueextra_headers)r$   r   r&   r;   r   r   r   r%   \   s    

zWebSocketTestSession.__init__r   c                 C  s   t  | _| j|  | _z2| j| j}| ddi | 	 }| 
| W n tyl   | j   Y n0 |dd | _|dd | _| S )Ntypezwebsocket.connectsubprotocolheaders)
contextlib	ExitStack
exit_stackenter_contextr;   portalstart_task_soon_runr(   r'   _raise_on_close	Exceptionclosegetr<   rA   )r$   _messager   r   r   	__enter__j   s    

zWebSocketTestSession.__enter__zanyio.Eventc                 C  s   t  S r#   )anyioEventr$   r   r   r   should_closez   s    z!WebSocketTestSession.should_closec                   s   | j   d S r#   )rW   setrV   r   r   r   _notify_close~   s    z"WebSocketTestSession._notify_close
typing.Anyargsr   c              	   G  sj   z&|  d W | j| j | j   n| j| j | j   0 | j sf| j }t|t	rB|qBd S )N  )
rO   rJ   rK   rY   rH   r@   emptyrP   
isinstanceBaseException)r$   r\   rR   r   r   r   __exit__   s    


zWebSocketTestSession.__exit__c              	     sz   ddd fdd}t  4 I dH <}|||  j I dH  |j  W d  I dH  qv1 I dH sl0    Y  dS )zE
        The sub-thread in which the websocket session runs.
        zanyio.abc.TaskGroupr"   )tgr   c              
     s   ztz   j j jI d H  W nF t y6   Y n2 tyf } z j|  W Y d }~n
d }~0 0 W | j	
  n| j	
  0 d S r#   )r   r&   _asgi_receive
_asgi_sendrT   Zget_cancelled_exc_classr`   r@   putcancel_scopecancel)rb   excrV   r   r   run_app   s    z*WebSocketTestSession._run.<locals>.run_appN)rT   Zcreate_task_groupZ
start_soonrW   waitrf   rg   )r$   ri   rb   r   rV   r   rL      s
    zWebSocketTestSession._runr   c                   s&   | j  rtdI d H  q | j  S )Nr   )r?   r^   rT   sleeprP   rV   r   r   r   rc      s    
z"WebSocketTestSession._asgi_receiverR   r   c                   s   | j | d S r#   )r@   re   r$   rR   r   r   r   rd      s    zWebSocketTestSession._asgi_sendc                 C  s   |d dkr*t |dd|dddnj|d dkr|d	 }|d
 }g }|  }|d dksbJ ||d  |ddsJqqJt||d|dd S )NrC   zwebsocket.closecoder]   reason )rn   ro   zwebsocket.http.response.startstatusrE   zwebsocket.http.response.bodybody	more_bodyF    )status_coderE   content)r   rP   r'   appendr8   join)r$   rR   ru   rE   rr   r   r   r   rM      s$    z$WebSocketTestSession._raise_on_closec                 C  s   | j | d S r#   )r?   re   rm   r   r   r   r(      s    zWebSocketTestSession.sendr0   )datar   c                 C  s   |  d|d d S )Nwebsocket.receiverC   textr(   r$   ry   r   r   r   	send_text   s    zWebSocketTestSession.send_textbytesc                 C  s   |  d|d d S )Nrz   rC   r   r}   r~   r   r   r   
send_bytes   s    zWebSocketTestSession.send_bytesr|   z typing.Literal['text', 'binary'])ry   moder   c                 C  sD   t j|ddd}|dkr*| d|d n| d|dd d S )	N),:F)
separatorsensure_asciir|   rz   r{   utf-8r   )jsondumpsr(   encode)r$   ry   r   r|   r   r   r   	send_json   s    zWebSocketTestSession.send_jsonr]   Nintz
str | None)rn   ro   r   c                 C  s   |  d||d d S )Nzwebsocket.disconnect)rC   rn   ro   r}   )r$   rn   ro   r   r   r   rO      s    zWebSocketTestSession.closec                 C  s   | j  }t|tr||S r#   )r@   rP   r_   r`   rm   r   r   r   r'      s    

zWebSocketTestSession.receivec                 C  s"   |   }| | tt|d S )Nr|   )r'   rM   typingcastr0   rm   r   r   r   receive_text   s    
z!WebSocketTestSession.receive_textc                 C  s"   |   }| | tt|d S )Nr   )r'   rM   r   r   r   rm   r   r   r   receive_bytes   s    
z"WebSocketTestSession.receive_bytes)r   r   c                 C  s<   |   }| | |dkr$|d }n|d d}t|S )Nr|   r   r   )r'   rM   decoder   loads)r$   r   rR   r|   r   r   r   receive_json   s    

z!WebSocketTestSession.receive_json)r|   )r]   N)r|   )r+   r,   r-   r%   rS   r   rW   rY   ra   rL   rc   rd   rM   r(   r   r   r   rO   r'   r   r   r   r   r   r   r   r6   [   s*    	 r6   c                   @  s6   e Zd Zdddddddd	d
dZdddddZdS )_TestClientTransportTrp   r9   r:   boolr0   r2   r"   )r   r;   raise_server_exceptions	root_path	app_stater   c                C  s"   || _ || _|| _|| _|| _d S r#   )r   r   r   r;   r   )r$   r   r;   r   r   r   r   r   r   r%      s
    	z_TestClientTransport.__init__zhttpx.Requesthttpx.Response)requestr   c                   s  j j}j jjdd}j j}j j}j jjdd}ddddd| }d|v rl|dd\}}	t|	}
n|}|}
dj	v rg }n0|
|krd	|
 fg}nd	| d|
 
 fg}|d
d j	 D 7 }|dv rXj	dd }|d u rg }ndd |dD }dt||| j||
 |ddg||
g|| j di id}t| j|| j}t|ddjt||| j||
 |ddg||
gdi i| j d}dddt id d  ddfdd}ddd  fd!d"}zL|  .}|tj|| j||| W d    n1 s&0    Y  W n2 tyd } z| jrP|W Y d }~n
d }~0 0 | jr~sJ d#nsd$g t d%td  d< tj f i d&i}d ur؈|_! |_"|S )'Nascii)encodingP   i  )httpwshttpswssr      hosts   hostc                 S  s$   g | ]\}}|   | fqS r   )lowerr   .0keyvaluer   r   r   
<listcomp>  s   z7_TestClientTransport.handle_request.<locals>.<listcomp>>   r   r   sec-websocket-protocolc                 S  s   g | ]}|  qS r   )strip)r   r   r   r   r   r   $  rt   r   Z	websocket
testclientiP  zwebsocket.http.response)rC   pathraw_pathr   schemequery_stringrE   clientserversubprotocolsstate
extensionsr   z1.1http.response.debug)rC   http_versionmethodr   r   r   r   r   rE   r   r   r   r   Fstreamr   rB   c                    s   r"  s I d H  ddiS   } t| tr@| d}nl| d u rNd}n^t| trz,| d }t|trx|d}d|ddW S  ty   dddd Y S 0 n| }dd|dS )	NrC   zhttp.disconnectr   rt   zhttp.requestT)rC   rr   rs   )rC   rr   )	is_setrj   readr_   r0   r   r   r(   StopIteration)rr   Z
body_byteschunk)r   request_completeresponse_completer   r   r'   M  s*    




z4_TestClientTransport.handle_request.<locals>.receiver"   rl   c                   s   | d dkrDrJ d| d d< dd |  dg D d< d	n| d d
krs\J d rlJ d|  dd}|  dd}jdkrd | |s܈d d   n$| d dkr| d d | d d  d S )NrC   zhttp.response.startz1Received multiple "http.response.start" messages.rq   ru   c                 S  s    g | ]\}}|  |  fqS r   )r   r   r   r   r   r   q  s   zE_TestClientTransport.handle_request.<locals>.send.<locals>.<listcomp>rE   Tzhttp.response.bodyz<Received "http.response.body" without "http.response.start".z7Received "http.response.body" after response completed.rr   rt   rs   FHEADr   r   r   infotemplatecontext)rP   r   r   writeseekrX   )rR   rr   rs   )r   
raw_kwargsr   r   response_startedr   r   r   r(   i  s:    



z1_TestClientTransport.handle_request.<locals>.sendz(TestClient did not receive any response.i  )ru   rE   r   r   )#urlr   netlocr   r   r   querysplitr   rE   r   Zmulti_itemsrP   r   r   r   copyr6   r   r;   r5   r   ioBytesIOcallrT   rU   r`   r   httpxZ
ByteStreamr   Responser   r   )r$   r   r   r   r   r   r   default_portr   Zport_stringportrE   rD   r   r&   r7   r'   r(   rJ   rh   responser   )r   r   r   r   r   r   r   r   handle_request   s    



6
z#_TestClientTransport.handle_requestN)Trp   )r+   r,   r-   r%   r   r   r   r   r   r      s     r   c                      s  e Zd ZU dZded< dZded< dNddddddddddd
 fddZejddddZ	ddddddZ
dddddddejjddejjdddd d!d"d#d$d%d&dd'ddd(dd)d* fd+d,Zdddejjddejjdd-d d%d&dd'ddd(dd)d.
 fd/d0Zdddejjddejjdd-d d%d&dd'ddd(dd)d.
 fd1d2Zdddejjddejjdd-d d%d&dd'ddd(dd)d.
 fd3d4Zdddddddejjddejjddd d!d"d#d$d%d&dd'ddd(dd)d5 fd6d7Zdddddddejjddejjddd d!d"d#d$d%d&dd'ddd(dd)d5 fd8d9Zdddddddejjddejjddd d!d"d#d$d%d&dd'ddd(dd)d5 fd:d;Zdddejjddejjdd-d d%d&dd'ddd(dd)d.
 fd<d=ZdOdd>d$d?d@ fdAdBZd ddCdDZd$ddEdFdGZdddHdIZdddJdKZdddLdMZ  ZS )P
TestClientFzFuture[None]taskNzanyio.abc.BlockingPortal | NonerJ   http://testserverTrp   asyncior   r0   r   z!typing.Literal['asyncio', 'trio']zdict[str, typing.Any] | Nonezhttpx._types.CookieTypes | Nonezdict[str, str] | Noner"   )
r   base_urlr   r   r1   r3   cookiesrE   follow_redirectsr   c
                   s   t ||p
i d| _t|r |}
ntt|}t|}
|
| _i | _t	| j| j
||| jd}|d u rdi }|dd t j||||	|d d S )N)r1   r3   )r;   r   r   r   z
user-agentr   )r   rE   	transportr   r   )r/   async_backendr   r   r   r!   r    r   r   r   _portal_factory
setdefaultsuperr%   )r$   r   r   r   r   r1   r3   r   rE   r   Zasgi_appr   	__class__r   r   r%     s4    zTestClient.__init__z6typing.Generator[anyio.abc.BlockingPortal, None, None]rB   c                 c  sR   | j d ur| j V  n:tjjf i | j}|V  W d    n1 sD0    Y  d S r#   )rJ   rT   from_threadstart_blocking_portalr   )r$   rJ   r   r   r   r     s    


zTestClient._portal_factoryzbool | Nonez%bool | httpx._client.UseClientDefault)r   allow_redirectsr   c                 C  sN   t jj}|d ur$d}t|t |}|d ur2|}n|d urJ|d urJtd|S )NzMThe `allow_redirects` argument is deprecated. Use `follow_redirects` instead.z9Cannot use both `allow_redirects` and `follow_redirects`.)r   _clientUSE_CLIENT_DEFAULTwarningswarnDeprecationWarningRuntimeError)r$   r   r   redirectrR   r   r   r   _choose_redirect_arg  s    zTestClient._choose_redirect_arg)rv   ry   filesr   paramsrE   r   authr   r   timeoutr   zhttpx._types.URLTypesz"httpx._types.RequestContent | Nonez_RequestData | Nonez httpx._types.RequestFiles | NonerZ   z#httpx._types.QueryParamTypes | Nonezhttpx._types.HeaderTypes | Nonez7httpx._types.AuthTypes | httpx._client.UseClientDefaultz:httpx._types.TimeoutTypes | httpx._client.UseClientDefaultr   )r   r   rv   ry   r   r   r   rE   r   r   r   r   r   r   r   c                  s<   |  |}| ||}t j|||||||||	|
|||dS N)rv   ry   r   r   r   rE   r   r   r   r   r   )Z
_merge_urlr   r   r   )r$   r   r   rv   ry   r   r   r   rE   r   r   r   r   r   r   r   r   r   r   r     s"    
zTestClient.request)r   rE   r   r   r   r   r   r   )
r   r   rE   r   r   r   r   r   r   r   c             
     s(   |  ||}
t j||||||
||	dS N)r   rE   r   r   r   r   r   )r   r   rP   r$   r   r   rE   r   r   r   r   r   r   r   r   r   r   rP     s    zTestClient.getc             
     s(   |  ||}
t j||||||
||	dS r   )r   r   optionsr   r   r   r   r   /  s    zTestClient.optionsc             
     s(   |  ||}
t j||||||
||	dS r   )r   r   headr   r   r   r   r   J  s    zTestClient.head)r   rv   ry   r   r   r   rE   r   r   r   r   r   r   r   c                  s0   |  |
|}t j|||||||||	|||dS r   )r   r   postr$   r   rv   ry   r   r   r   rE   r   r   r   r   r   r   r   r   r   r   r   e  s    zTestClient.postc                  s0   |  |
|}t j|||||||||	|||dS r   )r   r   re   r   r   r   r   re     s    zTestClient.putc                  s0   |  |
|}t j|||||||||	|||dS r   )r   r   patchr   r   r   r   r     s    zTestClient.patchc             
     s(   |  ||}
t j||||||
||	dS r   )r   r   deleter   r   r   r   r     s    zTestClient.deleteztyping.Sequence[str] | Noner6   )r   r   kwargsr   c              
     s   t d|}|di }|dd |dd |dd |d urT|d	d
| ||d< zt jd|fi | W n* ty } z|j}W Y d }~nd }~0 0 td|S )Nzws://testserverrE   
connectionupgradezsec-websocket-keyztestserver==zsec-websocket-versionZ13r   z, GETzExpected WebSocket upgrade)	r   rP   r   rx   r   r   r5   r7   r   )r$   r   r   r   rE   rh   r7   r   r   r   websocket_connect  s    
zTestClient.websocket_connectc                   s   t  }|tjjf i j _ |jddfdd}t	t
j\}}t	t
j\}}t||_t||_ j_ j |jdd fdd}| _W d    n1 s0    Y  S )Nr"   rB   c                     s
   d  _ d S r#   )rJ   r   rV   r   r   reset_portal  s    z*TestClient.__enter__.<locals>.reset_portalc                     s     j d S r#   )r   wait_shutdownr   rJ   r$   r   r   r    s    z+TestClient.__enter__.<locals>.wait_shutdown)rF   rG   rI   rT   r   r   r   rJ   callbackZcreate_memory_object_streammathinfr
   stream_sendstream_receiverK   lifespanr   r   wait_startuppop_allrH   )r$   stackr  Zsend1Zreceive1Zsend2Zreceive2r  r   r  r   rS      s     

(zTestClient.__enter__r[   c                 G  s   | j   d S r#   )rH   rO   )r$   r\   r   r   r   ra     s    zTestClient.__exit__c              	     sX   d| j d}z2| || jj| jjI d H  W | jd I d H  n| jd I d H  0 d S )Nr
  )rC   r   )r   r   r	  r'   r  r(   )r$   r&   r   r   r   r
     s    zTestClient.lifespanc                   s`    j ddiI d H  dd fdd}| I d H }|d dv sDJ |d dkr\| I d H  d S )	NrC   zlifespan.startuprZ   rB   c                    s&    j  I d H } | d u r" j  | S r#   r  r'   r   resultrR   rV   r   r   r'   *  s    
z(TestClient.wait_startup.<locals>.receive)zlifespan.startup.completelifespan.startup.failedr  )r	  r(   r$   r'   rR   r   rV   r   r  '  s    zTestClient.wait_startupc              	     s   dd fdd} j 4 I d H `  jddiI d H  | I d H }|d dv sTJ |d dkrl| I d H  W d   I d H  q1 I d H s0    Y  d S )	NrZ   rB   c                    s&    j  I d H } | d u r" j  | S r#   r  r  rV   r   r   r'   9  s    
z)TestClient.wait_shutdown.<locals>.receiverC   zlifespan.shutdown)zlifespan.shutdown.completelifespan.shutdown.failedr  )r  r	  r(   r  r   rV   r   r  8  s    zTestClient.wait_shutdown)r   Trp   r   NNNT)N)r+   r,   r-   Z__test__r4   rJ   r%   rF   contextmanagerr   r   r   r   r   r   rP   r   r   r   re   r   r   r  rS   ra   r
  r  r  __classcell__r   r   r   r   r     s   
        &(	2*(((0'0'0'( r   )G
__future__r   rF   r   r   r   r  r=   sysr   r   concurrent.futuresr   	functoolsr   typesr   urllib.parser   r   rT   Z	anyio.abcZanyio.from_threadr   r	   Zanyio.streams.stapledr
   Zstarlette._utilsr   Zstarlette.typesr   r   r   r   r   Zstarlette.websocketsr   version_infor   Ztyping_extensionsr   ModuleNotFoundErrorr   CallableContextManagerabcZBlockingPortalr:   	AwaitableZASGIInstancer!   r9   Mappingr0   UnionIterabler   Z_RequestDatar   r    	TypedDictr/   rN   r5   r   r8   r6   ZBaseTransportr   ZClientr   r   r   r   r   <module>   sd   
 

  4