
    7|ht-                     ~    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e      Zy)	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            
          e Zd ZU dZeed<   eed<   dZeed<    ed      Zde	eef   fd	Z
defd
Zdededede	eef   fdZ	 d&dedee	   de	fdZdedefdZ	 	 d&dededee	   defdZ ed      ede	defd              Zdee	   fdZdee	   fdZ	 d'dededee	   de	fdZ	 d'dededee	   de	fdZ	 d'dededee	   de	fdZ	 d'dededee	   de	fdZdefd Zdefd!Zdefd"Z defd#Z!defd$Z"defd%Z#y)(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                     ddd}| j                   r"|j                  dd| j                    i       |S |j                  d| j                  i       |S )zFormat headers for requests.zapplication/json)AcceptzContent-TypeAuthorizationzBearer z	X-API-Key)r   updater   )selfheaderss     c/var/www/html/test/engine/venv/lib/python3.12/site-packages/langchain_community/utilities/zapier.py_format_headersz ZapierNLAWrapper._format_headers4   sc     ).

 --NN GD,N,N+O"PQ  NNK)@)@AB    c                     t        j                         }|j                  j                  | j	                                |S N)requestsr   r   r   r   )r   sessions     r   _get_sessionzZapierNLAWrapper._get_sessionD   s0    ""$t3356r   methodurlkwargsc                   K   t        j                  | j                               4 d{   } |j                  ||fi |4 d{   }|j	                          |j                          d{   cddd      d{    cddd      d{    S 7 k7 P7 *7 7 # 1 d{  7  sw Y   nxY wddd      d{  7   y# 1 d{  7  sw Y   yxY ww)zMake an async request.)r   N)aiohttpClientSessionr   requestraise_for_statusjson)r   r$   r%   r&   r"   responses         r   	_arequestzZapierNLAWrapper._arequestI   s     ((1E1E1GH 	- 	-G&wvs=f= - -))+%]]_,- - -	- 	- 	--,-	-- - -	- 	- 	- 	- 	-s   )CBCCB	C$B!0B1B!4C BCCBCCB!CC!B3	'B*(B3	/C6CCCCCCCNinstructionsparamsc                 b    |r|ni }|j                  d|i       |r|j                  ddi       |S )zCreate a payload for an action.r/   preview_onlyT)r   )r   r/   r0   r2   datas        r   _create_action_payloadz'ZapierNLAWrapper._create_action_payloadP   s>      vR	

 KK./r   	action_idc                 (    | j                   d| dz   S )zCreate a url for an action.exposed/z	/execute/)r   )r   r5   s     r   _create_action_urlz#ZapierNLAWrapper._create_action_url^   s    ''HYKy*IIIr   c                 b    | j                  |||      }t        d| j                  |      |      S )NPOSTr,   )r4   r   r8   )r   r5   r/   r0   r2   r3   s         r   _create_action_requestz'ZapierNLAWrapper._create_action_requestb   s9     **<N##I.
 	
r   before)modevaluesc                 H    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   )clsr?   zapier_nla_api_key_defaultr   s       r   validate_environmentz%ZapierNLAWrapper.validate_environmentp   sP    
 &*" +f4)+&68F23 2  &	
 (:#$r   c                 f   K   | j                  d| j                  dz          d{   }|d   S 7 	w)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)
        GETr7   Nresults)r.   r   )r   r-   s     r   alistzZapierNLAWrapper.alist   s7     & t/G/G*/TUU	"" Vs   #1/
1c                 ~   | j                         }	 |j                  | j                  dz         }|j                          |j                         d   S # t        j
                  $ rV}j                  dk(  r@| j                  rt	        j
                  d| |      t	        j
                  d| |      |d}~ww xY w)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)
        r7   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: NrH   )	r#   getr   r+   r!   	HTTPErrorstatus_coder   r,   )r   r"   r-   http_errs       r   listzZapierNLAWrapper.list   s    & ##%	{{4#;#;j#HIH%%'  }}y)) !! 	##s*55",,++3*6 "*	  ((,,4:7% 
 N	s   .A B<&AB77B<c                     | j                         }| j                  |||      }|j                  |j                  |            }|j	                          |j                         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#   r<   sendprepare_requestr+   r,   r   r5   r/   r0   r"   r*   r-   s          r   runzZapierNLAWrapper.run   s\     ##%--ivN<< 7 7 @A!!#}}x((r   c                    K   | j                  d| j                  |      | j                  ||             d{   }|d   S 7 	w)rQ   r:   r;   NrR   r.   r8   r4   r   r5   r/   r0   r-   s        r   arunzZapierNLAWrapper.arun   sS      ##I.,,\6B ( 
 

 !!
s   7AA
Ac                    | j                         }|r|ni }|j                  ddi       | j                  |||d      }|j                  |j	                  |            }|j                          |j                         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.r2   Tinput_params)r#   r   r<   rS   rT   r+   r,   rU   s          r   previewzZapierNLAWrapper.preview   sx     ##%!r~t,---ivtT<< 7 7 @A!!#}}~..r   c           	         K   | j                  d| j                  |      | j                  ||d             d{   }|d   S 7 	w)r\   r:   T)r2   r;   NrR   rX   rY   s        r   apreviewzZapierNLAWrapper.apreview   sY      ##I.,,\6PT,U ( 
 

 !!
s   9AA
Ac                 P     | j                   |i |}t        j                  |      S )cSame as run, but returns a stringified version of the JSON for
        insertting back into an LLM.)rV   r,   dumpsr   argsr&   r3   s       r   
run_as_strzZapierNLAWrapper.run_as_str  s(     txx((zz$r   c                 l   K    | j                   |i | d{   }t        j                  |      S 7 w)rb   N)rZ   r,   rc   rd   s       r   arun_as_strzZapierNLAWrapper.arun_as_str  s4      TYY///zz$ 0   424c                 P     | j                   |i |}t        j                  |      S )gSame as preview, but returns a stringified version of the JSON for
        insertting back into an LLM.)r^   r,   rc   rd   s       r   preview_as_strzZapierNLAWrapper.preview_as_str  s(     t||T,V,zz$r   c                 l   K    | j                   |i | d{   }t        j                  |      S 7 w)rk   N)r`   r,   rc   rd   s       r   apreview_as_strz ZapierNLAWrapper.apreview_as_str  s4     
 #T]]D3F33zz$ 4ri   c                 L    | j                         }t        j                  |      S )dSame as list, but returns a stringified version of the JSON for
        insertting back into an LLM.)rO   r,   rc   r   actionss     r   list_as_strzZapierNLAWrapper.list_as_str   s     ))+zz'""r   c                 h   K   | j                          d{   }t        j                  |      S 7 w)rp   N)rI   r,   rc   rq   s     r   alist_as_strzZapierNLAWrapper.alist_as_str&  s*      

$zz'"" %s   202)NFr    )$__name__
__module____qualname____doc__str__annotations__r   r
   model_configr   r   r   r#   r   r.   r   r4   r8   r   r<   r   classmethodrE   r   rI   rO   rV   rZ   r^   r`   rf   rh   rl   rn   rs   ru    r   r   r   r      sE   $ #&&??Lc3h  g 
-c - -s -tCQTH~ - NS)1$	JC JC J "&

 
 	
 

 (#$ 3   $0#T$Z #,&*d4j &*R KO)),/)9A$)	)$ KO"",/"9A$"	"& KO//,//9A$/	/ KO"",/"9A$"	" S   C      	 #S ##C #r   r   )ry   r,   typingr   r   r   r   r(   r!   langchain_core.utilsr   pydanticr	   r
   r   r   r   r   r~   r   r   <module>r      s5     , ,   5 ; ; %Q#y Q#r   