U
    h9                     @   sh   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	m
Z
 ddl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)	BaseModelroot_validatorget_from_dict_or_env)Literalc                   @   sF  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dZee ed< dZee ed< dZeej ed< G dd dZeddeedddZeeedddZeeedddZeeedd d!Zeeedd"d#Zeee d$d%d&Zeed$d'd(Zd.eeeed)d*d+Z d/eeeed)d,d-Z!dS )0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   Ntbsserper_api_key
aiosessionc                   @   s   e Zd ZdZdS )zGoogleSerperAPIWrapper.ConfigTN)__name__
__module____qualname__Zarbitrary_types_allowed r   r   O/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/utilities/google_serper.pyConfig-   s   r   T)pre)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   r   r   validate_environment0   s      z+GoogleSerperAPIWrapper.validate_environment)querykwargsr"   c                 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   runF   s    
zGoogleSerperAPIWrapper.runc                    s2   | 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   aresultsT   s    	zGoogleSerperAPIWrapper.aresultsc                    s8   | j |f| j| j| j| j| jd|I dH }| |S )z6Run query through GoogleSearch and parse result async.r1   N)r2   r   r   r   r   r   r.   r/   r   r   r   aruna   s    
zGoogleSerperAPIWrapper.arun)r-   r"   c              	   C   sx  g }| drb| di }| dr0| dgS | drN| dddgS | drb| dS | dr| di }| d}| d	}|r|| d
| d | d}|r|| | di  D ]$\}}	|| d| d
|	 d q|| j| j  d | j D ]P}
d|
kr*||
d  |
 di  D ] \}}	|| d
|	 d q:qt|dkrtd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itemsresult_key_for_typer   r   len)r,   r-   ZsnippetsZ
answer_boxZkgr7   Zentity_typer9   	attributevalueresultr   r   r   _parse_snippetso   s8    










z&GoogleSerperAPIWrapper._parse_snippetsc                 C   s   d | |S )Nr6   )joinrD   )r,   r-   r   r   r   r.      s    z%GoogleSerperAPIWrapper._parse_results)search_termr*   r&   r"   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   s   i | ]\}}|d k	r||qS Nr   .0keyrB   r   r   r   
<dictcomp>   s       zEGoogleSerperAPIWrapper._google_serper_api_results.<locals>.<dictcomp>https://google.serper.dev/)headersparams)r   r>   requestspostraise_for_statusjson)r,   rF   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st 4 I d H @}|j|||dd	4 I d H }| I d H }	W 5 Q I d H R X W 5 Q I d H R X n<| jj|||d
d	4 I d H }| I d H }	W 5 Q I d H R X |	S )NrG   rH   rI   rP   rJ   c                 S   s   i | ]\}}|d k	r||qS rK   r   rL   r   r   r   rO      s       zNGoogleSerperAPIWrapper._async_google_serper_search_results.<locals>.<dictcomp>F)rR   rQ   rU   T)r   r>   r   aiohttpClientSessionrT   rV   )
r,   rF   r*   r&   rQ   urlrR   sessionrW   rX   r   r   r   r2      s8    
    0   z:GoogleSerperAPIWrapper._async_google_serper_search_results)r   )r   )"r   r   r   __doc__r   int__annotations__r   strr   r   r
   r?   r   r   r   r   rY   rZ   r   r   r   r$   r   r-   r0   r3   r4   dictr   rD   r.   r+   r2   r   r   r   r   r      sH   
	"      r   )r]   typingr   r   r   r   rY   rS   Zlangchain_core.pydantic_v1r   r   Zlangchain_core.utilsr	   Ztyping_extensionsr
   r   r   r   r   r   <module>   s   