
    K.hM                        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j&        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j=        dz  d&ee>eee)z           ee         e.f         df         fd'            Z?dS )(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dS )StreamableHTTPErrorz3Base exception for StreamableHTTP transport errors.N__name__
__module____qualname____doc__     l/Users/user/workspace/sujinbaek/cqa-test-app/venv/lib/python3.11/site-packages/mcp/client/streamable_http.pyr   r   5   s        ====r$   r   c                       e Zd ZdZdS )ResumptionErrorz*Raised when resumption request is invalid.Nr   r#   r$   r%   r'   r'   9   s        444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	<   dS )
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)   =   s         **#s(^d
#####d****$$$$r$   r)   c                   b   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j        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j        d&e"ded'e#e$         d(eg df         d)e%d
dfd*Z&dej        d
dfd+Z'd
edz  fd,Z(dS )0StreamableHTTPTransportz/StreamableHTTP client transport implementation.N   ,  urlr+   timeoutr0   authreturnc                 p   || _         |pi | _        t          |t                    r|                                n|| _        t          |t                    r|                                n|| _        || _        d| _        d| _	        t          t           dt           t          t          i| j        | _        dS )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<Wi2P2P]w,,...V]0:;KY0W0Wm**,,,]m 	 	 $t$$s$$$ 
 l 
r$   base_headersc                     |                                 }| j        r| j        |t          <   | j        r| j        |t          <   |S )zAUpdate headers with session ID and protocol version if available.)copyr,   MCP_SESSION_IDrC   MCP_PROTOCOL_VERSION)rI   rK   r+   s      r%   _prepare_request_headersz0StreamableHTTPTransport._prepare_request_headersm   sH    ##%%? 	6&*oGN#  	B,0,AG()r$   messagec                 V    t          |j        t                    o|j        j        dk    S )z2Check if the message is an initialization request.
initialize)rA   rootr   methodrI   rQ   s     r%   _is_initialization_requestz2StreamableHTTPTransport._is_initialization_requestv   s$    ',77_GL<OS_<__r$   c                 V    t          |j        t                    o|j        j        dk    S )z4Check if the message is an initialized notification.znotifications/initialized)rA   rT   r   rU   rV   s     r%   _is_initialized_notificationz4StreamableHTTPTransport._is_initialized_notificationz   s%    ',(;<<sATXsAssr$   responsec                     |j                             t                    }|r+|| _        t                              d| j                    dS dS )z3Extract and store session ID from response headers.zReceived session ID: N)r+   getrN   r,   loggerinfo)rI   rZ   new_session_ids      r%   '_maybe_extract_session_id_from_responsez?StreamableHTTPTransport._maybe_extract_session_id_from_response~   sY    
 ")--n== 	C,DOKKAAABBBBB	C 	Cr$   c                    t          |j        t                    r|j        j        r	 t	          j        |j        j                  }t          |j                  | _        t          
                    d| j                    dS # t          $ rO}t                              d|            t                              d|j        j                    Y d}~dS d}~ww xY wdS dS )z>Extract protocol version from initialization response message.zNegotiated protocol version: z=Failed to parse initialization response as InitializeResult: zRaw result: N)rA   rT   r   resultr   model_validater5   protocolVersionrC   r]   r^   	Exceptionwarning)rI   rQ   init_resultexcs       r%   ,_maybe_extract_protocol_version_from_messagezDStreamableHTTPTransport._maybe_extract_protocol_version_from_message   s   
 glO44 	E9L 	EE.=gl>QRR(+K,G(H(H%SD<QSSTTTTT E E Ed_bddeeeCgl.ACCDDDDDDDDDE	E 	E 	E 	Es   AB 
CACCFsser/   original_request_idresumption_callbackis_initializationc                   K   |j         dk    r6	 t          j        |j                  }t                              d|            |r|                     |           |.t          |j        t          t          z            r||j        _        t          |          }|                    |           d{V  |j        r|r ||j                   d{V  t          |j        t          t          z            S # t          $ r@}t                              d           |                    |           d{V  Y d}~dS d}~ww xY wt                              d|j                     dS )z@Handle an SSE event, returning True if the response is complete.rQ   zSSE message: NzError parsing SSE messageFzUnknown SSE event: )eventr   model_validate_jsondatar]   debugri   rA   rT   r   r   idr   sendre   	exceptionrf   )	rI   rj   r/   rk   rl   rm   rQ   r-   rh   s	            r%   _handle_sse_eventz)StreamableHTTPTransport._handle_sse_event   s      9	!!(<SXFF6W66777 % OEEgNNN '2z',P_bnPn7o7o2&9GLO"0"9"9(--o>>>>>>>>> 6 61 6--cf555555555 "',,0NOOO     !<===(--c222222222uuuuu
 NN<<<===5s   C'C8 8
E5D==Er*   c           
      \  K   	 | j         sdS |                     | j                  }t          |d| j        |t          j        | j        | j                            4 d{V 	 }|j	        
                                 t                              d           |                                2 3 d{V }|                     ||           d{V  $6 	 ddd          d{V  dS # 1 d{V swxY w Y   dS # t          $ r(}t                              d|            Y d}~dS d}~ww xY w)z0Handle GET stream for server-initiated messages.NGETreadr+   r=   zGET SSE connection establishedzGET stream error (non-fatal): )r,   rP   rH   r   r<   r1   Timeoutr=   r0   rZ   raise_for_statusr]   rr   	aiter_sserv   re   )rI   r*   r/   r+   event_sourcerj   rh   s          r%   handle_get_streamz)StreamableHTTPTransport.handle_get_stream   s=     	A? 33D4HIIG#dl9NOOO   J J J J J J J J %66888=>>>!-!7!7!9!9 J J J J J J J#006HIIIIIIIIII ":!9J J J J J J J J J J J J J J J J J J J J J J J J J J J J J J  	A 	A 	ALL?#??@@@@@@@@@	AsN   C9 AC9 %AC&-C3C&C9 &
C00C9 3C04C9 9
D+D&&D+ctxc           
      H  K   |                      |j                  }|j        r!|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{V 	 }|j                                         t*                              d           |                                2 3 d{V }|                     ||j        ||j        r|j        j        nd           d{V }|r!|j                                         d{V   na6 	 ddd          d{V  dS # 1 d{V swxY w Y   dS )z/Handle a resumption request using GET with SSE.z.Resumption request requires a resumption tokenNrx   ry   r{   z)Resumption GET SSE connection established)rP   r+   r.   resumption_tokenLAST_EVENT_IDr'   rA   r-   rQ   rT   r   rs   r   r*   r<   r1   r|   r=   r0   rZ   r}   r]   rr   r~   rv   r/   on_resumption_token_updateaclose)rI   r   r+   rk   r   rj   is_completes          r%   _handle_resumption_requestz2StreamableHTTPTransport._handle_resumption_request   s|     //<<< 	TCL9 	T%(\%BGM""!"RSSS #c)16GG 	F"%"5"="B"EJHM$,T5JKKK
 
 
 	 	 	 	 	 	 	 	 !22444LLDEEE)3355 	 	 	 	 	 	 	c$($:$:*'?B|UCL;;QU	% %        &/66888888888E 65	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s    AFE<!AF
FFc           	        K   |                      |j                  }|j        j        }|                     |          }|j                            d| j        |                    ddd          |          4 d{V 	 }|j	        dk    r.t                              d           	 ddd          d{V  dS |j	        d	k    rYt          |j        t                    r+|                     |j        |j        j                   d{V  	 ddd          d{V  dS |                                 |r|                     |           t          |j        t                    r|j                            t*          d
                                          }|                    t0                    r#|                     ||j        |           d{V  nY|                    t4                    r|                     |||           d{V  n!|                     ||j                   d{V  ddd          d{V  dS # 1 d{V swxY w Y   dS )z/Handle a POST request with response processing.POSTTjson)by_aliasmodeexclude_none)r   r+   N   zReceived 202 Acceptedi   )rP   r+   r-   rQ   rW   r*   streamr<   
model_dumpstatus_coder]   rr   rA   rT   r   _send_session_terminated_errorr/   rs   r}   r`   r\   rG   lower
startswithrE   _handle_json_responserF   _handle_sse_response_handle_unexpected_content_type)rI   r   r+   rQ   rm   rZ   content_types          r%   _handle_post_requestz,StreamableHTTPTransport._handle_post_request   s     //<<%- ;;GDD:$$H##TT#RR	 % 
 
 "	 "	 "	 "	 "	 "	 "	 "	
 #s**4555"	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 #s**glN;; ==.         !"	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	$ %%'''  G<<XFFF ',77 
'/33L"EEKKMM**400 44Xs?UWhiiiiiiiiii!,,S11 33HcCTUUUUUUUUUU>>$.        ?"	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	 "	s    >'H<8AH<DH<<
I	Ic                   K   	 |                                  d{V }t          j        |          }|r|                     |           t	          |          }|                    |           d{V  dS # t          $ r@}t                              d           |                    |           d{V  Y d}~dS d}~ww xY w)z%Handle JSON response from the server.NzError parsing JSON response)	areadr   rp   ri   r   rt   re   r]   ru   )rI   rZ   r/   rm   contentrQ   r-   rh   s           r%   r   z-StreamableHTTPTransport._handle_json_response(  s      	/$NN,,,,,,,,G$8AAG ! KAA'JJJ,W55O$))/::::::::::: 	/ 	/ 	/:;;;$))#...............	/s   A/A5 5
B??5B::B?c                   K   	 t          |          }|                                2 3 d{V }|                     ||j        |j        r|j        j        nd|           d{V }|r|                                 d{V   dS ^6 dS # t          $ rE}t          	                    d           |j        
                    |           d{V  Y d}~dS d}~ww xY w)z$Handle SSE response from the server.N)rl   rm   zError reading SSE stream:)r   r~   rv   r/   r.   r   r   re   r]   ru   rt   )rI   rZ   r   rm   r   rj   r   es           r%   r   z,StreamableHTTPTransport._handle_sse_response=  sZ     	1&x00L)3355       c$($:$:*TWT`)j)P)Pfj&7	 %; % %        "//+++++++++EE 655  	1 	1 	18999(--a000000000000000	1s(   #B BAB B 
C:CCr   c                    K   d| }t                               |           |                    t          |                     d{V  dS )z+Handle unexpected content type in response.zUnexpected content type: N)r]   errorrt   
ValueError)rI   r   r/   	error_msgs       r%   r   z7StreamableHTTPTransport._handle_unexpected_content_typeV  s[       ?>>	Y %%j&;&;<<<<<<<<<<<r$   
request_idc                    K   t          d|t          dd                    }t          t          |                    }|                    |           d{V  dS )z)Send a session terminated error response.z2.0iX  zSession terminated)coderQ   )jsonrpcrs   r   N)r   r   r   r   rt   )rI   r/   r   jsonrpc_errorr-   s        r%   r   z6StreamableHTTPTransport._send_session_terminated_error`  sv       %0DEEE
 
 

 ))F)FGG %%o66666666666r$   write_stream_readerwrite_streamstart_get_streamtgc                    K   	 |4 d{V  |2 3 d{V }|j         }t          |j        t                    r|j        nd}	t	          |	o|	j                  t                              d|                                 |          r
 |             t          | j
         j        ||	| j                   fd}
t          |j        t                    r|                    |
            |
             d{V  6 	 ddd          d{V  n# 1 d{V swxY w Y   n*# t           $ r t                              d           Y nw xY w|                                 d{V  |                                 d{V  dS # |                                 d{V  |                                 d{V  w xY w)z&Handle writing requests to the server.NzSending client message: )r*   r+   r,   r-   r.   r/   r0   c                     K   r                                 d {V  d S                                 d {V  d S N)r   r   )r   is_resumptionrI   s   r%   handle_request_asynczAStreamableHTTPTransport.post_writer.<locals>.handle_request_async  sh      ( A"&"A"A#"F"FFFFFFFFFF"&";";C"@"@@@@@@@@@@r$   zError in post_writer)rQ   rA   r.   r   boolr   r]   rr   rY   r)   rH   r,   r0   rT   r   
start_soonre   ru   r   )rI   r*   r   r/   r   r   r   r-   rQ   r.   r   r   r   s   `          @@r%   post_writerz#StreamableHTTPTransport.post_writern  s     -	(* &5 &5 &5 &5 &5 &5 &5 &5-@ %5 %5 %5 %5 %5 %5 %5/-5G &o&>@UVV"00!  %))Oh6O$P$PMLL!EG!E!EFFF 88AA +((***(% $ 4#'?(7!)+=)-)>  CA A A A A A A "',?? 5&:;;;;224444444444K .A-@&5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5 &5P  	5 	5 	5344444	5 %++---------%%''''''''''' %++---------%%''''''''''sW   D( DDC+DD( 
D  D( #D $D( 'F ($EF EF 6F>c                   K   | j         sdS 	 |                     | j                  }|                    | j        |           d{V }|j        dk    rt                              d           dS |j        dvr$t                              d|j                    dS dS # t          $ r(}t                              d|            Y d}~dS d}~ww xY w)z2Terminate the session by sending a DELETE request.N)r+   i  z)Server does not allow session termination)      zSession termination failed: )
r,   rP   rH   deleter<   r   r]   rr   rf   re   )rI   r*   r+   rZ   rh   s        r%   terminate_sessionz)StreamableHTTPTransport.terminate_session  s      	F		A33D4HIIG#]]48W]EEEEEEEEH#s**HIIIII%Z77Th>RTTUUUUU 87 	A 	A 	ANN?#??@@@@@@@@@	As   A!B 0+B 
C)CCc                     | j         S )zGet the current session ID.)r,   )rI   s    r%   get_session_idz&StreamableHTTPTransport.get_session_id  s
    r$   )Nr:   r;   N)NNF)F))r   r    r!   r"   r5   r4   r7   r   r1   AuthrJ   rP   r   r   rW   rY   Responser`   ri   r   r6   r   r   r   rv   r2   r   r)   r   r   r   r   r   r   StreamReaderr   r   r	   r   r   r   r#   r$   r%   r9   r9   J   s       99
 *.%'.4"&
 

 c3h$&
 "	

  )+
 j4
 

 
 
 
@T#s(^ SRUX    `. `T ` ` ` `tN tt t t t tC.C 
C C C CEE 
E E E E& 15GK"'' '' )' '-	'
 &seYt_&<=D'  ' 
' ' ' 'RA!A )A 
	A A A A8 N  t        D(n ( ( ( ( (\ #(	/ /./ )/  	/
 
/ / / /2 #(	1 1.1 1  	1
 
1 1 1 12== )= 
	= = = =7(7 7 
	7 7 7 77(!7( *7( )	7(
 -^<7( #2t8,7( 7( 
7( 7( 7( 7(rAe.? AD A A A 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{V 	 t                              d|              |j        t          j
        j        j                  j                  4 d{V 	 dfd}
                    j        |	||
           	 ||j        fW V  j        r|r                               d{V  j                                         nB# j        r|r                               d{V  j                                         w xY w	 ddd          d{V  n# 1 d{V swxY w Y                                    d{V  |                                 d{V  n9#                                  d{V  |                                 d{V  w xY w	 ddd          d{V  dS # 1 d{V swxY w Y   dS )	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: ry   )r+   r=   r>   r?   c                  @                         j                    d S r   )r   r   )r*   r/   r   	transports   r%   r   z/streamablehttp_client.<locals>.start_get_stream  s#    MM)"=vGYZZZZZr$   )r?   N)r9   anyiocreate_memory_object_streamr   re   create_task_groupr]   rr   rH   r1   r|   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     s     : (Wg?OQUVVI&+&GYbHb&cde&f&f#(-(I.(YZ[(\(\%L%&(( #( #( #( #( #( #( #(B"	(LLH3HHIII++!1i&7i>XYYY^   - - - - - - - - [ [ [ [ [ [ [ [ [ )'& $  	-#$!0     !+ B0B B'99&AAAAAAAAAO**,,,, !+ B0B B'99&AAAAAAAAAO**,,,,,9- - - - - - - - - - - - - - - - - - - - - - - - - - -< %++---------%%'''''''''' %++---------%%'''''''''''G#( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #( #(sg   ?H9AG,*F&E>F&?FF&G,&
F0	0G,3F0	4G,75H9,6H""H99
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]   re   SessionMessageOrErrorr6   r   r5   GetSessionIdCallbackrN   rO   r   rG   rD   rE   rF   r   r'   r)   r9   r4   r7   r   r   tupler   r#   r$   r%   <module>r      sv     ? ? ? ? ? ? ? ? ? ? * * * * * * ! ! ! ! ! !               R R R R R R R R @ @ @ @ @ @ @ @ @ @ P P P P P P P P D D D D D D D D	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 
	8	$	$ '2 %&;<(8C$J/ !- 	 > > > > >) > > >5 5 5 5 5) 5 5 5 	 	 	 	 	 	 	 	o o o o o o o od  &*!#*0#1G"D( D(	D(#s(^d"D( YD( i'	D(
 D( /D( *t
D( 	!.9"<=~.	
 	
D( D( D( D( D( D(r$   