o
    m=8jn                     @  s  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	m
Z
mZ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mZmZmZmZ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$ 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/m0Z0 ej1dkrd dlm2Z2 nd dl3m2Z2 erd dl4Z5n+zd dl4Z5W n$ e6y   zd dl5Z5W n e6y   e7ddw ej8de(dd Y nw eg ee j9j: f Z;ee,e.ge
d f Z<ee-ge<f Z=ee-e,e.ge
d f Z>ee?e?ee? B e@B f ZAd(ddZBG dd dZCG dd deZDG dd deEZFG d d! d!e5jGe0ZHG d"d# d#ZIG d$d% d%e5jJZKG d&d' d'e5jLZMdS ))    )annotationsN)	AwaitableCallable	GeneratorIterableMappingMutableMappingSequence)Future)AbstractContextManager)GeneratorType)TYPE_CHECKINGAnyLiteral	TypedDict	TypeGuardcast)unquoteurljoin)StapledObjectStream)is_async_callable)StarletteDeprecationWarning)ASGIAppMessageReceiveScopeSend)WebSocketDisconnect)      )SelfzThe starlette.testclient module requires the httpx2 package to be installed.
You can install this with:
    $ pip install httpx2
zRUsing `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.   
stacklevelappASGI2App | ASGI3AppreturnTypeGuard[ASGI3App]c                 C  s   t | r
t| dS t| S )N	__await__)inspectisclasshasattrr   r$    r-   [/home/nk/hobo-godmode/plappi-mvp/.venv/lib/python3.10/site-packages/starlette/testclient.py	_is_asgi3?   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__J      
z_WrapASGI2.__init__scoper   receiver   sendr   c                   s    |  |}|||I d H  d S r4   r,   )r5   r8   r9   r:   instancer-   r-   r.   __call__M   s   
z_WrapASGI2.__call__N)r$   r1   r&   r2   )r8   r   r9   r   r:   r   r&   r2   )__name__
__module____qualname____doc__r6   r<   r-   r-   r-   r.   r0   E   s    
r0   c                   @  s   e Zd ZU ded< ded< dS )_AsyncBackendstrbackenddict[str, Any]backend_optionsN)r=   r>   r?   __annotations__r-   r-   r-   r.   rA   R   s   
 rA   c                   @  s   e Zd ZdddZdS )	_UpgradesessionWebSocketTestSessionr&   r2   c                 C  r3   r4   )rH   )r5   rH   r-   r-   r.   r6   X   r7   z_Upgrade.__init__N)rH   rI   r&   r2   )r=   r>   r?   r6   r-   r-   r-   r.   rG   W   s    rG   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.   rJ   \   s    rJ   c                   @  s   e Zd Zd9d	d
Zd:ddZd;ddZd<ddZd=ddZd=ddZd>dd Z	d?d"d#Z
d@dAd'd(ZdBdCd/d0ZdDd1d2ZdEd3d4ZdFd5d6Zd@dGd7d8Zd*S )HrI   r$   ASGI3Appr8   r   portal_factory_PortalFactoryTyper&   r2   c                 C  s"   || _ || _d | _|| _d | _d S r4   )r$   r8   accepted_subprotocolrL   extra_headers)r5   r$   r8   rL   r-   r-   r.   r6   g   s
   
zWebSocketTestSession.__init__r    c                 C  s   t  T}||   | _}|| j\}}||j ||j	|j
 | ddi |  }| | |dd | _|dd | _|| jd | | _| W  d    S 1 s[w   Y  d S )Ntypezwebsocket.connectsubprotocolheaders  )
contextlib	ExitStackenter_contextrL   portal
start_task_runcallbackresultcallcancelr:   r9   _raise_on_closegetrN   rO   closepop_all
exit_stack)r5   stackrW   futcsmessager-   r-   r.   	__enter__s   s   


$zWebSocketTestSession.__enter__argsr   bool | Nonec                 G  s   | j j| S r4   )rb   __exit__r5   rh   r-   r-   r.   rj      s   zWebSocketTestSession.__exit__task_status'anyio.abc.TaskStatus[anyio.CancelScope]c          	        s6  t tj}|\}}t tj}|\}}|z |_ |M |; t  '}|| _|| _|| | | j	|j
|jI dH  t  I dH  W d   n1 sOw   Y  W d   n1 s^w   Y  W d   n1 smw   Y  W d   n1 s|w   Y  W d   dS W d   dS 1 sw   Y  dS )zE
        The sub-thread in which the websocket session runs.
        N)anyiocreate_memory_object_streammathinfCancelScope_receive_tx_send_rxstartedr$   r8   r9   r:   sleep_forever)	r5   rl   r:   send_txsend_rxr9   
receive_tx
receive_rxre   r-   r-   r.   rY      s$   "
  P zWebSocketTestSession._runrf   r   c                 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 )NrP   zwebsocket.closecoderS   reason )r{   r|   zwebsocket.http.response.startstatusrR   Tzwebsocket.http.response.bodybody	more_bodyF    )status_coderR   content)r   r_   r9   appendrJ   join)r5   rf   r   rR   r   r-   r-   r.   r^      s   z$WebSocketTestSession._raise_on_closec                 C  s   | j | jj| d S r4   )rW   r\   rs   r:   r5   rf   r-   r-   r.   r:         zWebSocketTestSession.senddatarB   c                 C     |  d|d d S )Nwebsocket.receiverP   textr:   r5   r   r-   r-   r.   	send_text      zWebSocketTestSession.send_textbytesc                 C  r   )Nr   rP   r   r   r   r-   r-   r.   
send_bytes   r   zWebSocketTestSession.send_bytesr   mode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)r5   r   r   r   r-   r-   r.   	send_json   s   zWebSocketTestSession.send_jsonrS   Nr{   intr|   
str | Nonec                 C  s   |  d||d d S )Nzwebsocket.disconnect)rP   r{   r|   r   )r5   r{   r|   r-   r-   r.   r`      r   zWebSocketTestSession.closec                 C  s   | j | jjS r4   )rW   r\   rt   r9   r5   r-   r-   r.   r9      s   zWebSocketTestSession.receivec                 C      |   }| | tt|d S )Nr   )r9   r^   r   rB   r   r-   r-   r.   receive_text      
z!WebSocketTestSession.receive_textc                 C  r   )Nr   )r9   r^   r   r   r   r-   r-   r.   receive_bytes   r   z"WebSocketTestSession.receive_bytesc                 C  s<   |   }| | |dkr|d }n|d d}t|S )Nr   r   r   )r9   r^   decoder   loads)r5   r   rf   r   r-   r-   r.   receive_json   s   


z!WebSocketTestSession.receive_json)r$   rK   r8   r   rL   rM   r&   r2   r&   r    )rh   r   r&   ri   )rl   rm   r&   r2   rf   r   r&   r2   )r   rB   r&   r2   )r   r   r&   r2   )r   )r   r   r   r   r&   r2   )rS   N)r{   r   r|   r   r&   r2   r&   r   )r&   rB   )r&   r   )r   r   r&   r   )r=   r>   r?   r6   rg   rj   rY   r^   r:   r   r   r   r`   r9   r   r   r   r-   r-   r-   r.   rI   f   s    










rI   c                   @  s&   e Zd Z		ddddZdddZdS )_TestClientTransportTr}   r$   rK   rL   rM   raise_server_exceptionsbool	root_pathrB   clienttuple[str, int]	app_staterD   r&   r2   c                C  s(   || _ || _|| _|| _|| _|| _d S r4   )r$   r   r   rL   r   r   )r5   r$   rL   r   r   r   r   r-   r-   r.   r6      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||ddd | j||
 || j||
g|| j di id}t| j|| j}t|ddjt||ddd | j||
 || j||
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y6 } z| jr,|W Y d }~nd }~ww | jrCsBJ d#nsNd$g t d%td   d< tj!d)i d&i}d urp|_" |_#|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   ?r   zwebsocket.http.response)rP   pathraw_pathr   schemequery_stringrR   r   serversubprotocolsstate
extensionsr   z1.1http.response.debug)rP   http_versionmethodr   r   r   r   r   rR   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 )	NrP   zhttp.disconnectr   r   zhttp.requestT)rP   r   r   )rP   r   )	is_setwaitread
isinstancerB   r   r   r:   StopIteration)r   
body_byteschunk)r   request_completeresponse_completer-   r.   r9   ,  s.   





z4_TestClientTransport.handle_request.<locals>.receiverf   r2   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 )NrP   zhttp.response.startz1Received multiple "http.response.start" messages.r~   r   c                 S  s    g | ]\}}|  |  fqS r-   )r   r   r-   r-   r.   r   N  s     zE_TestClientTransport.handle_request.<locals>.send.<locals>.<listcomp>rR   Tzhttp.response.bodyz<Received "http.response.body" without "http.response.start".z7Received "http.response.body" after response completed.r   r   r   FHEADr   r   r   infotemplatecontext)r_   r   r   writeseekset)rf   r   r   )r   
raw_kwargsr   r   response_startedr   r-   r.   r:   H  s*   
z1_TestClientTransport.handle_request.<locals>.sendz(TestClient did not receive any response.i  )r   rR   r   r   r   r   r-   )$urlr   netlocr   r   r   querysplitr   rR   r   multi_itemsr_   r   r   r   r   copyrI   r$   rL   rG   r   ioBytesIOr\   rn   EventBaseExceptionr   httpx
ByteStreamr   Responser   r   )r5   r   r   r   r   r   r   default_portr   port_stringportrR   rQ   r   r8   rH   r9   r:   rW   excresponser-   )r   r   r   r   r   r   r   r.   handle_request   s   



z#_TestClientTransport.handle_requestN)Tr}   )r$   rK   rL   rM   r   r   r   rB   r   r   r   rD   r&   r2   )r   r   r&   r   )r=   r>   r?   r6   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	ddddddde
jje
jje
jjdd%da fd;d<Zddde
jje
jje
jjdd=db fd>d?Zddde
jje
jje
jjdd=db fd@dAZddde
jje
jje
jjdd=db fdBdCZddddddde
jje
jje
jjdd%dc fdDdEZddddddde
jje
jje
jjdd%dc fdFdGZddddddde
jje
jje
jjdd%dc fdHdIZddde
jje
jje
jjdd=db fdJdKZ	ddde fdPdQZdfdSdTZdgdVdWZdhdXdYZdhdZd[Zdhd\d]Z  ZS )i
TestClientFzFuture[None]taskNzanyio.abc.BlockingPortal | NonerW   http://testserverTr}   asyncio
testclientiP  r$   r   base_urlrB   r   r   r   rC   Literal['asyncio', 'trio']rE   dict[str, Any] | Nonecookieshttpx._types.CookieTypes | NonerR   dict[str, str] | Nonefollow_redirectsr   r   r&   r2   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)rC   rE   )rL   r   r   r   r   z
user-agentr   )r   rR   	transportr  r  )rA   async_backendr/   r   r1   r0   r$   r   r   _portal_factory
setdefaultsuperr6   )r5   r$   r   r   r   rC   rE   r  rR   r  r   asgi_appr  	__class__r-   r.   r6   }  s2   

zTestClient.__init__/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-   )rW   rn   from_threadstart_blocking_portalr  )r5   rW   r-   r-   r.   r	    s   
"zTestClient._portal_factoryr   r   filesr   paramsrR   r  authr  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.UseClientDefault%bool | httpx._client.UseClientDefaultr  :httpx._types.TimeoutTypes | httpx._client.UseClientDefaultr   r   c                  sJ   |t jurtjdtdd | |}t j|||||||||	|
|||dS )NzYou should not use the 'timeout' argument with the TestClient. See https://github.com/Kludex/starlette/issues/1108 for more information.r!   r"   r  )r   USE_CLIENT_DEFAULTwarningswarnr   
_merge_urlr  r   )r5   r   r   r   r   r  r   r  rR   r  r  r  r  r   r  r-   r.   r     s,   

zTestClient.requestr  rR   r  r  r  r  r   c          	   
        t  j||||||||dS Nr$  )r  r_   	r5   r   r  rR   r  r  r  r  r   r  r-   r.   r_        zTestClient.getc          	   
     r%  r&  )r  optionsr'  r  r-   r.   r)    r(  zTestClient.optionsc          	   
     r%  r&  )r  headr'  r  r-   r.   r*    r(  zTestClient.headc                  $   t  j|||||||||	|
||dS Nr  )r  postr5   r   r   r   r  r   r  rR   r  r  r  r  r   r  r-   r.   r-       zTestClient.postc                  r+  r,  )r  putr.  r  r-   r.   r0  :  r/  zTestClient.putc                  r+  r,  )r  patchr.  r  r-   r.   r1  Y  r/  zTestClient.patchc          	   
     r%  r&  )r  deleter'  r  r-   r.   r2  x  r(  zTestClient.deleter   Sequence[str] | NonekwargsrI   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://testserverrR   
connectionupgradezsec-websocket-keyztestserver==zsec-websocket-version13r   z, GETzExpected WebSocket upgrade)	r   r_   r
  r   r  r   rG   rH   RuntimeError)r5   r   r   r4  rR   r   rH   r  r-   r.   websocket_connect  s    
zTestClient.websocket_connectr    c                   s   t  f}|tjjdi j _ |jdfdd}t	t
j}t	t
j}g ||R D ]}||j q2t| _t| _ j_ j |jd fdd}| _W d    S 1 smw   Y  S )	Nr&   r2   c                     s
   d  _ d S r4   )rW   r-   r   r-   r.   reset_portal  s   
z*TestClient.__enter__.<locals>.reset_portalc                     s     j d S r4   )r\   wait_shutdownr-   rW   r5   r-   r.   r<    s   z+TestClient.__enter__.<locals>.wait_shutdownr-   r&   r2   )rT   rU   rV   rn   r  r  r  rW   rZ   ro   rp   rq   r`   r   stream_sendstream_receivestart_task_soonlifespanr   r\   wait_startupra   rb   )r5   rc   r;  r:   r9   channelr<  r-   r=  r.   rg     s,   
 



zTestClient.__enter__rh   c                 G  s   | j   d S r4   )rb   r`   rk   r-   r-   r.   rj     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 )NrB  )rP   r   )r   r$   r@  r9   r?  r:   )r5   r8   r-   r-   r.   rB    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 )
NrP   zlifespan.startupr&   r   c                    (    j  I d H } | d u r j  | S r4   r?  r9   r   r[   rf   r   r-   r.   r9     
   
z(TestClient.wait_startup.<locals>.receive)zlifespan.startup.completelifespan.startup.failedrI  r&   r   r@  r:   r5   r9   rf   r-   r   r.   rC    s   zTestClient.wait_startupc                   sb   d	 fdd} j ddiI d H  | I d H }|d dv s!J |d dkr/| I d H  d S d S )
Nr&   r   c                    rE  r4   rF  rG  r   r-   r.   r9     rH  z)TestClient.wait_shutdown.<locals>.receiverP   zlifespan.shutdown)zlifespan.shutdown.completelifespan.shutdown.failedrM  rJ  rK  rL  r-   r   r.   r<    s   zTestClient.wait_shutdown)	r   Tr}   r   NNNTr   )r$   r   r   rB   r   r   r   rB   rC   r  rE   r  r  r  rR   r  r  r   r   r   r&   r2   )r&   r  )r   rB   r   r  r   r  r   r  r  r  r   r   r  r  rR   r  r  r  r  r  r  r  r  r  r   r  r&   r   )r   r  r  r  rR   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  rR   r  r  r  r  r  r  r  r  r  r   r  r&   r   r4   )r   rB   r   r3  r4  r   r&   rI   r   )rh   r   r&   r2   r>  )r=   r>   r?   __test__rF   rW   r6   rT   contextmanagerr	  r   _clientr   r   r_   r)  r*  r-  r0  r1  r2  r:  rg   rj   rB  rC  r<  __classcell__r-   r-   r  r.   r   x  s   
 (-###



r   )r$   r%   r&   r'   )N
__future__r   rT   r)   r   r   rp   sysr!  collections.abcr   r   r   r   r   r   r	   concurrent.futuresr
   r   typesr   typingr   r   r   r   r   r   urllib.parser   r   rn   	anyio.abcanyio.from_threadanyio.streams.stapledr   starlette._utilsr   starlette.exceptionsr   starlette.typesr   r   r   r   r   starlette.websocketsr   version_infor    typing_extensionshttpx2r   ModuleNotFoundErrorr9  r"  abcBlockingPortalrM   ASGIInstancer1   rK   rB   r   _RequestDatar/   r0   rA   	ExceptionrG   r   rJ   rI   BaseTransportr   Clientr   r-   r-   r-   r.   <module>   s|    $ 





i *