o
    Zh!                     @   sz   d Z ddlZddlZddlmZmZmZmZ ddlZddl	m
Z
 ddlmZmZmZmZ G dd dZG dd	 d	eZdS )
zWChain that calls SerpAPI.

Heavily borrowed from https://github.com/ofirpress/self-ask
    N)AnyDictOptionalTuple)get_from_dict_or_env)	BaseModel
ConfigDictFieldmodel_validatorc                   @   s,   e Zd ZdZd	ddZdeddfddZdS )
HiddenPrintszContext manager to hide prints.returnNc                 C   s   t j| _ttjdt _dS )zOpen file to pipe stdout to.wN)sysstdout_original_stdoutopenosdevnull)self r   \/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/utilities/serpapi.py	__enter__   s   zHiddenPrints.__enter___c                 G   s   t j  | jt _dS )z$Close file that stdout was piped to.N)r   r   closer   )r   r   r   r   r   __exit__   s   
zHiddenPrints.__exit__)r   N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r      s    
r   c                   @   s  e Zd ZU dZdZeed< edddddd	Ze	ed
< dZ
ee ed< dZeej ed< ed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	fddZdede	fddZdedeeef fd d!Zed"e	defd#d$ZdS )%SerpAPIWrappera  Wrapper around SerpAPI.

    To use, you should have the ``google-search-results`` python package installed,
    and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass
    `serpapi_api_key` as a named parameter to the constructor.

    Example:
        .. code-block:: python

            from langchain_community.utilities import SerpAPIWrapper
            serpapi = SerpAPIWrapper()
    Nsearch_enginegooglez
google.comusen)ZengineZgoogle_domainglZhl)defaultparamsserpapi_api_key
aiosessionTZforbid)Zarbitrary_types_allowedextrabefore)modevaluesr   c                 C   sF   t |dd}||d< zddlm} ||d< W |S  ty"   tdw )z?Validate that api key and python package exists in environment.r'   ZSERPAPI_API_KEYr   )GoogleSearchr    zdCould not import serpapi python package. Please install it with `pip install google-search-results`.)r   Zserpapir-   ImportError)clsr,   r'   r-   r   r   r   validate_environment<   s   
z#SerpAPIWrapper.validate_environmentquerykwargsc                    s   |  | |I dH S )z1Run query through SerpAPI and parse result async.N)_process_responsearesultsr   r1   r2   r   r   r   arunO   s   zSerpAPIWrapper.arunc                 K   s   |  | |S )z+Run query through SerpAPI and parse result.)r3   resultsr5   r   r   r   runS   s   zSerpAPIWrapper.runc                 C   sH   |  |}t  | |}| }W d   |S 1 sw   Y  |S )z4Run query through SerpAPI and return the raw result.N)
get_paramsr   r    get_dict)r   r1   r&   searchresr   r   r   r7   W   s   



zSerpAPIWrapper.resultsc              
      s   dt ttttf f f fdd}| \}}jsdt 4 I dH 4}|j||d4 I dH }| I dH }W d  I dH  n1 I dH sGw   Y  W d  I dH  |S 1 I dH s]w   Y  |S jj||d4 I dH }| I dH }W d  I dH  |S 1 I dH sw   Y  |S )zFUse aiohttp to run query through SerpAPI and return the results async.r   c                     s6     } d| d< jrj| d< d| d< d}|| fS )NpythonsourceZserp_api_keyjsonoutputzhttps://serpapi.com/search)r9   r'   )r&   urlr1   r   r   r   construct_url_and_paramsb   s   

z9SerpAPIWrapper.aresults.<locals>.construct_url_and_paramsN)r&   )r   strr   r(   aiohttpClientSessiongetr?   )r   r1   rC   rA   r&   sessionresponser<   r   rB   r   r4   _   s$   $
	*zSerpAPIWrapper.aresultsc                 C   s   | j |d}i | j|}|S )zGet parameters for SerpAPI.)Zapi_keyq)r'   r&   )r   r1   _paramsr&   r   r   r   r9   v   s
   zSerpAPIWrapper.get_paramsr<   c           	   	   C   s^  d|   v rtd| d  d|   v r| d | d< d|   v rz| d }t|tr.|d }d|  v r8|d S d|  v rB|d S d|  v rL|d S d	|  v rV|d	 S i }| D ]\}}t|ttfsut|trq|d
su|||< q\t|S d|   v r| d dd S d|   v r| d S d|   v r| d S d|   v r| d S d|   v rd| d   v r| d d S d|   v rd| d d   v r| d dd S d|   v r| d S d|   v rd| d   v r| d d S d|   v rd| d   v r| d d S d|   v r'd| d d   v r'tdd | d dd D S g }d|   v r| d }d|v r=|d nd }d!|  v rM||d!  | D ]6\}}t|trt|tr|d"vr|	d#s|	d$s|d
s|| d%| d&| d' qQ| 
d(g D ]Q}d|  v r||d  qd	|  v r||d	  qd)|  v r||d)  qd*|  v r||d*  qd+|  v r||d+  qd,|   v r|| d,  d-| v rt| d- tr|| d- 7 }d-|   v r"t| d- tr"d.| d-   v r"|| d- d.  t|dkr-t|S d/S )0zProcess response from SerpAPI.errorzGot error from SerpAPI: Zanswer_box_list
answer_boxr   resultanswerZsnippetZsnippet_highlighted_wordshttpZevents_resultsN
   Zsports_resultsZtop_storiesZnews_resultsZjobs_resultsjobsZshopping_resultstitle   Zquestions_and_answersZpopular_destinationsdestinationsZ
top_sightsZsightsZimages_results	thumbnailc                 S   s   g | ]}|d  qS )rV   r   ).0itemr   r   r   
<listcomp>   s    z4SerpAPIWrapper._process_response.<locals>.<listcomp>knowledge_graph description)rS   r\   Z_stick_link z: .Zorganic_resultsZrich_snippetZrich_snippet_tablelinkZbuying_guideZlocal_resultsZplaceszNo good search result found)keys
ValueError
isinstancelistitemsdictrD   
startswithappendendswithrG   len)	r<   rM   rO   keyvalueZsnippetsrZ   rS   Zorganic_resultr   r   r   r3      s   
 
z SerpAPIWrapper._process_response)r   r   r   r   r    r   __annotations__r	   r&   rf   r'   r   rD   r(   rE   rF   r   Zmodel_configr
   classmethodr   r0   r6   r8   r7   r4   r9   staticmethodr3   r   r   r   r   r      s4   
 	r   )r   r   r   typingr   r   r   r   rE   Zlangchain_core.utilsr   Zpydanticr   r   r	   r
   r   r   r   r   r   r   <module>   s    