o
    ȳg                     @   sR  d Z ddlmZmZ ddlmZmZmZmZmZ ddl	Z	ddl
mZ ddlmZmZmZmZ G dd dZzdd	lmZmZmZmZmZ W nE ey   d
edef dedededef fddZdeddfddZdededdfddZddedfdedededdfddZY nw de	jde fd d!Z!G d"d# d#eZ"d$Z#G d%d& d&eZ$dS )'z.Util that invokes the Passio Nutrition AI API.    )datetime	timedelta)AnyCallableDictOptionalfinalN)get_from_dict_or_env)	BaseModel
ConfigDictFieldmodel_validatorc                   @   s4   e Zd ZdZed	ddZededdfddZdS )
NoDiskStoragez!Mixin to prevent storing on disk.returnNc                 C      t dNzDo not store on disk.AttributeErrorself r   m/var/www/html/chatdoc2/venv/lib/python3.10/site-packages/langchain_community/utilities/passio_nutrition_ai.py__getstate__      zNoDiskStorage.__getstate__statec                 C   r   r   r   )r   r   r   r   r   __setstate__   r   zNoDiskStorage.__setstate__r   N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r      s    r   )retryretry_if_resultstop_after_attemptwait_exponentialwait_randomf.argskwargsr   c                 O   s   | S Nr   )r&   r'   r(   r   r   r   retry_fallback!      r*   nc                 C      d S r)   r   )r,   r   r   r   stop_after_attempt_fallback&      r.   abc                 C   r-   r)   r   )r0   r1   r   r   r   wait_random_fallback)   r/   r2      inf
multiplierminmaxc                 C   r-   r)   r   r5   r6   r7   r   r   r   wait_exponential_fallback,   r+   r9   rspc                 C   s   t | o| jdv S )z&Check if a HTTP response is retryable.)i  i  i  i  i  i  i  )boolstatus_code)r:   r   r   r   is_http_retryable2   s   r=   c                	   @   s   e Zd ZU dZee ed< defddZe	de
fddZdefd	d
Zeeeededdedddd ddedejfddZdddZdS )ManagedPassioLifeAuthz)Manage the token for the NutritionAI API._access_token_expirysubscription_keyc                 C   s"   || _ d | _d | _d | _d | _d S r)   )r@   _last_tokenr?   _access_token_customer_idr   r@   r   r   r   __init__<   s
   
zManagedPassioLifeAuth.__init__r   c                 C   s$   |   s|   d| j | jdS )NzBearer )Authorizationz	Passio-ID)is_valid_nowrefresh_access_tokenrB   rC   r   r   r   r   headersC   s
   
zManagedPassioLifeAuth.headersc                 C   s,   | j d uo| jd uo| jd uo| jt kS r)   )rB   rC   r?   r   nowr   r   r   r   rG   L   s   
z"ManagedPassioLifeAuth.is_valid_now   r   333333?r3   皙?   r8   r!   stopwaitc                 C   s   t d| S )Nz;https://api.passiolife.com/v2/token-cache/napi/oauth/token/)requestsgetrD   r   r   r   	_http_getT   s   zManagedPassioLifeAuth._http_getNc                 C   s`   |  | j}|std|  | _}|d | _|d | _t t	|d d t	dd | _
dS )z1Refresh the access token for the NutritionAI API.zCould not get access tokencustomer_idaccess_token
expires_in)seconds   N)rT   r@   
ValueErrorjsonrA   rC   rB   r   rJ   r   r?   )r   r:   tokenr   r   r   rH   ^   s   

z*ManagedPassioLifeAuth.refresh_access_tokenr   )r   r   r   r    r   r   __annotations__strrE   propertydictrI   r;   rG   r!   r"   r=   r#   r%   r$   rR   ResponserT   rH   r   r   r   r   r>   7   s   
 r>   z@https://api.passiolife.com/v2/products/napi/food/search/advancedc                	   @   s   e Zd ZU dZeed< eedZeed< ee	dZ
e	ed< eed< edd	d
Zeeeededdedddd dde	dejfddZdede	fddZeddededefddZdedee fd d!Zd"S )#NutritionAIAPIz(Wrapper for the Passio Nutrition AI API.nutritionai_subscription_key)defaultnutritionai_api_url)default_factorymore_kwargsauth_Tforbid)arbitrary_types_allowedextrarK   r   rL   r3   rM   rN   r8   rO   paramsr   c                 C   s   t j| j| jj|dS )N)rI   rl   )rR   rS   re   rh   rI   )r   rl   r   r   r   rT      s
   zNutritionAIAPI._http_getsearch_termc                 C   s0   |  d|i| j}|std|  | S )z0Call the NutritionAI API and return the results.termz%Could not get NutritionAI API results)rT   rg   rZ   raise_for_statusr[   )r   rm   r:   r   r   r   _api_call_results   s
   z NutritionAIAPI._api_call_resultsbefore)modevaluesc                 C   s:   t |dd}||d< t |ddt}||d< t||d< |S )z9Validate that api key and endpoint exists in environment.rc   NUTRITIONAI_SUBSCRIPTION_KEYre   NUTRITIONAI_API_URLrh   )r	   DEFAULT_NUTRITIONAI_API_URLr>   )clsrs   rc   re   r   r   r   validate_environment   s   z#NutritionAIAPI.validate_environmentqueryc                 C   s"   |  |}|rt|dk rdS |S )z4Run query through NutrtitionAI API and parse result.r3   N)rp   len)r   ry   resultsr   r   r   run   s   
zNutritionAIAPI.runN)r   r   r   r    r^   r]   r   rv   re   r`   rg   r>   r   model_configr!   r"   r=   r#   r%   r$   rR   ra   rT   rp   r   classmethodr   r   rx   r   r|   r   r   r   r   rb   s   s*   
 rb   )%r    r   r   typingr   r   r   r   r   rR   langchain_core.utilsr	   pydanticr
   r   r   r   r   tenacityr!   r"   r#   r$   r%   ImportErrorr*   intr.   floatr2   r9   ra   r;   r=   r>   rv   rb   r   r   r   r   <module>   sJ     



8