o
    ȳg!                     @   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   a/var/www/html/chatdoc2/venv/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)enginegoogle_domainglhl)defaultparamsserpapi_api_key
aiosessionTforbid)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*   SERPAPI_API_KEYr   )GoogleSearchr    zdCould not import serpapi python package. Please install it with `pip install google-search-results`.)r   serpapir3   ImportError)clsr1   r*   r3   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   r8   r9   r   r   r   arunO   s   zSerpAPIWrapper.arunc                 K   s   |  | |S )z+Run query through SerpAPI and parse result.)r:   resultsr<   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   r8   r)   searchresr   r   r   r>   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sourceserp_api_keyjsonoutputzhttps://serpapi.com/search)r@   r*   )r)   urlr8   r   r   r   construct_url_and_paramsb   s   

z9SerpAPIWrapper.aresults.<locals>.construct_url_and_paramsN)r)   )r   strr   r+   aiohttpClientSessiongetrG   )r   r8   rK   rI   r)   sessionresponserC   r   rJ   r   r;   _   s$   $
	*zSerpAPIWrapper.aresultsc                 C   s   | j |d}i | j|}|S )zGet parameters for SerpAPI.)api_keyq)r*   r)   )r   r8   _paramsr)   r   r   r   r@   v   s
   zSerpAPIWrapper.get_paramsrC   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: answer_box_list
answer_boxr   resultanswersnippetsnippet_highlighted_wordshttpevents_resultsN
   sports_resultstop_storiesnews_resultsjobs_resultsjobsshopping_resultstitle   questions_and_answerspopular_destinationsdestinations
top_sightssightsimages_results	thumbnailc                 S   s   g | ]}|d  qS )rm   r   ).0itemr   r   r   
<listcomp>   s    z4SerpAPIWrapper._process_response.<locals>.<listcomp>knowledge_graph description)re   rs   _stick_link z: .organic_resultsrich_snippetrich_snippet_tablelinkbuying_guidelocal_resultsplaceszNo good search result found)keys
ValueError
isinstancelistitemsdictrL   
startswithappendendswithrO   len)	rC   rW   rY   keyvaluesnippetsrq   re   organic_resultr   r   r   r:      s   
 
z SerpAPIWrapper._process_response)r   r   r   r   r    r   __annotations__r	   r)   r   r*   r   rL   r+   rM   rN   r   model_configr
   classmethodr   r7   r=   r?   r>   r;   r@   staticmethodr:   r   r   r   r   r      s4   
 	r   )r   r   r   typingr   r   r   r   rM   langchain_core.utilsr   pydanticr   r   r	   r
   r   r   r   r   r   r   <module>   s    