
    3fi                     v    d dl Z d dlmZmZmZ d dlmZ d dlZd dlZd dl	m
Z
 d dlmZmZmZmZ  G d de      Zy)    N)AnyDictOptional)quoteget_from_dict_or_env)	BaseModel
ConfigDictFieldmodel_validatorc                      e Zd ZU dZ edd      Z eddddd	d
      Zee	d<   	  ei       Z
ee	d<   	 dZee   e	d<   	 dZee   e	d<   	 dZee   e	d<   	 dZee   e	d<   	 dZee   e	d<   	 dZeej,                     e	d<   	  ed      ededefd              ZdedefdZdedefdZdedefdZdedefdZdedefd Z d!edefd"Z!dedefd#Z"dedefd$Z#d%edefd&Z$d'edefd(Z%d%edefd)Z&y)*DataForSeoAPIWrapperz"Wrapper around the DataForSeo API.Tforbid)arbitrary_types_allowedextrazUnited Statesen
   googleorganic)location_namelanguage_codedepthse_namese_type)defaultdefault_paramsparamsN	api_loginapi_passwordjson_result_typesjson_result_fields	top_count
aiosessionbefore)modevaluesreturnc                 N    t        |dd      }t        |dd      }||d<   ||d<   |S )z7Validate that login and password exists in environment.r   DATAFORSEO_LOGINr   DATAFORSEO_PASSWORDr   )clsr&   loginpasswords       q/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/langchain_community/utilities/dataforseo_api_search.pyvalidate_environmentz)DataForSeoAPIWrapper.validate_environment,   s;     %V[:LM'@UV#{!)~    urlc                 ^   K   | j                  | j                  |       d{         S 7 w):Run request to DataForSEO SERP API and parse result async.N)_process_response_aresponse_jsonselfr1   s     r.   arunzDataForSeoAPIWrapper.arun6   s(     %%D,@,@,E&EFF&Es    -+	-c                 B    | j                  | j                  |            S )r3   )r4   _response_jsonr6   s     r.   runzDataForSeoAPIWrapper.run:   s    %%d&9&9#&>??r0   c                 F    | j                  |      }| j                  |      S N)r:   _filter_resultsr7   r1   ress      r.   resultszDataForSeoAPIWrapper.results>   s#    !!#&##C((r0   c                 b   K   | j                  |       d {   }| j                  |      S 7 wr=   )r5   r>   r?   s      r.   aresultszDataForSeoAPIWrapper.aresultsB   s/     ((--##C(( .s   /-/keywordc                 r   | j                   | j                  t        d      t        j                  | j                    d| j                   j                  d            j                  d      }d| dd}dt        |      i}i || j                  | j                  }|g}d|d	    d
|d    d}|||dS )z8Prepare the request details for the DataForSEO SERP API.z)api_login or api_password is not provided:zutf-8zBasic zapplication/json)AuthorizationzContent-TyperD   z#https://api.dataforseo.com/v3/serp/r   /r   z/live/advanced)r1   headersdata)
r   r   
ValueErrorbase64	b64encodeencodedecoder   r   r   )r7   rD   credrI   objrJ   _urls          r.   _prepare_requestz%DataForSeoAPIWrapper._prepare_requestF   s    >>!T%6%6%>HII~~a 1 123::7C

&/ 	 '-TFOEWX%.);;++;t{{;u1#i.1AI~/ 	
 
 	
r0   responsec                 h    |j                  d      dk7  rt        d|j                  d             |S )z;Check the response from the DataForSEO SERP API for errors.status_codei N  z$Got error from DataForSEO SERP API: status_message)getrK   )r7   rT   s     r.   _check_responsez$DataForSeoAPIWrapper._check_response[   s<    <<&%/6x||DT7U6VW  r0   c                     | j                  |      }t        j                  |d   |d   |d         }|j                          | j	                  |j                               S )zFUse requests to run request to DataForSEO SERP API and return results.r1   rI   rJ   rI   json)rS   requestspostraise_for_statusrY   r\   )r7   r1   request_detailsrT   s       r.   r:   z#DataForSeoAPIWrapper._response_jsonc   s]    //4==E"#I. (

 	!!###HMMO44r0   c                   K   | j                  |      }| j                  s|t        j                         4 d{   }|j	                  |d   |d   |d         4 d{   }|j                          d{   }ddd      d{    ddd      d{    nX| j                  j	                  |d   |d   |d         4 d{   }|j                          d{   }ddd      d{    | j                        S 7 7 7 7 # 1 d{  7  sw Y   xY w7 # 1 d{  7  sw Y   BxY w7 q7 [7 M# 1 d{  7  sw Y   ]xY ww)zDUse aiohttp to request DataForSEO SERP API and return results async.Nr1   rI   rJ   r[   )rS   r#   aiohttpClientSessionr^   r\   rY   )r7   r1   r`   sessionrT   r@   s         r.   r5   z$DataForSeoAPIWrapper._aresponse_jsonn   s^    //4,,. 0 0'"<<#E*+I6(0 (  0 0  (/C0 00 0 0 ++&'	2$V, ,  , , $MMO+, , ##C((00
 00 0 0 00 0 0 0,
 ,, , , ,s   6EDE"D$DD$"D6D	7D;D$DD$ED"0ED9ED?D; D?$E/D=0ED$	DD$D	DD	D$"E$D6*D-+D62E;D?=E?EEEEr@   c                    g }| j                   | j                   ng }|j                  dg       D ]  }|j                  dg       D ]  }|j                  dg       D ]{  }t        |      dk(  s|j                  dd      |v r0| j                  |       t        |      dk7  r|j	                  |       | j
                  bt        |      | j
                  k\  s{    |S )Ntasksresultitemsr   type )r    rX   len_cleanup_unnecessary_itemsappendr"   )r7   r@   outputtypestaskrg   items          r.   r>   z$DataForSeoAPIWrapper._filter_results   s    *.*@*@*L&&RTGGGR( 	D((8R0 "JJw3 D5zQ$((62*>%*G77=t9>"MM$/~~1c&kT^^6S	 r0   dc                    | j                   | j                   ng }t        |      dkD  r]t        |j                               D ]A  \  }}t	        |t
              r$| j                  |       t        |      dk(  s6||= :||vs?||= C d|v r|d= d|v r|d= d|v r|d= t        |j                               D ]'  \  }}t	        |t
              s| j                  |       ) |S )Nr   xpathposition	rectangle)r!   rk   listrh   
isinstancedictrl   )r7   rr   fieldskvs        r.   rl   z/DataForSeoAPIWrapper._cleanup_unnecessary_items   s    ,0,C,C,O((UWv;?QWWY 1a&33A61v{aDf_! a<'
?*!+O 	3DAq!T"//2	3 r0   c                 .   d}|j                  dg       D ]  }|j                  dg       D ]  }|j                  d      }|j                  dg       }d|v r"t        d |D              j                  d      }nd	|v r"t        d
 |D              j                  d      }nqd|v r"t        d |D              j                  d      }nKd|v r"t        d |D              j                  d      }n%d|v r!t        d |D              j                  d      }|s   |S )z*Process response from DataForSEO SERP API.zNo good search result foundrf   rg   
item_typesrh   
answer_boxc              3   J   K   | ]  }|j                  d       dk(  s|  yw)ri   r   NrX   .0rq   s     r.   	<genexpr>z9DataForSeoAPIWrapper._process_response.<locals>.<genexpr>   s%      !!%$((62Bl2R!   ##textknowledge_graphc              3   J   K   | ]  }|j                  d       dk(  s|  yw)ri   r   Nr   r   s     r.   r   z9DataForSeoAPIWrapper._process_response.<locals>.<genexpr>   s&      !!%$((62BFW2W!r   descriptionfeatured_snippetc              3   J   K   | ]  }|j                  d       dk(  s|  yw)ri   r   Nr   r   s     r.   r   z9DataForSeoAPIWrapper._process_response.<locals>.<genexpr>   s&      !!%$((62BFX2X!r   shoppingc              3   J   K   | ]  }|j                  d       dk(  s|  yw)ri   r   Nr   r   s     r.   r   z9DataForSeoAPIWrapper._process_response.<locals>.<genexpr>   s%      !!%$((62Bj2P!r   pricer   c              3   J   K   | ]  }|j                  d       dk(  s|  yw)ri   r   Nr   r   s     r.   r   z9DataForSeoAPIWrapper._process_response.<locals>.<genexpr>   s%      !!%$((62Bi2O!r   )rX   next)r7   r@   toretrp   rg   r~   rh   s          r.   r4   z&DataForSeoAPIWrapper._process_response   sJ   -GGGR( 	D((8R0 #ZZ5


7B/:-  !).! c&k  '*4  !).! c-(  (:5  !).! c-(   :-  !).! c'l  *,  !).! c-(  1	4 r0   )'__name__
__module____qualname____doc__r
   model_configr   r   ry   __annotations__r   r   r   strr   r    rw   r!   r"   intr#   rb   rc   r   classmethodr   r   r/   r8   r;   rA   rC   rS   rY   r:   r5   r>   rl   r4    r0   r.   r   r      s   , $L
 !,! 
ND  A$FD$C#Ix}#;"&L(3-&>(,x~, )--!#Ix}#.26J../6A(#$ 3   $Gc Gc G@s @s @)3 )4 ))# )$ )
 
 
*  	5# 	5$ 	5) ) )(4 D D T ,T c r0   r   )rL   typingr   r   r   urllib.parser   rb   r]   langchain_core.utilsr   pydanticr	   r
   r   r   r   r   r0   r.   <module>r      s.     & &    5 B Bx9 xr0   