o
    ȳgb                     @   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   organic)r   r   r   r   result_key_for_typeNtbsserper_api_key
aiosessionT)arbitrary_types_allowedbefore)modevaluesreturnc                 C   s   t |dd}||d< |S )z,Validate that api key exists in environment.r   SERPER_API_KEYr   )clsr    r    r$   g/var/www/html/chatdoc2/venv/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   r1   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.r3   N)r4   r   r   r   r   r   r0   r1   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 )N	answerBoxanswersnippet
 snippetHighlightedknowledgeGraphtitler   z: .description
attributesr   z&No good Google Search Result was found)getreplaceappenditemsr   r   r   len)r.   r/   snippets
answer_boxkgr>   entity_typer@   	attributevalueresultr$   r$   r%   _parse_snippetsq   s:   









z&GoogleSerperAPIWrapper._parse_snippetsc                 C   s   d | |S )Nr;   )joinrN   )r.   r/   r$   r$   r%   r0      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keyrL   r$   r$   r%   
<dictcomp>       zEGoogleSerperAPIWrapper._google_serper_api_results.<locals>.<dictcomp>https://google.serper.dev/)headersparams)r   rE   requestspostraise_for_statusjson)r.   rP   r,   r(   r]   r^   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 )NrQ   rR   rS   r\   rT   c                 S   rU   rV   r$   rW   r$   r$   r%   rZ      r[   zNGoogleSerperAPIWrapper._async_google_serper_search_results.<locals>.<dictcomp>F)r^   r]   ra   T)r   rE   r   aiohttpClientSessionr`   rb   )
r.   rP   r,   r(   r]   urlr^   sessionrc   rd   r$   r$   r%   r4      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   re   rf   r	   model_configr
   classmethodr   r   r&   r/   r2   r5   r6   r   rN   r0   r-   r4   r$   r$   r$   r%   r      s\   
 	"
r   )rl   typingr   r   r   r   re   r_   langchain_core.utilsr   pydanticr   r	   r
   typing_extensionsr   r   r$   r$   r$   r%   <module>   s    