o
    Zhb                     @   sl   d 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 G dd deZdS )	z7Util that calls Google Search using the Serper.dev API.    )AnyDictListOptionalNget_from_dict_or_env)	BaseModel
ConfigDictmodel_validator)Literalc                	   @   st  e Zd ZU dZdZeed< dZeed< dZ	eed< dZ
ed	 ed
< dddddZeed< dZee ed< dZee ed< dZeej ed< eddZeddededefddZdededefdd Zdededefd!d"Zdededefd#d$Zdededefd%d&Zd'edee fd(d)Z d'edefd*d+Z!	d2d,ed-ededefd.d/Z"	d2d,ed-ededefd0d1Z#dS )3GoogleSerperAPIWrappera  Wrapper around the Serper.dev Google Search API.

    You can create a free API key at https://serper.dev.

    To use, you should have the environment variable ``SERPER_API_KEY``
    set with your API key, or pass `serper_api_key` as a named parameter
    to the constructor.

    Example:
        .. code-block:: python

            from langchain_community.utilities import GoogleSerperAPIWrapper
            google_serper = GoogleSerperAPIWrapper()
    
   kusglenhlsearch)newsr   placesimagestyper   r   r   Zorganic)r   r   r   r   result_key_for_typeNtbsserper_api_key
aiosessionT)Zarbitrary_types_allowedbefore)modevaluesreturnc                 C   s   t |dd}||d< |S )z,Validate that api key exists in environment.r   ZSERPER_API_KEYr   )clsr   r    r!   b/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/utilities/google_serper.pyvalidate_environment1   s
   z+GoogleSerperAPIWrapper.validate_environmentquerykwargsc                 K   s(   | j |f| j| j| j| j| jd|S )Run query through GoogleSearch.r   r   numr   search_type)_google_serper_api_resultsr   r   r   r   r   )selfr$   r%   r!   r!   r"   results<   s   zGoogleSerperAPIWrapper.resultsc                 K   s2   | j |f| j| j| j| j| jd|}| |S )z0Run query through GoogleSearch and parse result.r'   )r*   r   r   r   r   r   _parse_resultsr+   r$   r%   r,   r!   r!   r"   runH   s   

zGoogleSerperAPIWrapper.runc                    s4   | j |f| j| j| j| j| jd|I dH }|S )r&   r   r   r(   r)   r   N)#_async_google_serper_search_resultsr   r   r   r   r   r.   r!   r!   r"   aresultsV   s   	zGoogleSerperAPIWrapper.aresultsc                    s:   | j |f| j| j| j| j| jd|I dH }| |S )z6Run query through GoogleSearch and parse result async.r0   N)r1   r   r   r   r   r   r-   r.   r!   r!   r"   arunc   s   

zGoogleSerperAPIWrapper.arunr,   c              	   C   sp  g }| dr1| di }| dr| dgS | dr'| dddgS | dr1| dS | drz| di }| d}| d	}|rS|| d
| d | d}|r_|| | di  D ]\}}	|| d| d
|	 d qg|| j| j  d | j D ]%}
d|
v r||
d  |
 di  D ]\}}	|| d
|	 d qqt|dkrdgS |S )NZ	answerBoxZanswerZsnippet
 ZsnippetHighlightedZknowledgeGraphtitler   z: .description
attributesr   z&No good Google Search Result was found)getreplaceappenditemsr   r   r   len)r+   r,   ZsnippetsZ
answer_boxZkgr6   Zentity_typer8   	attributevalueresultr!   r!   r"   _parse_snippetsq   s:   









z&GoogleSerperAPIWrapper._parse_snippetsc                 C   s   d | |S )Nr5   )joinrB   )r+   r,   r!   r!   r"   r-      s   z%GoogleSerperAPIWrapper._parse_resultssearch_termr)   c                 K   sT   | j pddd}d|idd | D }tjd| ||d}|  | }|S )	N application/jsonz	X-API-KEYzContent-Typeqc                 S      i | ]\}}|d ur||qS Nr!   .0keyr@   r!   r!   r"   
<dictcomp>       zEGoogleSerperAPIWrapper._google_serper_api_results.<locals>.<dictcomp>https://google.serper.dev/)headersparams)r   r=   requestspostraise_for_statusjson)r+   rD   r)   r%   rQ   rR   responsesearch_resultsr!   r!   r"   r*      s   z1GoogleSerperAPIWrapper._google_serper_api_resultsc           
   
      s.  | j pddd}d| }d|idd | D }| jsit 4 I d H 6}|j|||dd	4 I d H }| I d H }	W d   I d H  n1 I d H sLw   Y  W d   I d H  |	S 1 I d H sbw   Y  |	S | jj|||d
d	4 I d H }| I d H }	W d   I d H  |	S 1 I d H sw   Y  |	S )NrE   rF   rG   rP   rH   c                 S   rI   rJ   r!   rK   r!   r!   r"   rN      rO   zNGoogleSerperAPIWrapper._async_google_serper_search_results.<locals>.<dictcomp>F)rR   rQ   rU   T)r   r=   r   aiohttpClientSessionrT   rV   )
r+   rD   r)   r%   rQ   urlrR   sessionrW   rX   r!   r!   r"   r1      s<   
*z:GoogleSerperAPIWrapper._async_google_serper_search_results)r   )$__name__
__module____qualname____doc__r   int__annotations__r   strr   r   r   r   dictr   r   r   r   rY   rZ   r	   Zmodel_configr
   classmethodr   r   r#   r,   r/   r2   r3   r   rB   r-   r*   r1   r!   r!   r!   r"   r      s\   
 	"
r   )r`   typingr   r   r   r   rY   rS   Zlangchain_core.utilsr   Zpydanticr   r	   r
   Ztyping_extensionsr   r   r!   r!   r!   r"   <module>   s    