Ë
    µŒjx?  ã                   ó˜   — d Z ddl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mZmZ defd„Z G d„ d	e«      Z G d
„ de«      Zy)aa  Utility for using SearxNG meta search API.

SearxNG is a privacy-friendly free metasearch engine that aggregates results from
`multiple search engines
<https://docs.searxng.org/admin/engines/configured_engines.html>`_ and databases and
supports the `OpenSearch
<https://github.com/dewitt/opensearch/blob/master/opensearch-1-1-draft-6.md>`_
specification.

More details on the installation instructions `here. <../../integrations/searx.html>`_

For the search API refer to https://docs.searxng.org/dev/search_api.html

Quick Start
-----------


In order to use this utility you need to provide the searx host. This can be done
by passing the named parameter :attr:`searx_host <SearxSearchWrapper.searx_host>`
or exporting the environment variable SEARX_HOST.
Note: this is the only required parameter.

Then create a searx search instance like this:

    .. code-block:: python

        from langchain_community.utilities import SearxSearchWrapper

        # when the host starts with `http` SSL is disabled and the connection
        # is assumed to be on a private network
        searx_host='http://self.hosted'

        search = SearxSearchWrapper(searx_host=searx_host)


You can now use the ``search`` instance to query the searx API.

Searching
---------

Use the :meth:`run() <SearxSearchWrapper.run>` and
:meth:`results() <SearxSearchWrapper.results>` methods to query the searx API.
Other methods are available for convenience.

:class:`SearxResults` is a convenience wrapper around the raw json result.

Example usage of the ``run`` method to make a search:

    .. code-block:: python

        s.run(query="what is the best search engine?")

Engine Parameters
-----------------

You can pass any `accepted searx search API
<https://docs.searxng.org/dev/search_api.html>`_ parameters to the
:py:class:`SearxSearchWrapper` instance.

In the following example we are using the
:attr:`engines <SearxSearchWrapper.engines>` and the ``language`` parameters:

    .. code-block:: python

        # assuming the searx host is set as above or exported as an env variable
        s = SearxSearchWrapper(engines=['google', 'bing'],
                            language='es')

Search Tips
-----------

Searx offers a special
`search syntax <https://docs.searxng.org/user/index.html#search-syntax>`_
that can also be used instead of passing engine parameters.

For example the following query:

    .. code-block:: python

        s = SearxSearchWrapper("langchain library", engines=['github'])

        # can also be written as:
        s = SearxSearchWrapper("langchain library !github")
        # or even:
        s = SearxSearchWrapper("langchain library !gh")


In some situations you might want to pass an extra string to the search query.
For example when the `run()` method is called by an agent. The search suffix can
also be used as a way to pass extra parameters to searx or the underlying search
engines.

    .. code-block:: python

        # select the github engine and pass the search suffix
        s = SearchWrapper("langchain library", query_suffix="!gh")


        s = SearchWrapper("langchain library")
        # select github the conventional google search syntax
        s.run("large language models", query_suffix="site:github.com")


*NOTE*: A search suffix can be defined on both the instance and the method level.
The resulting query will be the concatenation of the two with the former taking
precedence.


See `SearxNG Configured Engines
<https://docs.searxng.org/admin/engines/configured_engines.html>`_ and
`SearxNG Search Syntax <https://docs.searxng.org/user/index.html#id1>`_
for more details.

Notes
-----
This wrapper is based on the SearxNG fork https://github.com/searxng/searxng which is
better maintained than the original Searx project and offers more features.

Public searxNG instances often use a rate limiter for API usage, so you might want to
use a self hosted instance and disable the rate limiter.

If you are self-hosting an instance you can customize the rate limiter for your
own network as described
`here <https://docs.searxng.org/src/searx.botdetection.html#limiter-src>`_.


For a list of public SearxNG instances see https://searx.space/
é    N)ÚAnyÚDictÚListÚOptional)Úget_from_dict_or_env)Ú	BaseModelÚ
ConfigDictÚFieldÚPrivateAttrÚmodel_validatorÚreturnc                  ó   — dddœS )NÚenÚjson)ÚlanguageÚformat© r   ó    út/var/www/html/Fitness-lenito-AI-main/venv/lib/python3.12/site-packages/langchain_community/utilities/searx_search.pyÚ_get_default_paramsr   ‘   s   € Ø¨Ñ/Ð/r   c                   óp   ‡ — e Zd ZU dZdZeed<   defˆ fd„Zdefd„Ze	de
fd„«       Ze	de
fd	„«       Zˆ xZS )
ÚSearxResultsz,Dict like wrapper around search api results.Ú Ú_dataÚdatac                 ó\   •— t        j                  |«      }t        ‰| �  |«       | | _        y)zATake a raw result from Searx and make it into a dict like object.N)r   ÚloadsÚsuperÚ__init__Ú__dict__)Úselfr   Ú	json_dataÚ	__class__s      €r   r   zSearxResults.__init__š   s%   ø€ ä—J‘J˜tÓ$ˆ	Ü‰Ñ˜Ô#Øˆ�r   r   c                 ó   — | j                   S )z$Text representation of searx result.)r   ©r!   s    r   Ú__str__zSearxResults.__str__    s   € à�z‰zÐr   c                 ó$   — | j                  d«      S )zGSilence mypy for accessing this field.

        :meta private:
        Úresults©Úgetr%   s    r   r(   zSearxResults.results¤   s   € ð �x‰x˜	Ó"Ð"r   c                 ó$   — | j                  d«      S )z#Helper accessor on the json result.Úanswersr)   r%   s    r   r,   zSearxResults.answers¬   s   € ð �x‰x˜	Ó"Ð"r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚstrÚ__annotations__r   r&   Úpropertyr   r(   r,   Ú__classcell__)r#   s   @r   r   r   •   s]   ø… Ù6à€Eˆ3ƒOð˜Sõ ð˜ó ð ð#˜ò #ó ð#ð ð#˜ò #ó ô#r   r   c                   óL  — e Zd ZU dZ e«       Zeed<   dZe	ed<   dZ
eed<    ee¬«      Zeed<   d	Zee   ed
<   g Zeee	      ed<   g Zeee	      ed<   dZee	   ed<   dZeed<   d	Zee   ed<    ed¬«      ededefd„«       «       Z ed¬«      Zdedefd„Z dedefd„Z!	 	 	 d!de	deee	      deee	      dee	   dede	fd„Z"	 	 d"de	deee	      dee	   dede	f
d„Z#	 	 	 d!de	dedeee	      deee	      dee	   dedee   fd„Z$	 	 d"de	dedeee	      dee	   dedee   fd „Z%y	)#ÚSearxSearchWrapperaï  Wrapper for Searx API.

    To use you need to provide the searx host by passing the named parameter
    ``searx_host`` or exporting the environment variable ``SEARX_HOST``.

    In some situations you might want to disable SSL verification, for example
    if you are running searx locally. You can do this by passing the named parameter
    ``unsecure``. You can also pass the host url scheme as ``http`` to disable SSL.

    Example:
        .. code-block:: python

            from langchain_community.utilities import SearxSearchWrapper
            searx = SearxSearchWrapper(searx_host="http://localhost:8888")

    Example with SSL disabled:
        .. code-block:: python

            from langchain_community.utilities import SearxSearchWrapper
            # note the unsecure parameter is not needed if you pass the url scheme as
            # http
            searx = SearxSearchWrapper(searx_host="http://localhost:8888",
                                                    unsecure=True)


    Ú_resultr   Ú
searx_hostFÚunsecure)Údefault_factoryÚparamsNÚheadersÚenginesÚ
categoriesÚquery_suffixé
   ÚkÚ
aiosessionÚbefore)ÚmodeÚvaluesr   c                 ó”  — |j                  di «      }t        «       }i |¥|¥|d<   |j                  d«      }|rdj                  |«      |d   d<   |j                  d«      }|rdj                  |«      |d   d<   t        |dd«      }|j	                  d«      st        d|› d	�«       d
|z   }n|j	                  d«      rd|d<   ||d<   |S )z?Validate that custom searx params are merged with default ones.r;   r=   Ú,r>   r8   Ú
SEARX_HOSTÚhttpzRWarning: missing the url scheme on host                 ! assuming secure https://Ú zhttps://zhttp://Tr9   )r*   r   Újoinr   Ú
startswithÚprint)ÚclsrE   Úuser_paramsÚdefaultr=   r>   r8   s          r   Úvalidate_paramsz"SearxSearchWrapper.validate_paramsÙ   sê   € ð —j‘j ¨2Ó.ˆÜ%Ó'ˆØ5˜gÐ5¨Ð5ˆˆxÑà—*‘*˜YÓ'ˆÙØ*-¯(©(°7Ó*;ˆF�8Ñ˜YÑ'à—Z‘Z Ó-ˆ
ÙØ-0¯X©X°jÓ-AˆF�8Ñ˜\Ñ*ä)¨&°,ÀÓMˆ
Ø×$Ñ$ VÔ,Üð+Ø+5¨,°að9ôð $ jÑ0‰JØ×"Ñ" 9Ô-Ø!%ˆF�:ÑØ)ˆˆ|Ñàˆr   Úforbid)Úextrac                 óò   — t        j                  | j                  | j                  || j                   ¬«      }|j
                  st        d|j                  «      ‚t        |j                  «      }|| _	        |S )zActual request to searx API.©r<   r;   ÚverifyúSearx API returned an error: )
Úrequestsr*   r8   r<   r9   ÚokÚ
ValueErrorÚtextr   r7   )r!   r;   Ú
raw_resultÚress       r   Ú_searx_api_queryz#SearxSearchWrapper._searx_api_queryú   s`   € ä—\‘\Ø�O‰OØ—L‘LØØ—}‘}Ð$ô	
ˆ
ð �}Š}ÜÐ<¸j¿o¹oÓNÐNÜ˜:Ÿ?™?Ó+ˆØˆŒØˆ
r   c              ƒ   ó¬  K  — | j                   sÏt        j                  «       4 ƒd {  –—† }| j                  |dœ}| j                  rd|d<    |j
                  | j                  fi |¤Ž4 ƒd {  –—† }|j                  st        d|j                  «      ‚t        |j                  «       ƒ d {  –—† «      }|| _        d d d «      ƒd {  –—†  d d d «      ƒd {  –—†  S | j                   j                  | j                  | j                  || j                   ¬«      4 ƒd {  –—† }|j                  st        d|j                  «      ‚t        |j                  «       ƒ d {  –—† «      }|| _        d d d «      ƒd {  –—†  |S 7 �ŒZ7 �Œ7 ŒÚ7 ŒÁ# 1 ƒd {  –—†7  sw Y   ŒÑxY w7 ŒÈ# 1 ƒd {  –—†7  sw Y   S xY w7 Œ—7 ŒZ7 ŒA# 1 ƒd {  –—†7  sw Y   S xY w­w)N)r<   r;   FÚsslrW   rU   )rB   ÚaiohttpÚClientSessionr<   r9   r*   r8   rY   rZ   r[   r   r7   )r!   r;   ÚsessionÚkwargsÚresponseÚresults         r   Ú_asearx_api_queryz$SearxSearchWrapper._asearx_api_query	  sŽ  è ø€ Ø�ŠÜ×,Ñ,×.Ô.°'à#Ÿ|™|Ø$ñ �ð —=’=Ø$)�F˜5‘MØ&˜7Ÿ;™; t§¡ÑA¸&×AÒAÀXØ#Ÿ;š;Ü(Ð)HÈ(Ï-É-ÓXÐXÜ)°·±³×*?Ó@�FØ#)�D”L÷	 B×A÷ /×.ð0 ˆð —‘×*Ñ*Ø—‘ØŸ™ØØŸ=™=Ð(ð	 +÷ ô ð
 Ø—{’{Ü$Ð%DÀhÇmÁmÓTÐTÜ%¨H¯M©M«O×&;Ó<�Ø%�”÷÷ ð ˆð1 /ùð Bùð +@øð Bø×A×AÑAúð /ø×.×.Ð.ð0 ˆúðøð '<øðø÷ ÷ ð ð ˆüsô   ‚%G§F¨G«AF"Á-FÁ.F"Á1;FÂ,FÂ-FÂ<F"ÃF	ÃF"ÃGÃF ÃAGÄ F8Ä!GÄ$;F>ÅF:
Å F>Å/GÅ:F<Å;GÆF"ÆFÆ	F"ÆF	ÆFÆF	ÆF"Æ GÆ"F5Æ(F+Æ)F5Æ0	GÆ:F>Æ<GÆ>GÇGÇGÇGÚqueryrd   c           	      ó  — d|i}i | j                   ¥|¥|¥}| j                  r2t        | j                  «      dkD  r|dxx   d| j                  z   z  cc<   t        |t        «      rt        |«      dkD  r|dxx   d|z   z  cc<   t        |t
        «      r"t        |«      dkD  rdj                  |«      |d<   t        |t
        «      r"t        |«      dkD  rdj                  |«      |d<   | j                  |«      }t        |j                  «      dkD  r|j                  d   }	|	S t        |j                  «      dkD  rHdj                  |j                  d| j                   D �
cg c]  }
|
j                  d	d
«      ‘Œ c}
«      }	|	S d}	|	S c c}
w )ao  Run query through Searx API and parse results.

        You can pass any other params to the searx query API.

        Args:
            query: The query to search for.
            query_suffix: Extra suffix appended to the query.
            engines: List of engines to use for the query.
            categories: List of categories to use for the query.
            **kwargs: extra parameters to pass to the searx API.

        Returns:
            str: The result of the query.

        Raises:
            ValueError: If an error occurred with the query.


        Example:
            This will make a query to the qwant engine:

            .. code-block:: python

                from langchain_community.utilities import SearxSearchWrapper
                searx = SearxSearchWrapper(searx_host="http://my.searx.host")
                searx.run("what is the weather in France ?", engine="qwant")

                # the same result can be achieved using the `!` syntax of searx
                # to select the engine using `query_suffix`
                searx.run("what is the weather in France ?", query_suffix="!qwant")
        Úqr   rJ   rG   r=   r>   ú

NÚcontentr   úNo good search result found)r;   r?   ÚlenÚ
isinstancer1   ÚlistrK   r^   r,   r(   rA   r*   )r!   rh   r=   r>   r?   rd   Ú_paramsr;   r]   ÚtoretÚrs              r   ÚrunzSearxSearchWrapper.run%  sr  € ðP �ð
ˆð 6�D—K‘KÐ5 7Ð5¨fÐ5ˆà×Ò¤ T×%6Ñ%6Ó!7¸!Ò!;Ø�3‹K˜3 ×!2Ñ!2Ñ2Ñ2‹Kä�l¤CÔ(¬S°Ó->ÀÒ-BØ�3‹K˜3 Ñ-Ñ-‹Kä�gœtÔ$¬¨W«¸Ò)9Ø #§¡¨Ó 1ˆF�9Ñä�j¤$Ô'¬C°
«O¸aÒ,?Ø#&§8¡8¨JÓ#7ˆF�<Ñ à×#Ñ# FÓ+ˆäˆs�{‰{Ó˜aÒØ—K‘K ‘NˆEð ˆô �—‘Ó Ò!Ø—K‘K¸s¿{¹{È8ÈTÏVÉVÑ?TÓ UÑ?T¸! §¡ y°"Õ!5Ð?TÑ UÓVˆEð ˆð 2ˆEàˆùò	 !Vs   ÅFc           	   ‹   óÌ  K  — d|i}i | j                   ¥|¥|¥}| j                  r2t        | j                  «      dkD  r|dxx   d| j                  z   z  cc<   t        |t        «      rt        |«      dkD  r|dxx   d|z   z  cc<   t        |t
        «      r"t        |«      dkD  rdj                  |«      |d<   | j                  |«      ƒ d{  –—† }t        |j                  «      dkD  r|j                  d   }|S t        |j                  «      dkD  rHdj                  |j                  d| j                   D �	cg c]  }	|	j                  dd	«      ‘Œ c}	«      }|S d
}|S 7 Œ‘c c}	w ­w)z Asynchronously version of `run`.rj   r   rJ   rG   r=   Nrk   rl   r   rm   )r;   r?   rn   ro   r1   rp   rK   rg   r,   r(   rA   r*   )
r!   rh   r=   r?   rd   rq   r;   r]   rr   rs   s
             r   ÚarunzSearxSearchWrapper.arunj  sU  è ø€ ð �ð
ˆð 6�D—K‘KÐ5 7Ð5¨fÐ5ˆà×Ò¤ T×%6Ñ%6Ó!7¸!Ò!;Ø�3‹K˜3 ×!2Ñ!2Ñ2Ñ2‹Kä�l¤CÔ(¬S°Ó->ÀÒ-BØ�3‹K˜3 Ñ-Ñ-‹Kä�gœtÔ$¬¨W«¸Ò)9Ø #§¡¨Ó 1ˆF�9Ñà×*Ñ*¨6Ó2×2ˆäˆs�{‰{Ó˜aÒØ—K‘K ‘NˆEð ˆô �—‘Ó Ò!Ø—K‘K¸s¿{¹{È8ÈTÏVÉVÑ?TÓ UÑ?T¸! §¡ y°"Õ!5Ð?TÑ UÓVˆEð ˆð 2ˆEàˆð 3úò !Vùs%   ‚C	E$ÃEÃA+E$Ä7EÅE$ÅE$Únum_resultsc           	      óž  — d|i}i | j                   ¥|¥|¥}| j                  r2t        | j                  «      dkD  r|dxx   d| j                  z   z  cc<   t        |t        «      rt        |«      dkD  r|dxx   d|z   z  cc<   t        |t
        «      r"t        |«      dkD  rdj                  |«      |d<   t        |t
        «      r"t        |«      dkD  rdj                  |«      |d<   | j                  |«      j                  d| }	t        |	«      dk(  rdd	igS |	D �
cg c]&  }
|
j                  d
d«      |
d   |
d   |
d   |
d   dœ‘Œ( c}
S c c}
w )a$  Run query through Searx API and returns the results with metadata.

        Args:
            query: The query to search for.
            query_suffix: Extra suffix appended to the query.
            num_results: Limit the number of results to return.
            engines: List of engines to use for the query.
            categories: List of categories to use for the query.
            **kwargs: extra parameters to pass to the searx API.

        Returns:
            Dict with the following keys:
            {
                snippet:  The description of the result.
                title:  The title of the result.
                link: The link to the result.
                engines: The engines used for the result.
                category: Searx category of the result.
            }

        rj   r   rJ   rG   r=   r>   NÚResultúNo good Search Result was foundrl   r   ÚtitleÚurlÚcategory©Úsnippetr{   Úlinkr=   r}   )
r;   r?   rn   ro   r1   rp   rK   r^   r(   r*   )r!   rh   rw   r=   r>   r?   rd   rq   r;   r(   rf   s              r   r(   zSearxSearchWrapper.results�  sh  € ð> �ð
ˆð 6�D—K‘KÐ5 7Ð5¨fÐ5ˆØ×Ò¤ T×%6Ñ%6Ó!7¸!Ò!;Ø�3‹K˜3 ×!2Ñ!2Ñ2Ñ2‹KÜ�l¤CÔ(¬S°Ó->ÀÒ-BØ�3‹K˜3 Ñ-Ñ-‹KÜ�gœtÔ$¬¨W«¸Ò)9Ø #§¡¨Ó 1ˆF�9ÑÜ�j¤$Ô'¬C°
«O¸aÒ,?Ø#&§8¡8¨JÓ#7ˆF�<Ñ Ø×'Ñ'¨Ó/×7Ñ7¸¸ÐEˆÜˆw‹<˜1ÒØÐ@ÐAÐBÐBñ "ó	
ñ "�ð "Ÿ:™: i°Ó4Ø ™Ø˜u™Ø! )Ñ,Ø" :Ñ.óð "ñ	
ð 		
ùò 	
s   Ä+E
c           	   ‹   óV  K  — d|i}i | j                   ¥|¥|¥}| j                  r2t        | j                  «      dkD  r|dxx   d| j                  z   z  cc<   t        |t        «      rt        |«      dkD  r|dxx   d|z   z  cc<   t        |t
        «      r"t        |«      dkD  rdj                  |«      |d<   | j                  |«      ƒ d{  –—† j                  d| }t        |«      dk(  rddigS |D �	cg c]&  }	|	j                  d	d
«      |	d   |	d   |	d   |	d   dœ‘Œ( c}	S 7 ŒVc c}	w ­w)zdAsynchronously query with json results.

        Uses aiohttp. See `results` for more info.
        rj   r   rJ   rG   r=   Nry   rz   rl   r   r{   r|   r}   r~   )
r;   r?   rn   ro   r1   rp   rK   rg   r(   r*   )
r!   rh   rw   r=   r?   rd   rq   r;   r(   rf   s
             r   ÚaresultszSearxSearchWrapper.aresultsÆ  sL  è ø€ ð �ð
ˆð 6�D—K‘KÐ5 7Ð5¨fÐ5ˆà×Ò¤ T×%6Ñ%6Ó!7¸!Ò!;Ø�3‹K˜3 ×!2Ñ!2Ñ2Ñ2‹KÜ�l¤CÔ(¬S°Ó->ÀÒ-BØ�3‹K˜3 Ñ-Ñ-‹KÜ�gœtÔ$¬¨W«¸Ò)9Ø #§¡¨Ó 1ˆF�9ÑØ×/Ñ/°Ó7×7×@Ñ@ÀÀ+ÐNˆÜˆw‹<˜1ÒØÐ@ÐAÐBÐBñ "ó	
ñ "�ð "Ÿ:™: i°Ó4Ø ™Ø˜u™Ø! )Ñ,Ø" :Ñ.óð "ñ	
ð 		
ð	 8úò	
ùs$   ‚C	D)ÃD"Ã(D)Ã4+D$ÄD)Ä$D))NNr   )Nr   )&r-   r.   r/   r0   r   r7   r   r2   r8   r1   r9   Úboolr
   r   r;   Údictr<   r   r=   r   r>   r?   rA   ÚintrB   r   r   Úclassmethodr   rQ   r	   Úmodel_configr^   rg   rt   rv   r(   r‚   r   r   r   r6   r6   ²   sn  … ññ6 (›M€Gˆ\Ó)Ø€J�ÓØ€HˆdÓÙÐ)<Ô=€FˆDÓ=Ø"€GˆX�d‰^Ó"Ø#%€GˆX�d˜3‘iÑ Ó%Ø&(€J�˜˜c™Ñ#Ó(Ø"$€L�(˜3‘-Ó$Ø€A€sƒKØ $€J�˜‘Ó$á˜(Ô#Øð Tð ¨cò ó ó $ðñ6 Øô€Lð tð °ó ð¨dð °|ó ð> (,Ø*.Ø&(ñCàðCð ˜$˜s™)Ñ$ðCð ˜T #™YÑ'ð	Cð
 ˜s‘mðCð ðCð 
óCðP (,Ø&(ñ	!àð!ð ˜$˜s™)Ñ$ð!ð ˜s‘mð	!ð
 ð!ð 
ó!ðN (,Ø*.Ø&(ñ7
àð7
ð ð7
ð ˜$˜s™)Ñ$ð	7
ð
 ˜T #™YÑ'ð7
ð ˜s‘mð7
ð ð7
ð 
ˆd‰ó7
ðz (,Ø&(ñ$
àð$
ð ð$
ð ˜$˜s™)Ñ$ð	$
ð
 ˜s‘mð$
ð ð$
ð 
ˆd‰ô$
r   r6   )r0   r   Útypingr   r   r   r   ra   rX   Úlangchain_core.utilsr   Úpydanticr   r	   r
   r   r   r„   r   r   r6   r   r   r   Ú<module>r‹      sP   ðñóB ß ,Ó ,ã Û Ý 5÷õ ð0˜Tó 0ô#�4ô #ô:x
˜õ x
r   