Ë
    ¥©	jI  ã                   óÂ   — U d Z ddlZddlZddlmZmZ ddlmZ ddlZddlm	Z	 ddl
mZmZ ddlmZ ddlmZ dd	lmZ  ee«      Z G d
„ d«      Zdaedz  ed<   defd„Zy)z{
IBM watsonx.ai client with automatic IAM token refresh.
Tokens expire after 60 minutes - refresh 5 minutes before expiry.
é    N)ÚdatetimeÚ	timedelta)ÚAny)ÚIAMAuthenticator)Ú	APIClientÚCredentials)ÚModelInference)Úsettings)Ú
get_loggerc                   óh   — e Zd ZdZd„ Zdefd„Zdd„Zdefd„Z		 	 dde
d	e
d
edz  dedz  dede
fd„Zy)ÚWatsonxClientz¸
    Manages watsonx.ai API client with automatic token refresh.
    
    IAM tokens expire after 60 minutes. We refresh 5 minutes before expiry
    to avoid mid-request failures.
    c                 ó
  — t         j                  | _        t         j                  | _        t         j
                  | _        t         j                  | _        d | _	        d | _
        t        j                  d| j                  ¬«       y )NÚwatsonx_client_initialized)Úurl)r
   Úwatsonx_api_keyÚapi_keyÚwatsonx_project_idÚ
project_idÚwatsonx_urlr   Ú iam_token_refresh_margin_secondsÚrefresh_marginÚ_clientÚ_token_expiryÚloggerÚinfo©Úselfs    ú;/var/www/html/prparty/backend/app/clients/watsonx_client.pyÚ__init__zWatsonxClient.__init__   s[   € Ü×/Ñ/ˆŒÜ"×5Ñ5ˆŒÜ×'Ñ'ˆŒÜ&×GÑGˆÔà)-ˆŒØ.2ˆÔä�‰Ð0°d·h±hˆÕ?ó    Úreturnc                 ó˜   — | j                   €y| j                   t        j                  «       z
  j                  «       }|| j                  k  S )zCheck if token needs refresh.T)r   r   ÚnowÚtotal_secondsr   )r   Útime_until_expirys     r   Ú_should_refresh_tokenz#WatsonxClient._should_refresh_token(   sD   € à×ÑÐ%Øð "×/Ñ/´(·,±,³.Ñ@×OÑOÓQÐØ  D×$7Ñ$7Ñ7Ð7r    Nc                 óT  — t         j                  d«       t        | j                  | j                  ¬«      }t        || j                  ¬«      | _        t        j                  «       t        d¬«      z   | _        t         j                  d| j                  j                  «       d¬«       y	)
z'Create new API client with fresh token.Úrefreshing_watsonx_token)r   r   )Úcredentialsr   é<   )ÚminutesÚwatsonx_token_refreshedi  )Ú
expires_atÚvalid_for_secondsN)r   r   r   r   r   r   r   r   r   r#   r   r   Ú	isoformat)r   r)   s     r   Ú_refresh_clientzWatsonxClient._refresh_client1   s~   € ä�‰Ð.Ô/ä!Ø—‘Ø—L‘Lô
ˆô
 !¨[ÀTÇ_Á_ÔUˆŒô &Ÿ\™\›^¬iÀÔ.CÑCˆÔä�‰Ø%Ø×)Ñ)×3Ñ3Ó5Ø"ð 	õ 	
r    c                 ó€   — | j                  «       r| j                  «        | j                  €J d«       ‚| j                  S )z+Get API client, refreshing token if needed.zClient should be initialized)r&   r0   r   r   s    r   Ú
get_clientzWatsonxClient.get_clientE   s:   € à×%Ñ%Ô'Ø× Ñ Ô"à�|‰|Ð'ÐGÐ)GÓGÐ'Ø�|‰|Ðr    Úmodel_idÚpromptÚ
max_tokensÚtemperatureÚkwargsc           
   ‹   ó¨  ‡‡K  — | j                  «       }|€t        j                  }|€t        j                  }t        j                  d|t        ‰«      ||¬«       t        j                  «       }	 t        ||||dœ|¥¬«      Št        j                  «       }|j                  dˆˆfd„«      ƒ d{  –—† }	t        j                  «       |z
  }
t        j                  d|t        |	«      t        |
d«      ¬	«       |	S 7 ŒI# t        $ rI}t        j                  «       |z
  }
t        j                  d
|t        |«      t        |
d«      ¬«       ‚ d}~ww xY w­w)a™  
        Generate text using watsonx.ai foundation model.
        
        Args:
            model_id: Model identifier (e.g., 'ibm/granite-3-3-8b-instruct')
            prompt: Input prompt
            max_tokens: Maximum tokens to generate
            temperature: Sampling temperature (0.0-1.0)
            **kwargs: Additional model parameters
        
        Returns:
            Generated text
        NÚwatsonx_generate_request)r3   Úprompt_lengthr5   r6   )Úmax_new_tokensr6   )r3   Ú
api_clientÚparamsc                  ó(   •— ‰ j                  ‰¬«      S )N)r4   )Úgenerate_text)Úmodelr4   s   €€r   ú<lambda>z-WatsonxClient.generate_text.<locals>.<lambda>�   s   ø€ ˜e×1Ñ1¸Ð1Ó@€ r    Úwatsonx_generate_successé   )r3   Úresponse_lengthÚelapsed_secondsÚwatsonx_generate_error)r3   ÚerrorrE   )r2   r
   Úgranite_max_tokensÚgranite_temperaturer   r   ÚlenÚtimer	   ÚasyncioÚget_event_loopÚrun_in_executorÚroundÚ	ExceptionrG   Ústr)r   r3   r4   r5   r6   r7   ÚclientÚ
start_timeÚloopÚresultÚelapsedÚer@   s     `         @r   r?   zWatsonxClient.generate_textM   sS  ùè ø€ ð* —‘Ó"ˆð ÐÜ!×4Ñ4ˆJØÐÜ"×6Ñ6ˆKä�‰Ø&ØÜ˜f›+Ø!Ø#ð 	ô 	
ô —Y‘Y“[ˆ
ð#	Ü"Ø!Ø!à&0Ø#.ñð ðôˆEô ×)Ñ)Ó+ˆDØ×/Ñ/ØÔ@ó÷ ˆFô —i‘i“k JÑ.ˆGä�K‰KØ*Ø!Ü # F£Ü % g¨qÓ 1ð	 ô ð ˆMðùô ò 	Ü—i‘i“k JÑ.ˆGÜ�L‰LØ(Ø!Ü˜!“fÜ % g¨qÓ 1ð	 ô ð ûð	üs?   „A,EÁ1A C= Â1C;Â2AC= Ã:EÃ;C= Ã=	EÄAE
Å
EÅE)r!   N)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úboolr&   r0   r   r2   rQ   ÚintÚfloatr   r?   © r    r   r   r      s€   „ ñò	@ð8 tó 8ó
ð(˜Ió ð "&Ø$(ñJàðJð ðJð ˜$‘Jð	Jð
 ˜T‘\ðJð ðJð 
ôJr    r   Ú_watsonx_clientr!   c                  ó.   — t         €
t        «       a t         S )z-Get or create global watsonx client instance.)r`   r   r_   r    r   Úget_watsonx_clientrb   ž   s   € ô ÐÜ'›/ˆÜÐr    )r[   rL   rK   r   r   Útypingr   ÚhttpxÚ!ibm_cloud_sdk_core.authenticatorsr   Úibm_watsonx_air   r   Ú ibm_watsonx_ai.foundation_modelsr	   Ú
app.configr
   Úapp.logging_configr   rX   r   r   r`   Ú__annotations__rb   r_   r    r   ú<module>rk      s^   ðòó Û ß (Ý ã Ý >ß 1Ý ;å Ý )á	�HÓ	€÷Bñ BðL )-€� Ñ%Ó ,ð˜Mô r    