
    {h                         d Z ddl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  G d d	e      Z G d
 de      Zy)a=  
A modified version of httpx.ASGITransport that supports streaming responses.

This transport runs the ASGI app as a separate anyio task, allowing it to
handle streaming responses like SSE where the app doesn't terminate until
the connection is closed.

This is only intended for writing tests for the SSE transport.
    N)Anycast)RequestResponse)AsyncBaseTransport)AsyncByteStream)ASGIAppReceiveScopeSendc                   z    e Zd ZdZ	 	 	 ddedej                  j                  dede	de
e	ef   ddfd	Zd
edefdZy)StreamingASGITransporta?  
    A custom AsyncTransport that handles sending requests directly to an ASGI app
    and supports streaming responses like SSE.

    Unlike the standard ASGITransport, this transport runs the ASGI app in a
    separate anyio task, allowing it to handle responses from apps that don't
    terminate immediately (like SSE endpoints).

    Arguments:

    * `app` - The ASGI application.
    * `raise_app_exceptions` - Boolean indicating if exceptions in the application
       should be raised. Default to `True`. Can be set to `False` for use cases
       such as testing the content of a client 500 response.
    * `root_path` - The root path on which the ASGI application should be mounted.
    * `client` - A two-tuple indicating the client IP and port of incoming requests.
    * `response_timeout` - Timeout in seconds to wait for the initial response.
       Default is 10 seconds.

    TODO: https://github.com/encode/httpx/pull/3059 is adding something similar to
    upstream httpx. When that merges, we should delete this & switch back to the
    upstream implementation.
    app
task_groupraise_app_exceptions	root_pathclientreturnNc                 J    || _         || _        || _        || _        || _        y N)r   r   r   r   r   )selfr   r   r   r   r   s         d/var/www/html/hubwallet-dev/venv/lib/python3.12/site-packages/mcp/server/streaming_asgi_transport.py__init__zStreamingASGITransport.__init__0   s(     $8!"$    requestc                    	
K   t        j                  t              sJ dddidj                  j                  j
                  D cg c]  \  }}|j                         |f c}}j                  j                  j                  j                  j                  j                  j                  d      d   j                  j                  j                  j                  j                  j                  f j                   j                   dj                  j#                         dd	d dt%        j&                         t%        j&                         
t%        j(                  t*        t,        t.        f      d
      \  t%        j(                  t0           d
      \  	}dt*        t,        t.        f   ffddt*        t,        t.        f   dd ffdd fd}d	
fd} j2                  j5                  |        j2                  j5                  |       
j7                          d {    t9        t;        |            S c c}}w 7 !w)Nhttpversionz3.0z1.1   ?r   )typeasgihttp_versionmethodheadersschemepathraw_pathquery_stringserverr   r   Fi  d   r   c                     K   rj                          d {    ddiS 	 j                          d {   } d| ddS 7 '7 # t        $ r dddddcY S w xY ww)Nr    zhttp.disconnectTzhttp.requestr   Fr    body	more_body)wait	__anext__StopAsyncIteration)r-   request_body_chunksrequest_completeresponse_completes    r   receivez<StreamingASGITransport.handle_async_request.<locals>.received   s~       ',,... 122Q0::<< +DtLL / =% Q#'  .%PPQsA   AAAA AA AA AAAAmessagec                 D   K   j                  |        d {    y 7 wr   )send)r6   asgi_send_channelresponse_headersresponse_startedstatus_codes    r   r8   z9StreamingASGITransport.handle_async_request.<locals>.sendr   s      $((111s     c                    K   	 j                  t        t              t        t              t        t                     d {     j                          d {    y 7 # t
        $ rN j                  r s j                  ddg d       d {  7    j                  dddd       d {  7   Y qw xY w7 a#  j                          d {  7   w xY ww)Nhttp.response.starti  )r    statusr$   http.response.bodyr   Fr,   )	r   r   r   r
   r   	Exceptionr   r8   aclose)r9   r5   r;   scoper   r8   s   r   run_appz<StreamingASGITransport.handle_async_request.<locals>.run_appx   s     1hhtE5143I4PTVZK[\\\ (..000 ] n,,'+00:O[^km1nooo',,6JTWfk-lmmmn 1'..000s}   CA A% A#A% 
CB?C#A% %0B<BB<3B64B<9C ;B<<C ?CCCCCc                    K   	 4 d {    2 3 d {   } | d   dk(  r.	rJ | d   
| j                  dg       d	j                          ?| d   dk(  sH| j                  dd      }| j                  d	d
      }|r(j                  dk7  rj                  |       d {    |rj                          j	                          d {     d d d       d {    j                          j                          j	                          d {    y 7 7 
7 7 V6 U7 I# 1 d {  7  sw Y   YxY w7 (# j                          j                          j	                          d {  7   w xY ww)Nr    r>   r?   r$   Tr@   r-   r   r.   FHEAD)getsetr#   r8   rB   )r6   r-   r.   asgi_receive_channelcontent_send_channelinitial_response_readyr   r4   r:   r;   r<   s      r   process_messageszEStreamingASGITransport.handle_async_request.<locals>.process_messages   s~    4/ & &)= & &g"6?.CC'77#7*1(*;K/6{{9b/I,/3, 3668$V_0DD#*;;vs#;D(/K(GI#&(@&:&?&?&E E E#, 1 5 5 7&:&A&A&C C C %+& &0 '**,!%%'*113335&& !F !D' *>& & & &4 4 '**,!%%'*11333s   F E DE D+D'D D'?D+A	D+#D#$D++#D+D%D+E D) E $3F E F E  D'#D+%D+'D+)E +D=1D42D=9E  F 4E=6E97E==F )r$   stream)r   N)
isinstancerM   r   r#   r$   rawlowerurlr%   r&   r'   splitqueryhostportr   r   	__aiter__anyioEventcreate_memory_object_streamdictstrr   bytesr   
start_soonr/   r   StreamingASGIResponseStream)r   r   kvcontent_receive_channelrD   rL   rI   r9   rJ   rK   r5   r2   r3   r4   r:   r;   rC   r8   r<   s   ``     @@@@@@@@@@@@@r   handle_async_requestz+StreamingASGITransport.handle_async_request>   s     '../::: &!nn5<__5H5HI6AqAIkk((KK$$,,2248;#KK--{{'')9)9:kk
  &nn668   !KKM!& 382S2STXY\^aYaTb2cdg2h//8=8Y8YZ_8`ad8e55	MtCH~ 	M	2S#X 	24 	2 	2	1 	1 	4 	4B 	""7+""#34 %))+++ $./FG
 	
M JF 	,s   AI3I+3GI3I1"I3)T )z	127.0.0.1{   )__name__
__module____qualname____doc__r	   rW   abc	TaskGroupboolr[   tupleintr   r   r   rb    r   r   r   r      s}    8 &*"4%% II''% #	%
 % c3h% 
%v
v
 
v
r   r   c                       e Zd ZdZdej
                  j                  j                  e   ddfdZ	de
j                  e   fdZy)r^   z
    A modified ASGIResponseStream that supports streaming responses.

    This class extends the standard ASGIResponseStream to handle cases where
    the response body continues to be generated after the initial response
    is returned.
    receive_channelr   Nc                     || _         y r   )rp   )r   rp   s     r   r   z$StreamingASGIResponseStream.__init__   s      /r   c                   K   	 | j                   2 3 d {   }| 7 
6 	 | j                   j                          d {  7   y # | j                   j                          d {  7   w xY wwr   )rp   rB   )r   chunks     r   rV   z%StreamingASGIResponseStream.__aiter__   s`     	0#33  e3 &&--///$&&--///sM   A/A !!A !A A/ AA/A,%A(&A,,A/)re   rf   rg   rh   rW   streamsmemoryMemoryObjectReceiveStreamr\   r   typingAsyncIteratorrV   rn   r   r   r^   r^      sJ    /--GGN/ 
/0!5!5e!< 0r   r^   )rh   rw   r   r   rW   	anyio.abcanyio.streams.memoryhttpx._modelsr   r   httpx._transports.baser   httpx._typesr   starlette.typesr	   r
   r   r   r   r^   rn   r   r   <module>r      sF         + 5 ( 9 9]
/ ]
@0/ 0r   