o
    ưi!                     @   s   d Z ddlmZ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 ddlmZ G dd deZG d	d
 d
eddZG dd deZdS )zz
Calls SearXNG's /search endpoint to search the web.

SearXNG API Reference: https://docs.searxng.org/dev/search_api.html
    )DictListOptional	TypedDictUnionN)Logging)BaseSearchConfigSearchResponseSearchResultget_secret_strc                   @   s   e Zd ZU dZeed< dS )_SearXNGSearchRequestRequiredz/Required fields for SearXNG Search API request.qN)__name__
__module____qualname____doc__str__annotations__ r   r   a/home/app/Keep/.python/lib/python3.10/site-packages/litellm/llms/searxng/search/transformation.pyr      s   
 r   c                   @   sB   e Zd ZU dZeed< eed< eed< eed< eed< eed< dS )	SearXNGSearchRequestzg
    SearXNG Search API request format.
    Based on: https://docs.searxng.org/dev/search_api.html
    
categoriesZengineslanguageZpagenoZ
time_rangeformatN)r   r   r   r   r   r   intr   r   r   r   r      s   
 r   F)totalc                   @   s   e Zd ZedefddZdd Z		ddedee d	ee defd
dZ		dd	ee de
deeeee f  defddZdeeee f de
defddZdejdedefddZdS )SearXNGSearchConfigreturnc                   C      dS )NZSearXNGr   r   r   r   r   ui_friendly_name'   s   z$SearXNGSearchConfig.ui_friendly_namec                 C   r   )zW
        SearXNG supports both GET and POST, but we'll use GET for simplicity.
        GETr   )selfr   r   r   get_http_method+   s   z#SearXNGSearchConfig.get_http_methodNheadersapi_keyapi_basec                 K   s*   |pt d}|rd| |d< d|d< |S )z
        Validate environment and return headers.
        SearXNG is open-source and doesn't require an API key by default.
        Some instances may require authentication via headers.
        ZSEARXNG_API_KEYzBearer Authorizationzapplication/jsonzContent-Typer   )r"   r$   r%   r&   kwargsr   r   r   validate_environment1   s
   z(SearXNGSearchConfig.validate_environmentoptional_paramsdatac                 K   s   ddl m} |ptd}|std|ds'|dr"| d}n| d}|rAt|trAd|v rA|d }||}| d	| S |S )
a  
        Get complete URL for Search endpoint with query parameters.
        
        SearXNG uses GET requests, so we build the full URL with query params here.
        The transformed request body (data) contains the parameters needed for the URL.
        r   )	urlencodeZSEARXNG_API_BASEzSEARXNG_API_BASE is not set. Please set the `SEARXNG_API_BASE` environment variable or pass `api_base` parameter. Example: os.environ['SEARXNG_API_BASE'] = 'https://your-searxng-instance.com'z/search/search_searxng_params?)urllib.parser,   r   
ValueErrorendswith
isinstancedict)r"   r&   r*   r+   r(   r,   paramsZquery_stringr   r   r   get_complete_urlD   s   


z$SearXNGSearchConfig.get_complete_urlqueryc           	      K   s   t |tr
d|}|dd}d|v rN|d  }|dks!|dkr&d|d< n(|d	kr/d	|d< n|d
kr8d
|d< n|dkrAd|d< n|dkrJd|d< n||d< d|v rS	 t|}| D ]\}}||  vrm||vrm|||< q[d|iS )u  
        Transform Search request to SearXNG API format.
        
        Transforms Perplexity unified spec parameters:
        - query → q
        - max_results → (handled via pageno, SearXNG returns ~20 results per page)
        - search_domain_filter → (not directly supported)
        - country → language (approximate mapping)
        - max_tokens_per_page → (not applicable, ignored)
        
        All other SearXNG-specific parameters are passed through as-is.
        
        Args:
            query: Search query (string or list of strings). SearXNG only supports single string queries.
            optional_params: Optional parameters for the request
            
        Returns:
            Dict with typed request data following SearXNGSearchRequest spec
         json)r   r   countryusukenr   defresZjpjaZmax_resultsr/   )r4   listjoinlowerr5   itemsZ(get_supported_perplexity_optional_params)	r"   r8   r*   r(   Zrequest_datar;   Zresult_dataparamvaluer   r   r   transform_search_requestk   s4   






z,SearXNGSearchConfig.transform_search_requestraw_responselogging_objc           	      K   sr   |  }g }|dg D ]&}|dp|d}t|dd|dd|dd|dd	}|| qt|d
dS )u  
        Transform SearXNG API response to LiteLLM unified SearchResponse format.
        
        SearXNG → LiteLLM mappings:
        - results[].title → SearchResult.title
        - results[].url → SearchResult.url
        - results[].content → SearchResult.snippet
        - results[].publishedDate OR results[].pubdate → SearchResult.date
        - No last_updated field in SearXNG response (set to None)
        
        Args:
            raw_response: Raw httpx response from SearXNG API
            logging_obj: Logging object for tracking
            
        Returns:
            SearchResponse with standardized format
        resultsZpublishedDateZpubdatetitle urlcontentN)rM   rO   snippetdateZlast_updatedr.   )rL   object)r:   getr
   appendr	   )	r"   rJ   rK   r(   Zresponse_jsonrL   resultrR   Zsearch_resultr   r   r   transform_search_response   s    


z-SearXNGSearchConfig.transform_search_response)NN)N)r   r   r   staticmethodr   r    r#   r   r   r)   r5   r   r   r7   rI   httpxResponseLiteLLMLoggingObjr	   rW   r   r   r   r   r   %   sN    	

'
Fr   )r   typingr   r   r   r   r   rY   Z*litellm.litellm_core_utils.litellm_loggingr   r[   Z+litellm.llms.base_llm.search.transformationr   r	   r
   Zlitellm.secret_managers.mainr   r   r   r   r   r   r   r   <module>   s    