o
    i                     @   s   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	Z	d dl
mZ d dlmZ d dlmZmZ d dlmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZ eeZG dd deZG dd deZ dS )    N)AnyOptional)AsyncExitStack)cached_property)MCPAuthException)MCPClientBase)OAuthParamsAsyncOAuth2Client)MemoryObjectReceiveStreamMemoryObjectSendStream)
sse_client)SessionMessage)OAuth2Token)	BaseModelc                   @   sJ   e Zd ZU dZeed< dZeeee	f  ed< dZ
eed< dZeed< dS )	SSEServerParamsz6Parameters required for a MCPClient with SSE transporturlNheaders   timeouti,  sse_read_timeout)__name__
__module____qualname____doc__str__annotations__r   r   dictr   r   floatr    r   r   ]/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/mistralai/extra/mcp/sse.pyr      s   
 r   c                
       s  e Zd ZU dZee ed< eed< 			d#dedee dee dee	 f fd	d
Z
edefddZdefddZdedeeef fddZdededede	fddZdd Zde	ddfddZdeeef fddZdefddZd edeeejeef  ee f fd!d"Z  ZS )$MCPClientSSEaL  MCP client that uses sse for communication.

    The client provides authentication for OAuth2 protocol following the current MCP authorization spec:
    https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization.

    This is possibly going to change in the future since the protocol has ongoing discussions.
    _oauth_params_sse_paramsN
sse_paramsnameoauth_params
auth_tokenc                    s$   t  j|d || _|| _|| _d S )N)r$   )super__init__r"   r!   _auth_token)selfr#   r$   r%   r&   	__class__r   r   r(   /   s   
zMCPClientSSE.__init__returnc                 C   s   | j jdS )Nz/sse)r"   r   rstrip)r*   r   r   r   base_url;   s   zMCPClientSSE.base_urlc                 C   s&   | j durtd| j  || _ dS )z/Update the oauth params and client accordingly.Nz$Overriding current oauth params for )r!   loggerwarning_name)r*   r%   r   r   r   set_oauth_params?   s   

zMCPClientSSE.set_oauth_paramsredirect_urlc                    s@   | j du r
tdt| j }|j| j jj|d\}}||fS )z<Create the authorization url for client to start oauth flow.NzmCan't generate an authorization url without oauth_params being set, make sure the oauth params have been set.)redirect_uri)r!   r   r	   from_oauth_paramscreate_authorization_urlschemeauthorization_url)r*   r4   oauth_clientauth_urlstater   r   r   get_auth_url_and_stateE   s   


z#MCPClientSSE.get_auth_url_and_stateauthorization_responser<   c                    sH   | j du r
tdt| j }|j| j jj||ddi|dI dH }|S )z/Fetch the authentication token from the server.NzGCan't fetch a token without oauth_params, make sure they have been set.Content-Type!application/x-www-form-urlencoded)r   r>   r5   r   r<   )r!   r   r	   r6   fetch_tokenr8   	token_url)r*   r>   r4   r<   r:   oauth_tokenr   r   r   get_token_from_auth_responseR   s   
z)MCPClientSSE.get_token_from_auth_responsec                    st   | j du s| j jjdu rtd| jdu rtdt| j }|j| j jj| jd ddidI dH }| | dS )zRefresh an expired token.NzUCan't refresh a token without a refresh url make sure the oauth params have been set.z]Can't refresh a token without a refresh token, use the `set_auth_token` to add a OAuth2Token.refresh_tokenr?   r@   )r   rE   r   )	r!   r8   refresh_urlr   r)   r	   r6   rE   set_auth_token)r*   r:   rC   r   r   r   refresh_auth_tokeng   s    
zMCPClientSSE.refresh_auth_tokentokenc                 C   s
   || _ dS )z3Register the authentication token with this client.N)r)   )r*   rI   r   r   r   rG   y   s   
zMCPClientSSE.set_auth_tokenc                 C   s6   i }| j jr|| j jO }| jrd| jd  |d< |S )NzBearer access_tokenAuthorization)r"   r   r)   )r*   r   r   r   r   _format_headers}   s   zMCPClientSSE._format_headersc                    s,   t j| jj|  | jjd}|jtjj	kS )zKCheck if the client requires authentication to communicate with the server.)r   r   )
httpxgetr"   r   rL   r   status_codehttp
HTTPStatusUNAUTHORIZED)r*   responser   r   r   requires_auth   s   zMCPClientSSE.requires_auth
exit_stackc              
      s   z| t| jj|  | jj| jjdI d H W S  tyB } zt|t	j
r=|jjtjjkr=| jd u r8td|td| d }~ww )N)r   r   r   r   z4Authentication required but no auth params provided.zAuthentication required.)enter_async_contextr   r"   r   rL   r   r   	Exception
isinstancerM   HTTPStatusErrorrS   rO   rP   rQ   rR   r!   r   )r*   rU   er   r   r   _get_transport   s.   

zMCPClientSSE._get_transport)NNN) r   r   r   r   r   r   r   r   r   r   r(   r   r/   r3   tupler=   rD   rH   rG   r   rL   boolrT   r   r
   typingUnionr   rW   r   r[   __classcell__r   r   r+   r   r    #   sT   
 
	r    )!rP   loggingr^   r   r   
contextlibr   	functoolsr   rM   mistralai.extra.exceptionsr   mistralai.extra.mcp.baser   mistralai.extra.mcp.authr   r	   anyio.streams.memoryr
   r   mcp.client.sser   mcp.shared.messager   authlib.oauth2.rfc6749r   mistralai.typesr   	getLoggerr   r0   r   r    r   r   r   r   <module>   s$    
	