o
    ȳgt-                     @   sx   d Z ddlZddlmZmZmZmZ ddlZddlZddl	m
Z
 ddlmZmZmZ ddlmZmZ G dd deZdS )	a  Util that can interact with Zapier NLA.

Full docs here: https://nla.zapier.com/start/

Note: this wrapper currently only implemented the `api_key` auth method for testing
and server-side production use cases (using the developer's connected accounts on
Zapier.com)

For use-cases where LangChain + Zapier NLA is powering a user-facing application, and
LangChain needs access to the end-user's connected accounts on Zapier.com, you'll need
to use oauth. Review the full docs above and reach out to nla@zapier.com for
developer support.
    N)AnyDictListOptionalget_from_dict_or_env)	BaseModel
ConfigDictmodel_validator)RequestSessionc                
   @   s  e Zd ZU dZeed< eed< dZeed< eddZde	eef fd	d
Z
defddZdededede	eef fddZ	d:dedee	 de	fddZdedefddZ		d:dededee	 defddZeddede	defd d!Zdee	 fd"d#Zdee	 fd$d%Z	d;dededee	 de	fd&d'Z	d;dededee	 de	fd(d)Z	d;dededee	 de	fd*d+Z	d;dededee	 de	fd,d-Zdefd.d/Zdefd0d1Zdefd2d3Z defd4d5Z!defd6d7Z"defd8d9Z#dS )<ZapierNLAWrappera  Wrapper for Zapier NLA.

    Full docs here: https://nla.zapier.com/start/

    This wrapper supports both API Key and OAuth Credential auth methods. API Key
    is the fastest way to get started using this wrapper.

    Call this wrapper with either `zapier_nla_api_key` or
    `zapier_nla_oauth_access_token` arguments, or set the `ZAPIER_NLA_API_KEY`
    environment variable. If both arguments are set, the Access Token will take
    precedence.

    For use-cases where LangChain + Zapier NLA is powering a user-facing application,
    and LangChain needs access to the end-user's connected accounts on Zapier.com,
    you'll need to use OAuth. Review the full docs above to learn how to create
    your own provider and generate credentials.
    zapier_nla_api_keyzapier_nla_oauth_access_tokenzhttps://nla.zapier.com/api/v1/zapier_nla_api_baseforbid)extrareturnc                 C   s>   ddd}| j r|dd| j  i |S |d| ji |S )zFormat headers for requests.zapplication/json)AcceptzContent-TypeAuthorizationzBearer z	X-API-Key)r   updater   )selfheaders r   `/var/www/html/chatdoc2/venv/lib/python3.10/site-packages/langchain_community/utilities/zapier.py_format_headers4   s   z ZapierNLAWrapper._format_headersc                 C   s   t  }|j|   |S N)requestsr   r   r   r   )r   sessionr   r   r   _get_sessionD   s   zZapierNLAWrapper._get_sessionmethodurlkwargsc              
      s   t j|  d4 I dH E}|j||fi |4 I dH  }|  | I dH W  d  I dH  W  d  I dH  S 1 I dH sBw   Y  W d  I dH  dS 1 I dH sXw   Y  dS )zMake an async request.)r   N)aiohttpClientSessionr   requestraise_for_statusjson)r   r    r!   r"   r   responser   r   r   	_arequestI   s   .zZapierNLAWrapper._arequestNFinstructionsparamsc                 C   s0   |r|ni }| d|i |r| ddi |S )zCreate a payload for an action.r*   preview_onlyT)r   )r   r*   r+   r,   datar   r   r   _create_action_payloadP   s   z'ZapierNLAWrapper._create_action_payload	action_idc                 C   s   | j d| d S )zCreate a url for an action.exposed/z	/execute/)r   )r   r/   r   r   r   _create_action_url^   s   z#ZapierNLAWrapper._create_action_urlc                 C   s"   |  |||}td| ||dS )NPOSTr'   )r.   r   r1   )r   r/   r*   r+   r,   r-   r   r   r   _create_action_requestb   s   z'ZapierNLAWrapper._create_action_requestbefore)modevaluesc                 C   s4   d}d|v r	d}nd|d< t |dd|}||d< |S )z,Validate that api key exists in environment.Nr    r   ZAPIER_NLA_API_KEYr   )clsr7   zapier_nla_api_key_defaultr   r   r   r   validate_environmentp   s   z%ZapierNLAWrapper.validate_environmentc                    s"   |  d| jd I dH }|d S )a  Returns a list of all exposed (enabled) actions associated with
        current user (associated with the set api_key). Change your exposed
        actions here: https://nla.zapier.com/demo/start/

        The return list can be empty if no actions exposed. Else will contain
        a list of action objects:

        [{
            "id": str,
            "description": str,
            "params": Dict[str, str]
        }]

        `params` will always contain an `instructions` key, the only required
        param. All others optional and if provided will override any AI guesses
        (see "understanding the AI guessing flow" here:
        https://nla.zapier.com/api/v1/docs)
        GETr0   Nresults)r)   r   )r   r(   r   r   r   alist   s   zZapierNLAWrapper.alistc              
   C   s   |   }z|| jd }|  W n+ tjy= } z|jdkr7| jr-tjd| |dtjd| |d|d}~ww | d S )a  Returns a list of all exposed (enabled) actions associated with
        current user (associated with the set api_key). Change your exposed
        actions here: https://nla.zapier.com/demo/start/

        The return list can be empty if no actions exposed. Else will contain
        a list of action objects:

        [{
            "id": str,
            "description": str,
            "params": Dict[str, str]
        }]

        `params` will always contain an `instructions` key, the only required
        param. All others optional and if provided will override any AI guesses
        (see "understanding the AI guessing flow" here:
        https://nla.zapier.com/docs/using-the-api#ai-guessing)
        r0   i  zrAn unauthorized response occurred. Check that your access token is correct and doesn't need to be refreshed. Err: )r(   zLAn unauthorized response occurred. Check that your api key is correct. Err: Nr>   )	r   getr   r&   r   	HTTPErrorstatus_coder   r'   )r   r   r(   http_errr   r   r   list   s.   
zZapierNLAWrapper.listc                 C   s:   |   }| |||}|||}|  | d S )  Executes an action that is identified by action_id, must be exposed
        (enabled) by the current user (associated with the set api_key). Change
        your exposed actions here: https://nla.zapier.com/demo/start/

        The return JSON is guaranteed to be less than ~500 words (350
        tokens) making it safe to inject into the prompt of another LLM
        call.
        result)r   r4   sendprepare_requestr&   r'   r   r/   r*   r+   r   r%   r(   r   r   r   run   s
   zZapierNLAWrapper.runc                    s.   | j d| || ||dI dH }|d S )rE   r2   r3   NrF   r)   r1   r.   r   r/   r*   r+   r(   r   r   r   arun   s   
zZapierNLAWrapper.arunc                 C   sV   |   }|r|ni }|ddi | |||d}|||}|  | d S )Same as run, but instead of actually executing the action, will
        instead return a preview of params that have been guessed by the AI in
        case you need to explicitly review before executing.r,   Tinput_params)r   r   r4   rG   rH   r&   r'   rI   r   r   r   preview   s   zZapierNLAWrapper.previewc                    s2   | j d| || j||dddI dH }|d S )rN   r2   T)r,   r3   NrF   rK   rL   r   r   r   apreview   s   zZapierNLAWrapper.apreviewc                 O      | j |i |}t|S )cSame as run, but returns a stringified version of the JSON for
        insertting back into an LLM.)rJ   r'   dumpsr   argsr"   r-   r   r   r   
run_as_str     
zZapierNLAWrapper.run_as_strc                    "   | j |i |I dH }t|S )rS   N)rM   r'   rT   rU   r   r   r   arun_as_str  s   
zZapierNLAWrapper.arun_as_strc                 O   rR   )gSame as preview, but returns a stringified version of the JSON for
        insertting back into an LLM.)rP   r'   rT   rU   r   r   r   preview_as_str  rX   zZapierNLAWrapper.preview_as_strc                    rY   )r[   N)rQ   r'   rT   rU   r   r   r   apreview_as_str  s   
z ZapierNLAWrapper.apreview_as_strc                 C   s   |   }t|S )dSame as list, but returns a stringified version of the JSON for
        insertting back into an LLM.)rD   r'   rT   r   actionsr   r   r   list_as_str   s   
zZapierNLAWrapper.list_as_strc                    s   |   I dH }t|S )r^   N)r?   r'   rT   r_   r   r   r   alist_as_str&  s   
zZapierNLAWrapper.alist_as_str)NFr   )$__name__
__module____qualname____doc__str__annotations__r   r	   model_configr   r   r   r   r   r)   r   r.   r1   r   r4   r
   classmethodr<   r   r?   rD   rJ   rM   rP   rQ   rW   rZ   r\   r]   ra   rb   r   r   r   r   r      s   
 "

)




r   )rf   r'   typingr   r   r   r   r#   r   langchain_core.utilsr   pydanticr   r	   r
   r   r   r   r   r   r   r   <module>   s    