
    {h@L                     >   d Z ddl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 ddlZddl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mZ ddlmZmZ ddlmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%  ejL                  e'      Z(ee)z  Z*ee*   Z+ee   Z,eg e-dz  f   Z.dZ/dZ0dZ1dZ2dZ3dZ4dZ5 G d de)      Z6 G d de6      Z7e	 G d d             Z8 G d d      Z9eddddedfde-d e:e-e-f   dz  d!e;ez  d"e;ez  d#e<d$ed%ejz                  dz  d&ee>eee)z     ee   e.f   df   fd'       Z?y)(z
StreamableHTTP Client Transport Module

This module implements the StreamableHTTP transport for MCP clients,
providing support for HTTP POST requests with optional SSE streaming responses
and session management.
    N)AsyncGenerator	AwaitableCallable)asynccontextmanager)	dataclass)	timedelta)	TaskGroup)MemoryObjectReceiveStreamMemoryObjectSendStream)EventSourceServerSentEventaconnect_sse)McpHttpClientFactorycreate_mcp_http_client)ClientMessageMetadataSessionMessage)	ErrorDataInitializeResultJSONRPCErrorJSONRPCMessageJSONRPCNotificationJSONRPCRequestJSONRPCResponse	RequestIdzmcp-session-idzmcp-protocol-versionzlast-event-idzcontent-typeAcceptzapplication/jsonztext/event-streamc                       e Zd ZdZy)StreamableHTTPErrorz3Base exception for StreamableHTTP transport errors.N__name__
__module____qualname____doc__     [/var/www/html/hubwallet-dev/venv/lib/python3.12/site-packages/mcp/client/streamable_http.pyr   r   5   s    =r$   r   c                       e Zd ZdZy)ResumptionErrorz*Raised when resumption request is invalid.Nr   r#   r$   r%   r'   r'   9   s    4r$   r'   c                       e Zd ZU dZej
                  ed<   eeef   ed<   edz  ed<   e	ed<   e
dz  ed<   eed<   eed	<   y)
RequestContextz Context for a request operation.clientheadersN
session_idsession_messagemetadataread_stream_writersse_read_timeout)r   r    r!   r"   httpxAsyncClient__annotations__dictstrr   r   StreamWriterfloatr#   r$   r%   r)   r)   =   sF    *#s(^d
###d**$$r$   r)   c                   |   e Zd ZdZ	 	 	 	 d*dedeeef   dz  deez  deez  dej                  dz  ddfd	Z
d
eeef   deeef   fdZdedefdZdedefdZdej                   ddfdZdeddfdZ	 	 	 d+dedededz  deeged   f   dz  dedefdZdej2                  deddfdZdeddfdZdeddfdZ	 d,dej                   dededdfdZ	 d,dej                   dededdfdZdededdfd Z ded!eddfd"Z!dej2                  d#e"ded$e#e$   d%eg df   d&e%ddfd'Z&dej2                  ddfd(Z'dedz  fd)Z(y)-StreamableHTTPTransportz/StreamableHTTP client transport implementation.Nurlr+   timeoutr0   authreturnc                 N   || _         |xs i | _        t        |t              r|j	                         n|| _        t        |t              r|j	                         n|| _        || _        d| _        d| _	        t        t         dt         t        t        i| j                  | _        y)aS  Initialize the StreamableHTTP transport.

        Args:
            url: The endpoint URL.
            headers: Optional headers to include in requests.
            timeout: HTTP timeout for regular operations.
            sse_read_timeout: Timeout for SSE read operations.
            auth: Optional HTTPX authentication handler.
        Nz, )r:   r+   
isinstancer   total_secondsr;   r0   r<   r,   protocol_versionACCEPTJSONSSECONTENT_TYPErequest_headers)selfr:   r+   r;   r0   r<   s         r%   __init__z StreamableHTTPTransport.__init__M   s    " }"2<Wi2Pw,,.V]0:;KY0W**,]m 	 	 $tfBse$$ 
 ll 
r$   base_headersc                     |j                         }| j                  r| j                  |t        <   | j                  r| j                  |t        <   |S )zAUpdate headers with session ID and protocol version if available.)copyr,   MCP_SESSION_IDrA   MCP_PROTOCOL_VERSION)rG   rI   r+   s      r%   _prepare_request_headersz0StreamableHTTPTransport._prepare_request_headersm   sD    ##%??&*ooGN#  ,0,A,AG()r$   messagec                 l    t        |j                  t              xr |j                  j                  dk(  S )z2Check if the message is an initialization request.
initialize)r?   rootr   methodrG   rO   s     r%   _is_initialization_requestz2StreamableHTTPTransport._is_initialization_requestv   s(    ',,7_GLL<O<OS_<__r$   c                 l    t        |j                  t              xr |j                  j                  dk(  S )z4Check if the message is an initialized notification.znotifications/initialized)r?   rR   r   rS   rT   s     r%   _is_initialized_notificationz4StreamableHTTPTransport._is_initialized_notificationz   s)    ',,(;<sATATXsAssr$   responsec                     |j                   j                  t              }|r*|| _        t        j                  d| j                          yy)z3Extract and store session ID from response headers.zReceived session ID: N)r+   getrL   r,   loggerinfo)rG   rX   new_session_ids      r%   '_maybe_extract_session_id_from_responsez?StreamableHTTPTransport._maybe_extract_session_id_from_response~   sB    
 "))--n=,DOKK//@AB r$   c                    t        |j                  t              r~|j                  j                  rg	 t	        j
                  |j                  j                        }t        |j                        | _        t        j                  d| j                          yyy# t        $ rN}t        j                  d|        t        j                  d|j                  j                          Y d}~yd}~ww xY w)z>Extract protocol version from initialization response message.zNegotiated protocol version: z=Failed to parse initialization response as InitializeResult: zRaw result: N)r?   rR   r   resultr   model_validater5   protocolVersionrA   r[   r\   	Exceptionwarning)rG   rO   init_resultexcs       r%   ,_maybe_extract_protocol_version_from_messagezDStreamableHTTPTransport._maybe_extract_protocol_version_from_message   s    
 gllO49L9LE.==gll>Q>QR(+K,G,G(H%;D<Q<Q;RST :M4  E!^_b^cdegll.A.A-BCDDEs   A%B 	C1#AC,,C1sser/   original_request_idresumption_callbackis_initializationc                   K   |j                   dk(  r	 t        j                  |j                        }t        j                  d|        |r| j                  |       |2t        |j                  t        t        z        r||j                  _        t        |      }|j                  |       d{    |j                  r|r ||j                         d{    t        |j                  t        t        z        S t        j!                  d|j                           y7 p7 J# t        $ r9}t        j                  d       |j                  |       d{  7   Y d}~yd}~ww xY ww)z@Handle an SSE event, returning True if the response is complete.rO   zSSE message: NzError parsing SSE messageFzUnknown SSE event: )eventr   model_validate_jsondatar[   debugrg   r?   rR   r   r   idr   sendrc   	exceptionrd   )	rG   rh   r/   ri   rj   rk   rO   r-   rf   s	            r%   _handle_sse_eventz)StreamableHTTPTransport._handle_sse_event   s-     99	!(<<SXXF}WI67 %EEgN '2z',,P_bnPn7o&9GLLO"0"9(--o>>> 661-cff555 "',,,0NOO NN0<=! ? 6    !<=(--c222s_   E*BD% 0D!1'D% D#$D% =$E*!D% #D% %	E'.)E"EE"E*"E''E*r*   c           
      r  K   	 | j                   sy| j                  | j                        }t        |d| j                  |t        j                  | j                  | j                              4 d{   }|j                  j                          t        j                  d       |j                         2 3 d{   }| j                  ||       d{    $7 g7 !7 	6 ddd      d{  7   y# 1 d{  7  sw Y   yxY w# t        $ r"}t        j                  d|        Y d}~yd}~ww xY ww)z0Handle GET stream for server-initiated messages.NGETreadr+   r;   zGET SSE connection establishedzGET stream error (non-fatal): )r,   rN   rF   r   r:   r1   Timeoutr;   r0   rX   raise_for_statusr[   rp   	aiter_ssert   rc   )rG   r*   r/   r+   event_sourcerh   rf   s          r%   handle_get_streamz)StreamableHTTPTransport.handle_get_stream   s    	A??33D4H4HIG#dll9N9NO J J %%668=>!-!7!7!9 J J#006HIIIJJI ":J J J J J  	ALL9#?@@	As   D7D	 D7A"D	 3C4D	 7A C47C!;C<C!?C4CC4D	 C!C4!C4"D	 -C0.D	 3D74D:C=;DD	 D7D	 		D4D/*D7/D44D7ctxc           
        K   | j                  |j                        }|j                  r4|j                  j                  r|j                  j                  |t        <   nt        d      d}t        |j                  j                  j                  t              r*|j                  j                  j                  j                  }t        |j                  d| j                  |t        j                   | j"                  | j$                              4 d{   }|j&                  j)                          t*        j-                  d       |j/                         2 3 d{   }| j1                  ||j2                  ||j                  r|j                  j4                  nd       d{   }|sT ddd      d{    y7 7 c7 6 7 # 1 d{  7  sw Y   yxY ww)z/Handle a resumption request using GET with SSE.z.Resumption request requires a resumption tokenNrv   rw   ry   z)Resumption GET SSE connection established)rN   r+   r.   resumption_tokenLAST_EVENT_IDr'   r?   r-   rO   rR   r   rq   r   r*   r:   r1   rz   r;   r0   rX   r{   r[   rp   r|   rt   r/   on_resumption_token_update)rG   r   r+   ri   r}   rh   is_completes          r%   _handle_resumption_requestz2StreamableHTTPTransport._handle_resumption_request   s    //<<<CLL99%(\\%B%BGM"!"RSS #c))1166G"%"5"5"="="B"B"E"EJJHHMM$,,T5J5JK
 	 	 !!224LLDE)335  c$($:$:**'?B||CLL;;QU	%  %	 	 	 6	 	 	 	s   DGF>GA GGG G AG$G%G,G-G8G9G GGGGGGGGc           	        K   | j                  |j                        }|j                  j                  }| j	                  |      }|j
                  j                  d| j                  |j                  ddd      |      4 d{   }|j                  dk(  r't        j                  d       	 ddd      d{    y|j                  d	k(  rdt        |j                  t              r8| j                  |j                   |j                  j"                         d{    	 ddd      d{    y|j%                          |r| j'                  |       |j                  j)                  t*        d
      j-                         }|j/                  t0              r&| j3                  ||j                   |       d{    nU|j/                  t4              r| j7                  |||       d{    n$| j9                  ||j                          d{    ddd      d{    y7 7 n7 7 7 w7 H7 %7 # 1 d{  7  sw Y   yxY ww)z/Handle a POST request with response processing.POSTTjson)by_aliasmodeexclude_none)r   r+   N   zReceived 202 Acceptedi   )rN   r+   r-   rO   rU   r*   streamr:   
model_dumpstatus_coder[   rp   r?   rR   r   _send_session_terminated_errorr/   rq   r{   r^   rZ   rE   lower
startswithrC   _handle_json_responserD   _handle_sse_response_handle_unexpected_content_type)rG   r   r+   rO   rk   rX   content_types          r%   _handle_post_requestz,StreamableHTTPTransport._handle_post_request   s    //<%%-- ;;GD::$$HH##TT#R	 % 
  	  	
 ##s*45 	  	  	 ##s*gllN;==..   ! 	  	  	$ %%' <<XF#++//bAGGIL&&t,003;Q;QSdeee((-//#?PQQQ:: **  ; 	  	  	  	 	2 fQ; 	  	  	  	s   BIH$I&H8.I9H':I?AH8H*H8!I,H--I2BH88H090H8)H2*$H8H4H8IH6I'I*H8-I0H82H84H86I8I
>I?I
Ic                 h  K   	 |j                          d{   }t        j                  |      }|r| j                  |       t	        |      }|j                  |       d{    y7 Q7 # t        $ r9}t        j                  d       |j                  |       d{  7   Y d}~yd}~ww xY ww)z%Handle JSON response from the server.NzError parsing JSON response)	areadr   rn   rg   r   rr   rc   r[   rs   )rG   rX   r/   rk   contentrO   r-   rf   s           r%   r   z-StreamableHTTPTransport._handle_json_response%  s     	/$NN,,G$88AG !AA'J,W5O$))/::: - ; 	/:;$))#...	/s]   B2A- A)AA- #A+$A- (B2)A- +A- -	B/6)B*B" B*%B2*B//B2c                   K   	 t        |      }|j                         2 3 d{   }| j                  ||j                  |j                  r|j                  j
                  nd|       d{   }|sU y7 R7 6 y# t        $ rC}t        j                  d       |j                  j                  |       d{  7   Y d}~yd}~ww xY ww)z$Handle SSE response from the server.N)rj   rk   zError reading SSE stream:)
r   r|   rt   r/   r.   r   rc   r[   rs   rr   )rG   rX   r   rk   r}   rh   r   es           r%   r   z,StreamableHTTPTransport._handle_sse_response:  s     	1&x0L)335 
 
c$($:$:**TWT`T`)P)Pfj&7	 %; %  
 6  	189((--a000	1sy   CA< A:A6A:AA< ,A8-A< 4A< 5C6A:8A< :A< ;C<	C3C8B;9C>CCCr   c                    K   d| }t         j                  |       |j                  t        |             d{    y7 w)z+Handle unexpected content type in response.zUnexpected content type: N)r[   errorrr   
ValueError)rG   r   r/   	error_msgs       r%   r   z7StreamableHTTPTransport._handle_unexpected_content_typeR  s9      0~>	Y %%j&;<<<s   8AA A
request_idc                    K   t        d|t        dd            }t        t        |            }|j	                  |       d{    y7 w)z)Send a session terminated error response.z2.0iX  zSession terminated)coderO   )jsonrpcrq   r   N)r   r   r   r   rr   )rG   r/   r   jsonrpc_errorr-   s        r%   r   z6StreamableHTTPTransport._send_session_terminated_error\  sH      %0DE

 ))FG %%o666s   AAA
Awrite_stream_readerwrite_streamstart_get_streamtgc                    K   	 |4 d{    |2 3 d{   }|j                   }t        |j                  t              r|j                  nd}	t	        |	xr |	j
                        t        j                  d|         j                  |      r |        t        | j                   j                  ||	| j                         fd}
t        |j                  t              r|j                  |
        |
        d{    7 7 7 	6 ddd      d{  7   n# 1 d{  7  sw Y   nxY wn$# t         $ r t        j#                  d       Y nw xY w|j%                          d{  7   |j%                          d{  7   y# |j%                          d{  7   |j%                          d{  7   w xY ww)z&Handle writing requests to the server.NzSending client message: )r*   r+   r,   r-   r.   r/   r0   c                     K   rj                          d {    y j                          d {    y 7 7 wN)r   r   )r   is_resumptionrG   s   r%   handle_request_asynczAStreamableHTTPTransport.post_writer.<locals>.handle_request_async  s<     ("&"A"A#"FFF"&";";C"@@@ G@s   >:><>>zError in post_writer)rO   r?   r.   r   boolr   r[   rp   rW   r)   rF   r,   r0   rR   r   
start_soonrc   rs   aclose)rG   r*   r   r/   r   r   r   r-   rO   r.   r   r   r   s   `          @@r%   post_writerz#StreamableHTTPTransport.post_writerj  s    -	(* &5 &5-@ %5 %5/-55G &o&>&>@UV (00!  %))Oh6O6O$PMLL#;G9!EF 88A(*(% $ 4 4#'??(7!)+=)-)>)>CA "',,?&:;2444M&5%5J 5K .A&5 &5 &5 &5 &5P  	534	5 %++---%%''' %++---%%'''s   G
D< DD< D&DDDC+D&DD&D< DD&D&D< D" D< &D8,D/-D84D< ;F <EF EF  G
3E64G
FG
G'F*(G GGG
c                   K   | j                   sy	 | j                  | j                        }|j                  | j                  |       d{   }|j
                  dk(  rt        j                  d       y|j
                  dvr#t        j                  d|j
                          yy7 [# t        $ r"}t        j                  d|        Y d}~yd}~ww xY ww)z2Terminate the session by sending a DELETE request.N)r+   i  z)Server does not allow session termination)      zSession termination failed: )
r,   rN   rF   deleter:   r   r[   rp   rd   rc   )rG   r*   r+   rX   rf   s        r%   terminate_sessionz)StreamableHTTPTransport.terminate_session  s     		A33D4H4HIG#]]488W]EEH##s*HI%%Z7!=h>R>R=STU 8	 F  	ANN9#?@@	AsL   C;B* B((B* 5C60B* &C(B* *	C3CCCCc                     | j                   S )zGet the current session ID.)r,   )rG   s    r%   get_session_idz&StreamableHTTPTransport.get_session_id  s    r$   )N   ,  N)NNF)F))r   r    r!   r"   r5   r4   r7   r   r1   AuthrH   rN   r   r   rU   rW   Responser^   rg   r   r6   r   r   r   rt   r2   r~   r)   r   r   r   r   r   r   StreamReaderr   r   r	   r   r   r   r#   r$   r%   r9   r9   J   s   9
 *.%'.4"&

 c3h$&
 "	

  )+
 jj4
 

@T#s(^ SRUX `. `T `tN tt tC..C 
CEE 
E& 15GK"''' )' '-	'
 &seYt_&<=D'  ' 
'RA!!A )A 
	A8N t B&n & &X #(	/../ )/  	/
 
/2 #(	1..1 1  	1
 
10== )= 
	=7(7 7 
	77(!!7( *7( )	7(
 -^<7( #2t8,7( 7( 
7(rAe.?.? AD A d
 r$   r9   r   r   Tr:   r+   r;   r0   terminate_on_closehttpx_client_factoryr<   r=   c                  K   t        | ||||      t        j                  t        t        z     d      \  }t        j                  t           d      \  }}	t        j
                         4 d{   	 t        j                  d|          |j                  t        j                  j                  j                        j                        4 d{   dfd}
j                  j                  |	||
       	 ||j                   f j"                  r|rj%                         d{    j&                  j)                          ddd      d{    j+                          d{    |j+                          d{    ddd      d{    y7 >7 7 t# j"                  r|rj%                         d{  7   j&                  j)                          w xY w7 # 1 d{  7  sw Y   xY w7 7 |# j+                          d{  7   |j+                          d{  7   w xY w7 # 1 d{  7  sw Y   yxY ww)a  
    Client transport for StreamableHTTP.

    `sse_read_timeout` determines how long (in seconds) the client will wait for a new
    event before disconnecting. All other HTTP operations are controlled by `timeout`.

    Yields:
        Tuple containing:
            - read_stream: Stream for reading messages from the server
            - write_stream: Stream for sending messages to the server
            - get_session_id_callback: Function to retrieve the current session ID
    r   Nz'Connecting to StreamableHTTP endpoint: rw   )r+   r;   r<   c                  @    j                  j                          y r   )r   r~   )r*   r/   r   	transports   r%   r   z/streamablehttp_client.<locals>.start_get_stream  s    MM)"="=vGYZr$   )r=   N)r9   anyiocreate_memory_object_streamr   rc   create_task_groupr[   rp   rF   r1   rz   r;   r0   r<   r   r   r   r,   r   cancel_scopecancelr   )r:   r+   r;   r0   r   r   r<   read_streamr   r   r   r*   r/   r   r   s              @@@@r%   streamablehttp_clientr     s0    : (Wg?OQUVI&+&G&GYbHb&cde&f#(-(I(I.(YZ[(\%L%&&( #( #(B"	(LLB3%HI+!11i&7&7i>X>XY^^ - - [ [ ))'& $	-#$!00  !++0B'99&AAAOO**,9- -< %++---%%'''G#( #( #(-6 B !++0B'99&AAAOO**,9- - - -< .' %++---%%'''G#( #( #( #(s  A-I(3F14I(7I9A$HF4H!+HF8"HF6H H+G?,H0IHIHI I(+I,I(4H6H8#G<G G<<H?HH	H
H	HIII.H1
/II

III(I%II%!I()@r"   loggingcollections.abcr   r   r   
contextlibr   dataclassesr   datetimer   r   r1   	anyio.abcr	   anyio.streams.memoryr
   r   	httpx_sser   r   r   mcp.shared._httpx_utilsr   r   mcp.shared.messager   r   	mcp.typesr   r   r   r   r   r   r   r   	getLoggerr   r[   rc   SessionMessageOrErrorr6   r   r5   GetSessionIdCallbackrL   rM   r   rE   rB   rC   rD   r   r'   r)   r9   r4   r7   r   r   tupler   r#   r$   r%   <module>r      s    ? ? * !     R @ @ P D	 	 	 
		8	$ '2 %&;<(8C$J/ !- 	 >) >5) 5 	 	 	k k\  &*!#*0#1G"D(	D(#s(^d"D( YD( i'	D(
 D( /D( **t
D( 	!.9"<=~.	
 	
D( D(r$   