o
    `^h$u                     @  s6  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rd dl	m&Z& nd dl'm&Z& zd dl(Z(W n e)y   e*dw 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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
appASGI2App | ASGI3AppreturnTypeGuard[ASGI3App]c                 C  s   t | r
t| dS t| S )N	__await__)inspectisclasshasattrr   r    r   R/home/air/shanriGPT/back/venv/lib/python3.10/site-packages/starlette/testclient.py	_is_asgi32   s   

r    c                   @  s$   e Zd ZdZdddZdddZdS )
_WrapASGI2z7
    Provide an ASGI3 interface onto an ASGI2 app.
    r   ASGI2Appr   Nonec                 C  
   || _ d S Nr   )selfr   r   r   r   __init__=      
z_WrapASGI2.__init__scoper   receiver   sendr   c                   s    |  |}|||I d H  d S r%   r   )r&   r)   r*   r+   instancer   r   r   __call__@   s   
z_WrapASGI2.__call__N)r   r"   r   r#   )r)   r   r*   r   r+   r   r   r#   )__name__
__module____qualname____doc__r'   r-   r   r   r   r   r!   8   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/   r0   __annotations__r   r   r   r   r2   E   s   
 r2   c                   @  s   e Zd ZdddZdS )	_UpgradesessionWebSocketTestSessionr   r#   c                 C  r$   r%   )r9   )r&   r9   r   r   r   r'   K   r(   z_Upgrade.__init__N)r9   r:   r   r#   )r.   r/   r0   r'   r   r   r   r   r8   J   s    r8   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/   r0   r1   r   r   r   r   r;   O   s    r;   c                   @  s   e Zd Zd>d	d
Zd?ddZed@ddZdAddZdBddZdAddZ	dCddZ
dDddZdDddZdDd d!ZdEd$d%ZdFd'd(ZdGdHd,d-ZdIdJd4d5ZdCd6d7ZdKd8d9ZdLd:d;ZdGdMd<d=Zd/S )Nr:   r   ASGI3Appr)   r   portal_factory_PortalFactoryTyper   r#   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'   Z   s   


zWebSocketTestSession.__init__c                 C  s   t  | _| j|  | _z| j| j}| ddi | 	 }| 
| W n ty4   | j   w |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?   rD   )r&   _messager   r   r   	__enter__h   s   

zWebSocketTestSession.__enter__anyio.Eventc                 C  s   t  S r%   )anyioEventr&   r   r   r   should_closex   s   z!WebSocketTestSession.should_closec                   s   | j   d S r%   )rZ   setrY   r   r   r   _notify_close|   s   z"WebSocketTestSession._notify_closeargs
typing.Anyc              	   G  sv   z|  d W | j| j | j   n| j| j | j   w | j s9| j }t|t	r2|| j r&d S d S )N  )
rQ   rL   rM   r\   rJ   rC   emptyrR   
isinstanceBaseException)r&   r]   rT   r   r   r   __exit__   s   


zWebSocketTestSession.__exit__c              	     sx   d fdd}t  4 I dH }|||  j I dH  |j  W d  I dH  dS 1 I dH s5w   Y  dS )	zE
        The sub-thread in which the websocket session runs.
        tganyio.abc.TaskGroupr   r#   c              
     s   z=z   j j jI d H  W n t y   Y n ty. } z j|  d }~ww W | j	
  d S W | j	
  d S | j	
  w r%   )r   r)   _asgi_receive
_asgi_sendrW   get_cancelled_exc_classrb   rC   putcancel_scopecancel)rd   excrY   r   r   run_app   s   z*WebSocketTestSession._run.<locals>.run_appN)rd   re   r   r#   )rW   create_task_group
start_soonrZ   waitrj   rk   )r&   rm   rd   r   rY   r   rN      s   .zWebSocketTestSession._runr   c                   s:   | j  rt | _| j I d H  | j  s| j  S r%   )rB   r`   rW   rX   _queue_eventrp   rR   rY   r   r   r   rf      s   



z"WebSocketTestSession._asgi_receiverT   c                   s   | j | d S r%   )rC   ri   r&   rT   r   r   r   rg      s   zWebSocketTestSession._asgi_sendc                 C  s   |d dkrt |dd|ddd|d dkrJ|d	 }|d
 }g }	 |  }|d dks1J ||d  |dds?nq%t||d|dd S )NrE   zwebsocket.closecoder_   reason )rs   rt   zwebsocket.http.response.startstatusrG   Tzwebsocket.http.response.bodybody	more_bodyF    )status_coderG   content)r   rR   r*   appendr;   join)r&   rT   rz   rG   rw   r   r   r   rO      s&   z$WebSocketTestSession._raise_on_closec                 C  s.   | j | t| dr| j| jj d S d S )Nrq   )rB   ri   r   rL   rM   rq   r[   rr   r   r   r   r+      s   
zWebSocketTestSession.senddatar3   c                 C     |  d|d d S )Nwebsocket.receiverE   textr+   r&   r~   r   r   r   	send_text      zWebSocketTestSession.send_textbytesc                 C  r   )Nr   rE   r   r   r   r   r   r   
send_bytes   r   zWebSocketTestSession.send_bytesr   mode typing.Literal['text', 'binary']c                 C  sF   t j|ddd}|dkr| d|d d S | d|dd d S )	N),:F)
separatorsensure_asciir   r   r   utf-8r   )jsondumpsr+   encode)r&   r~   r   r   r   r   r   	send_json   s   zWebSocketTestSession.send_jsonr_   Nrs   intrt   
str | Nonec                 C  s   |  d||d d S )Nzwebsocket.disconnect)rE   rs   rt   r   )r&   rs   rt   r   r   r   rQ      s   zWebSocketTestSession.closec                 C  s   | j  }t|tr||S r%   )rC   rR   ra   rb   rr   r   r   r   r*      s   

zWebSocketTestSession.receivec                 C  "   |   }| | tt|d S )Nr   )r*   rO   typingcastr3   rr   r   r   r   receive_text      
z!WebSocketTestSession.receive_textc                 C  r   )Nr   )r*   rO   r   r   r   rr   r   r   r   receive_bytes   r   z"WebSocketTestSession.receive_bytesc                 C  s<   |   }| | |dkr|d }n|d d}t|S )Nr   r   r   )r*   rO   decoder   loads)r&   r   rT   r   r   r   r   receive_json   s   


z!WebSocketTestSession.receive_json)r   r<   r)   r   r=   r>   r   r#   )r   r:   )r   rV   r   r#   r]   r^   r   r#   r   r   rT   r   r   r#   )r~   r3   r   r#   )r~   r   r   r#   )r   )r~   r^   r   r   r   r#   )r_   N)rs   r   rt   r   r   r#   )r   r3   )r   r   )r   r   r   r^   )r.   r/   r0   r'   rU   r   rZ   r\   rc   rN   rf   rg   rO   r+   r   r   r   rQ   r*   r   r   r   r   r   r   r   r:   Y   s(    













r:   c                   @  s&   e Zd Z		ddddZdddZdS )_TestClientTransportTru   r   r<   r=   r>   raise_server_exceptionsbool	root_pathr3   	app_stater5   r   r#   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__requesthttpx.Requesthttpx.Responsec                   s  j j}j jjdd}j j}j j}j jjdd}ddddd| }d|v r6|dd\}}	t|	}
n|}|}
dj	v rBg }n|
|krNd	|
 fg}nd	| d|
 
 fg}|d
d j	 D 7 }|dv rj	dd }|d u rxg }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'fdd}d( fd!d"}z&|  }|tj|| j||| W d    n	1 sw   Y  W n ty, } z| jr"|W Y d }~nd }~ww | jr9s8J d#nsDd$g t d%td  d< tj d)i d&i}d urf|_! |_"|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     s    r   	websocket
testclientiP  zwebsocket.http.response)rE   pathraw_pathr   schemequery_stringrG   clientserversubprotocolsstate
extensionsr   z1.1http.response.debug)rE   http_versionmethodr   r   r   r   r   rG   r   r   r   r   Fstreamr   r   c                    s   r  s I d H  ddiS   } t| tr!| d}n5| d u r(d}n.t| trTz| d }t|tr=|d}d|ddW S  tyS   dddd Y S w | }dd|dS )	NrE   zhttp.disconnectr   ry   zhttp.requestT)rE   rw   rx   )rE   rw   )	is_setrp   readra   r3   r   r   r+   StopIteration)rw   
body_byteschunk)r   request_completeresponse_completer   r   r*   E  s.   





z4_TestClientTransport.handle_request.<locals>.receiverT   r#   c                   s   | d dkr$rJ d| d d< dd |  dg D d< d	d S | d d
kras0J d r8J d|  dd}|  dd}jdkrPd | |s_d d   d S d S | d dkru| d d | d d  d S d S )NrE   zhttp.response.startz1Received multiple "http.response.start" messages.rv   rz   c                 S  s    g | ]\}}|  |  fqS r   )r   r   r   r   r   r   g  s     zE_TestClientTransport.handle_request.<locals>.send.<locals>.<listcomp>rG   Tzhttp.response.bodyz<Received "http.response.body" without "http.response.start".z7Received "http.response.body" after response completed.rw   ry   rx   FHEADr   r   r   infotemplatecontext)rR   r   r   writeseekr[   )rT   rw   rx   )r   
raw_kwargsr   r   response_startedr   r   r   r+   a  s*   
z1_TestClientTransport.handle_request.<locals>.sendz(TestClient did not receive any response.i  )rz   rG   r   r   r   r   r   )#urlr   netlocr   r   r   querysplitr   rG   r   multi_itemsrR   r   r   r   copyr:   r   r=   r8   r   ioBytesIOcallrW   rX   rb   r   httpx
ByteStreamr   Responser   r   )r&   r   r   r   r   r   r   default_portr   port_stringportrG   rF   r   r)   r9   r*   r+   rL   rl   responser   )r   r   r   r   r   r   r   r   handle_request   s   



z#_TestClientTransport.handle_requestN)Tru   )r   r<   r=   r>   r   r   r   r3   r   r5   r   r#   )r   r   r   r   )r.   r/   r0   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< 					
				d^d_ fddZejd`d d!Z	dad%d&Z
dddddddejjddejjdd'db fd<d=Zdddejjddejjdd>dc fd?d@Zdddejjddejjdd>dc fdAdBZdddejjddejjdd>dc fdCdDZdddddddejjddejjdd'dd fdEdFZdddddddejjddejjdd'dd fdGdHZdddddddejjddejjdd'dd fdIdJZdddejjddejjdd>dc fdKdLZ	dedf fdQdRZdgdSdTZdhdVdWZdidXdYZdidZd[Zdid\d]Z  ZS )j
TestClientFzFuture[None]taskNzanyio.abc.BlockingPortal | NonerL   http://testserverTru   asyncior   r   base_urlr3   r   r   r   r4   !typing.Literal['asyncio', 'trio']r6   dict[str, typing.Any] | Nonecookieshttpx._types.CookieTypes | NonerG   dict[str, str] | Nonefollow_redirectsr   r#   c
                   s   t ||pi d| _t|r|}
n
tt|}t|}
|
| _i | _t	| j| j
||| jd}|d u r2i }|dd t j||||	|d d S )N)r4   r6   )r=   r   r   r   z
user-agentr   )r   rG   	transportr   r   )r2   async_backendr    r   r   r"   r!   r   r   r   _portal_factory
setdefaultsuperr'   )r&   r   r   r   r   r4   r6   r   rG   r   asgi_appr   	__class__r   r   r'     s0   
zTestClient.__init__6typing.Generator[anyio.abc.BlockingPortal, None, None]c                 c  sX    | j d ur| j V  d S tjjdi | j}|V  W d    d S 1 s%w   Y  d S )Nr   )rL   rW   from_threadstart_blocking_portalr   )r&   rL   r   r   r   r     s   
"zTestClient._portal_factorybool | Noneallow_redirects%bool | httpx._client.UseClientDefaultc                 C  sP   t jj}|d urd}t|t |}|d ur|}|S |d ur&|d ur&t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  redirectrT   r   r   r   _choose_redirect_arg  s   zTestClient._choose_redirect_arg)r{   r~   filesr   paramsrG   r   authr   r  timeoutr   r   r   httpx._types.URLTypesr{   "httpx._types.RequestContent | Noner~   _RequestData | Noner   httpx._types.RequestFiles | Noner   r^   r  #httpx._types.QueryParamTypes | Nonehttpx._types.HeaderTypes | Noner  7httpx._types.AuthTypes | httpx._client.UseClientDefaultr  :httpx._types.TimeoutTypes | httpx._client.UseClientDefaultr   r   c                  s<   |  |}| ||}t j|||||||||	|
|||dS N)r{   r~   r  r   r  rG   r   r  r   r  r   )
_merge_urlr  r   r   )r&   r   r   r{   r~   r  r   r  rG   r   r  r   r  r  r   r  r   r   r   r     s"   
zTestClient.request)r  rG   r   r  r   r  r  r   c             
     (   |  ||}
t j||||||
||	dS N)r  rG   r   r  r   r  r   )r  r   rR   r&   r   r  rG   r   r  r   r  r  r   r  r   r   r   rR        zTestClient.getc             
     r  r  )r  r   optionsr  r   r   r   r    r  zTestClient.optionsc             
     r  r  )r  r   headr  r   r   r   r   *  r  zTestClient.headc                  0   |  |
|}t j|||||||||	|||dS r  )r  r   postr&   r   r{   r~   r  r   r  rG   r   r  r   r  r  r   r  r   r   r   r"  C     zTestClient.postc                  r!  r  )r  r   ri   r#  r   r   r   ri   d  r$  zTestClient.putc                  r!  r  )r  r   patchr#  r   r   r   r%    r$  zTestClient.patchc             
     r  r  )r  r   deleter  r   r   r   r&    r  zTestClient.deleter   typing.Sequence[str] | Nonekwargsr:   c              
     s   t d|}|di }|dd |dd |dd |d ur*|d	d
| ||d< zt jd|fi | W td tyT } z
|j}W Y d }~|S d }~ww )Nzws://testserverrG   
connectionupgradezsec-websocket-keyztestserver==zsec-websocket-version13r   z, GETzExpected WebSocket upgrade)	r   rR   r   r}   r   r   r8   r9   r
  )r&   r   r   r(  rG   rl   r9   r   r   r   websocket_connect  s    
zTestClient.websocket_connectc                   s   t  \}|tjjdi j _ |jdfdd}t	t
j\}}t	t
j\}}t||_t||_ j_ j |jd fdd}| _W d    S 1 scw   Y  S )	Nr   r#   c                     s
   d  _ d S r%   )rL   r   rY   r   r   reset_portal  s   
z*TestClient.__enter__.<locals>.reset_portalc                     s     j d S r%   )r   wait_shutdownr   rL   r&   r   r   r/    s   z+TestClient.__enter__.<locals>.wait_shutdownr   r   )rH   rI   rK   rW   r   r  r   rL   callbackcreate_memory_object_streammathinfr
   stream_sendstream_receiverM   lifespanr   r   wait_startuppop_allrJ   )r&   stackr.  send1receive1send2receive2r/  r   r0  r   rU     s"   
 
zTestClient.__enter__r]   c                 G  s   | j   d S r%   )rJ   rQ   )r&   r]   r   r   r   rc     s   zTestClient.__exit__c              	     sX   d| j d}z| || jj| jjI d H  W | jd I d H  d S | jd I d H  w )Nr7  )rE   r   )r   r   r6  r*   r5  r+   )r&   r)   r   r   r   r7    s
   *zTestClient.lifespanc                   sb    j ddiI d H  d	 fdd}| I d H }|d dv s!J |d dkr/| I d H  d S d S )
NrE   zlifespan.startupr   r^   c                    (    j  I d H } | d u r j  | S r%   r5  r*   r   resultrT   rY   r   r   r*     
   
z(TestClient.wait_startup.<locals>.receive)zlifespan.startup.completelifespan.startup.failedrD  r   r^   )r6  r+   r&   r*   rT   r   rY   r   r8    s   zTestClient.wait_startupc              
     s   d	 fdd} j 4 I d H N  j4 I d H 0  jddiI d H  | I d H }|d dv s1J |d dkr=| I d H  W d   I d H  n1 I d H sMw   Y  W d   I d H  d S 1 I d H scw   Y  d S )
Nr   r^   c                    r?  r%   r@  rB  rY   r   r   r*     rC  z)TestClient.wait_shutdown.<locals>.receiverE   zlifespan.shutdown)zlifespan.shutdown.completelifespan.shutdown.failedrG  rE  )r5  r6  r+   rF  r   rY   r   r/    s    XzTestClient.wait_shutdown)r   Tru   r   NNNT)r   r   r   r3   r   r   r   r3   r4   r   r6   r   r   r   rG   r   r   r   r   r#   )r   r   )r   r  r  r  r   r  )r   r3   r   r  r{   r  r~   r  r  r  r   r^   r  r  rG   r  r   r   r  r  r   r  r  r  r  r  r   r   r   r   )r   r  r  r  rG   r  r   r   r  r  r   r  r  r  r  r  r   r   r   r   )r   r  r{   r  r~   r  r  r  r   r^   r  r  rG   r  r   r   r  r  r   r  r  r  r  r  r   r   r   r   r%   )r   r3   r   r'  r(  r^   r   r:   )r   r   r   r   )r.   r/   r0   __test__r7   rL   r'   rH   contextmanagerr   r  r   r  r  r   rR   r  r   r"  ri   r%  r&  r-  rU   rc   r7  r8  r/  __classcell__r   r   r   r   r     s   
 &
(%%%



r   )r   r   r   r   )G
__future__r   rH   r   r   r   r3  r@   sysr   r  concurrent.futuresr   	functoolsr   typesr   urllib.parser   r   rW   	anyio.abcanyio.from_threadr   r	   anyio.streams.stapledr
   starlette._utilsr   starlette.typesr   r   r   r   r   starlette.websocketsr   version_infor   typing_extensionsr   ModuleNotFoundErrorr
  CallableContextManagerabcBlockingPortalr>   	AwaitableASGIInstancer"   r<   Mappingr3   UnionIterabler   _RequestDatar    r!   	TypedDictr2   rP   r8   r   r;   r:   BaseTransportr   Clientr   r   r   r   r   <module>   sd    
 


  (