U
    h&(                     @   s   d Z ddlZddlmZ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 dZG dd	 d	eZG d
d deZG dd deZG dd deZG dd deZdS )zUtil that calls you.com Search API.

In order to set this up, follow instructions at:
https://documentation.you.com/quickstart
    N)AnyDictListLiteralOptionalDocument)	BaseModelFieldroot_validatorget_from_dict_or_envzhttps://api.ydc-index.ioc                   @   sZ   e Zd ZU dZeddZeed< eddZeed< eddZ	eed< ed	dZ
eed
< dS )YouHitMetadataz%Metadata on a single hit from you.comzThe title of the resultdescriptiontitlezThe url of the resulturlz$Thumbnail associated with the resultthumbnail_urlzDetails about the resultr   N)__name__
__module____qualname____doc__r
   r   str__annotations__r   r   r    r   r   E/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/utilities/you.pyr      s
   
r   c                   @   s(   e Zd ZU dZeddZee ed< dS )YouHitz>A single hit from you.com, which may contain multiple snippetszOne or snippets of textr   snippetsN)	r   r   r   r   r
   r   r   r   r   r   r   r   r   r      s   
r   c                   @   s(   e Zd ZU dZeddZee ed< dS )YouAPIOutputzOutput from you.com API.z-A list of dictionaries containing the resultsr   hitsN)	r   r   r   r   r
   r   r   r   r   r   r   r   r   r   "   s   
r   c                   @   s,   e Zd ZU dZeddZeed< eed< dS )YouDocumentzOutput of parsing one snippet.zOne snippet of textr   page_contentmetadataN)	r   r   r   r   r
   r!   r   r   r   r   r   r   r   r    *   s   
r    c                   @   s  e Zd ZU dZdZee ed< dZe	d ed< dZ
ee ed< dZee	d  ed	< dZee ed
< dZee ed< dZee ed< dZee ed< dZee ed< dZee ed< dZee ed< eddeedddZedddeedddZed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e dd$d%Z eeedd&d'Z!eeee dd(d)Z"dS )*YouSearchAPIWrapperaf  Wrapper for you.com Search and News API.

    To connect to the You.com api requires an API key which
    you can get at https://api.you.com.
    You can check out the docs at https://documentation.you.com/api-reference/.

    You need to set the environment variable `YDC_API_KEY` for retriever to operate.

    Attributes
    ----------
    ydc_api_key: str, optional
        you.com api key, if YDC_API_KEY is not set in the environment
    endpoint_type: str, optional
        you.com endpoints: search, news, rag;
        `web` and `snippet` alias `search`
        `rag` returns `{'message': 'Forbidden'}`
        @todo `news` endpoint
    num_web_results: int, optional
        The max number of web results to return, must be under 20.
        This is mapped to the `count` query parameter for the News API.
    safesearch: str, optional
        Safesearch settings, one of off, moderate, strict, defaults to moderate
    country: str, optional
        Country code, ex: 'US' for United States, see api docs for list
    search_lang: str, optional
        (News API) Language codes, ex: 'en' for English, see api docs for list
    ui_lang: str, optional
        (News API) User interface language for the response, ex: 'en' for English,
                   see api docs for list
    spellcheck: bool, optional
        (News API) Whether to spell check query or not, defaults to True
    k: int, optional
        max number of Documents to return using `results()`
    n_hits: int, optional, deprecated
        Alias for num_web_results
    n_snippets_per_hit: int, optional
        limit the number of snippets returned per hit
    Nydc_api_keysearch)r%   newsZragsnippetendpoint_typenum_web_results)offZmoderatestrict
safesearchcountrysearch_langui_lang
spellcheckkn_snippets_per_hitn_hitsT)pre)valuesreturnc                 C   s   t |dd}||d< |S )z,Validate that api key exists in environment.r$   ZYDC_API_KEYr   )clsr5   r$   r   r   r   validate_environmentm   s    z(YouSearchAPIWrapper.validate_environmentF)r4   Zskip_on_failurec                 C   sd   |d dkr@d}|D ]*}|| rt d| d|d  dt q|d dkr`|d r`t d	t |S )
Nr(   r&   )r.   r/   r0   zNews API-specific field 'z' is set but `endpoint_type="z"`. This will have no effect.r%   r'   r2   zGField 'n_snippets_per_hit' only has effect on `endpoint_type="search"`.)warningswarnUserWarning)r7   r5   Znews_api_fieldsfieldr   r   r   !warn_if_set_fields_have_no_effectu   s    z5YouSearchAPIWrapper.warn_if_set_fields_have_no_effectc                 C   s(   |d dkr$t d|d  dt |S )Nr(   r   z`endpoint_type="z7"` is deprecated. Use `endpoint_type="search"` instead.)r:   r;   DeprecationWarning)r7   r5   r   r   r   %warn_if_deprecated_endpoints_are_used   s    z9YouSearchAPIWrapper.warn_if_deprecated_endpoints_are_used)querykwargsr6   c                 K   sj   | j | jd|}| jdkr.|j|| jd n&| jdkrT|j|| j| j| j| jd dd | D }|S )z
        Parse parameters required for different You.com APIs.

        Args:
            query: The query to search for.
        )r,   r-   r9   )rA   r)   r&   )qcountr.   r/   r0   c                 S   s   i | ]\}}|d k	r||qS Nr   ).0r1   vr   r   r   
<dictcomp>   s       z8YouSearchAPIWrapper._generate_params.<locals>.<dictcomp>)	r,   r-   r(   updater)   r.   r/   r0   items)selfrA   rB   paramsr   r   r   _generate_params   s(    

z$YouSearchAPIWrapper._generate_params)raw_search_resultsr6   c                 C   s   | j dkr<|d d }| jdk	r.|d| j }dd |D S g }|d D ]}| jp^t|d}|dd| D ]\}|t||d|d	|d
|ddd | jdk	rrt|| jkrr|    S qrqH|S )z
        Extracts snippets from each hit and puts them in a Document
        Parameters:
            raw_search_results: A dict containing list of hits
        Returns:
            List[YouDocument]: A dictionary of parsed results
        r&   resultsNc                 S   s   g | ]}t |d  |dqS )r   r!   r"   r   )rF   resultr   r   r   
<listcomp>   s   z6YouSearchAPIWrapper._parse_results.<locals>.<listcomp>r   r   r   r   r   r   )r   r   r   r   rP   )r(   r1   r2   lengetappendr   )rK   rN   Znews_resultsZdocshitr2   r'   r   r   r   _parse_results   s0    


z"YouSearchAPIWrapper._parse_resultsc                 K   sX   d| j p
di}| j|f|}| jdkr,d| _tjt d| j ||d}|  | S )zRun query through you.com Search and return hits.

        Args:
            query: The query to search for.
        Returns: YouAPIOutput
        	X-API-Key r'   r%   /)rL   headers)r$   rM   r(   requestsrT   YOU_API_URLraise_for_statusjson)rK   rA   rB   r[   rL   responser   r   r   raw_results   s    
zYouSearchAPIWrapper.raw_resultsc                 K   s&   | j |fdd | D }| |S )zCRun query through you.com Search and parses results into Documents.c                 S   s   i | ]\}}|d k	r||qS rE   r   rF   keyvaluer   r   r   rH     s       z/YouSearchAPIWrapper.results.<locals>.<dictcomp>)ra   rJ   rW   )rK   rA   rB   rN   r   r   r   rO      s    zYouSearchAPIWrapper.resultsc                    s   d| j p
di}| j|f|}| jdkr,d| _t 4 I dH }|jt d| j ||d4 I dH ^}|jdkr| I dH }|W  5 Q I dH R  W  5 Q I dH R  S t	d	|j d
|j
 W 5 Q I dH R X W 5 Q I dH R X dS )z7Get results from the you.com Search API asynchronously.rX   rY   r'   r%   NrZ   )r   rL   r[      zError z: )r$   rM   r(   aiohttpZClientSessionrT   r]   statusr_   	Exceptionreason)rK   rA   rB   r[   rL   sessionresrO   r   r   r   raw_results_async  s    

(z%YouSearchAPIWrapper.raw_results_asyncc                    s,   | j |fdd | D I d H }| |S )Nc                 S   s   i | ]\}}|d k	r||qS rE   r   rb   r   r   r   rH   '  s       z5YouSearchAPIWrapper.results_async.<locals>.<dictcomp>)rl   rJ   rW   )rK   rA   rB   Zraw_search_results_asyncr   r   r   results_async   s    
z!YouSearchAPIWrapper.results_async)#r   r   r   r   r$   r   r   r   r(   r   r)   intr,   r-   r.   r/   r0   boolr1   r2   r3   r   r   r8   r>   r@   r   rM   r   r   rW   ra   rO   rl   rm   r   r   r   r   r#   1   sH   
'

(r#   )r   r:   typingr   r   r   r   r   rf   r\   Zlangchain_core.documentsr   Zlangchain_core.pydantic_v1r	   r
   r   Zlangchain_core.utilsr   r]   r   r   r   r    r#   r   r   r   r   <module>   s   	