U
    ™ÀÂhQ-  ã                   @   st   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
mZ ddl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)Ú	BaseModelÚroot_validator©Úget_from_dict_or_env)ÚRequestÚSessionc                   @   s¸  e Zd ZU dZeed< eed< dZeed< G dd„ dƒZeeef dœd	d
„Z	e
dœdd„Zeeeeeef dœdd„Zd8eee edœdd„Zeedœdd„Zd9eeee edœdd„Zeddeedœdd„ƒZee dœd d!„Zee dœd"d#„Zd:eeee edœd$d%„Zd;eeee edœd&d'„Zd<eeee edœd(d)„Zd=eeee edœd*d+„Zedœd,d-„Zedœd.d/„Zedœd0d1„Zedœd2d3„Zedœd4d5„Z edœd6d7„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_basec                   @   s   e Zd ZdZdS )zZapierNLAWrapper.ConfigZforbidN)Ú__name__Ú
__module__Ú__qualname__Úextra© r   r   úH/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/utilities/zapier.pyÚConfig0   s   r   )Úreturnc                 C   s<   dddœ}| j r(| dd| j › i¡ n| d| ji¡ |S )zFormat headers for requests.zapplication/json)ÚAcceptzContent-TypeÚAuthorizationzBearer z	X-API-Key)r   Úupdater   )ÚselfÚheadersr   r   r   Ú_format_headers3   s    þÿz ZapierNLAWrapper._format_headersc                 C   s   t  ¡ }|j |  ¡ ¡ |S )N)Úrequestsr   r   r   r   )r   Úsessionr   r   r   Ú_get_sessionC   s    zZapierNLAWrapper._get_session)ÚmethodÚurlÚkwargsr   c                 Ë   sŽ   t j|  ¡ d4 I dH šf}|j||f|Ž4 I dH š<}| ¡  | ¡ I dH W  5 Q I dH R £ W  5 Q I dH R £ S Q I dH R X W 5 Q I dH R X dS )zMake an async request.)r   N)ÚaiohttpZClientSessionr   ÚrequestÚraise_for_statusÚjson)r   r!   r"   r#   r   Úresponser   r   r   Ú	_arequestH   s    zZapierNLAWrapper._arequestNF)ÚinstructionsÚparamsr   c                 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_payloadO   s     ÿÿz'ZapierNLAWrapper._create_action_payload)Ú	action_idr   c                 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_url)r/   r*   r+   r   c                 C   s"   |   |||¡}td|  |¡|dS )NÚPOST©r'   )r.   r
   r1   )r   r/   r*   r+   r,   r-   r   r   r   Ú_create_action_requesta   s    ýz'ZapierNLAWrapper._create_action_requestT)Úpre)Úvaluesr   c                 C   s4   d}d|krd}nd|d< t |dd|ƒ}||d< |S )z,Validate that api key exists in environment.Nr   Ú r   ZZAPIER_NLA_API_KEYr   )Úclsr6   Zzapier_nla_api_key_defaultr   r   r   r   Úvalidate_environmento   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k
r„ } z@|jdkrp| jr\tjd|› |d‚tjd|› |d‚|‚W 5 d}~X Y nX | ¡ 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 )rB   r2   r3   NrC   ©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,   TZinput_params)r    r   r4   rD   rE   r&   r'   rF   r   r   r   Úpreviewé   s    zZapierNLAWrapper.previewc                 Ã   s0   | j d|  |¡| j||dddI dH }|d S )rK   r2   T)r,   r3   NrC   rH   rI   r   r   r   Úapreview÷   s    ýzZapierNLAWrapper.apreviewc                 O   s   | j ||Ž}t |¡S )úcSame as run, but returns a stringified version of the JSON for
        insertting back into an LLM.)rG   r'   Údumps©r   Úargsr#   r-   r   r   r   Ú
run_as_str  s    zZapierNLAWrapper.run_as_strc                 Ï   s   | j ||ŽI dH }t |¡S )rN   N)rJ   r'   rO   rP   r   r   r   Úarun_as_str
  s    zZapierNLAWrapper.arun_as_strc                 O   s   | j ||Ž}t |¡S )úgSame as preview, but returns a stringified version of the JSON for
        insertting back into an LLM.)rL   r'   rO   rP   r   r   r   Úpreview_as_str  s    zZapierNLAWrapper.preview_as_strc                 Ï   s   | j ||ŽI dH }t |¡S )rT   N)rM   r'   rO   rP   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.)rA   r'   rO   ©r   Úactionsr   r   r   Úlist_as_str  s    zZapierNLAWrapper.list_as_strc                 Ã   s   |   ¡ I dH }t |¡S )rW   N)r<   r'   rO   rX   r   r   r   Úalist_as_str$  s    zZapierNLAWrapper.alist_as_str)NF)NF)N)N)N)N)"r   r   r   Ú__doc__ÚstrÚ__annotations__r   r   r   r   r   r    r   r)   r   r.   r1   r
   r4   r   r9   r   r<   rA   rG   rJ   rL   rM   rR   rS   rU   rV   rZ   r[   r   r   r   r   r      s~   
   ÿ þ  ûú) ÿ  þ ÿ  þ ÿ  þ ÿ  þþr   )r\   r'   Útypingr   r   r   r   r$   r   Zlangchain_core.pydantic_v1r   r   Zlangchain_core.utilsr	   r
   r   r   r   r   r   r   Ú<module>   s   