🔍 Code Extractor

class GoogleSearchClient

Maturity: 49

A client class for performing Google searches using the Serper API through LangChain's GoogleSerperAPIWrapper, providing both single and batch search capabilities.

File:
/tf/active/vicechatdev/QA_updater/data_access/google_search_client.py
Lines:
7 - 85
Complexity:
moderate

Purpose

This class provides a convenient interface for executing Google searches via the Serper API. It handles API authentication, error logging, and supports both single query searches and batch searches with multiple queries. The class wraps LangChain's GoogleSerperAPIWrapper to provide a simplified interface with logging and error handling. It's designed for applications that need to programmatically retrieve Google search results, such as research tools, data gathering systems, or AI agents that need web search capabilities.

Source Code

class GoogleSearchClient:
    """Client for accessing Google search results via the Serper API."""
    
    def __init__(self, config: ConfigParser):
        """Initialize the client with required credentials."""
        self.logger = logging.getLogger(__name__)
        self.config = config

        # API key for Google Serper
        self.serper_api_key = self.config.get('api_keys', 'serper_api_key', fallback=None)
        
        # Initialize LangChain wrapper
        self.search_tool = GoogleSerperAPIWrapper()
        
        if not self.serper_api_key:
            self.logger.warning("Serper API key not provided. Google search functionality will not work.")
        
        self.logger.info("GoogleSearchClient initialized.")

    def search(self, query: str, max_results: int = 10) -> str:
        """
        Search Google via the Serper API using LangChain's wrapper.
        
        Args:
            query: Search query
            max_results: Maximum number of results to return (note: may not be respected by wrapper)
            
        Returns:
            String containing formatted search results
        """
        try:
            self.logger.info(f"Executing search query: {query}")
            result = self.search_tool.run(query)
            self.logger.debug(f"Got search result of length: {len(result)}")
            return result
        except Exception as e:
            self.logger.exception(f"Error during Google Serper API request: {e}")
            return "Error retrieving search results."

    def search_all(self, queries: List[str], operators: List[str] = None, domains: List[str] = None, max_results_per_query: int = 3) -> List[str]:
        """
        Execute multiple search queries and combine the results.
        
        Args:
            queries: List of search queries
            operators: Optional list of search operators to apply
            domains: Optional list of domains to restrict the search to
            max_results_per_query: Maximum results to return per query
            
        Returns:
            List of search result strings
        """
        all_results = []
        
        # Process each query
        for query in queries:
            modified_query = query
            
            # Apply operators if provided
            # if operators:
            #     for operator in operators:
            #         if operator.strip() and operator not in modified_query:
            #             modified_query = f"{modified_query} {operator}"
            
            # # Apply domain restrictions if provided
            # if domains and domains[0].strip():  # Only use first domain for simplicity
            #     domain = domains[0].strip()
            #     if "site:" not in modified_query:
            #         modified_query = f"{modified_query} site:{domain}"
            
            # Execute search
            self.logger.info(f"Searching for: {modified_query}")
            result = self.search(modified_query, max_results_per_query)
            
            # Add the result if it's not empty
            if result and result != "Error retrieving search results.":
                all_results.append(f"Search for '{modified_query}':\n{result}")
        
        return all_results

Parameters

Name Type Default Kind
bases - -

Parameter Details

config: A ConfigParser object containing configuration settings, specifically expected to have an 'api_keys' section with a 'serper_api_key' entry. This is the primary configuration source for API credentials and other settings.

Return Value

The constructor returns an instance of GoogleSearchClient. The search() method returns a string containing formatted search results from the Serper API, or an error message string if the search fails. The search_all() method returns a list of strings, where each string contains the formatted results for one query, prefixed with the query text.

Class Interface

Methods

__init__(self, config: ConfigParser) -> None

Purpose: Initialize the GoogleSearchClient with configuration containing API credentials and set up the LangChain search wrapper

Parameters:

  • config: ConfigParser object containing API keys and configuration settings, must have 'api_keys' section with 'serper_api_key'

Returns: None - initializes the instance with logger, config, serper_api_key, and search_tool attributes

search(self, query: str, max_results: int = 10) -> str

Purpose: Execute a single Google search query via the Serper API and return formatted results

Parameters:

  • query: The search query string to execute on Google
  • max_results: Maximum number of results to return (default 10), though this may not be respected by the underlying wrapper

Returns: String containing formatted search results from the Serper API, or 'Error retrieving search results.' if an exception occurs

search_all(self, queries: List[str], operators: List[str] = None, domains: List[str] = None, max_results_per_query: int = 3) -> List[str]

Purpose: Execute multiple search queries in batch and return combined results, with optional support for search operators and domain restrictions (currently commented out)

Parameters:

  • queries: List of search query strings to execute
  • operators: Optional list of search operators to apply to queries (currently not implemented, code is commented out)
  • domains: Optional list of domains to restrict searches to (currently not implemented, code is commented out)
  • max_results_per_query: Maximum number of results to return per individual query (default 3)

Returns: List of strings, each containing formatted search results prefixed with the query text. Error results are filtered out automatically.

Attributes

Name Type Description Scope
logger logging.Logger Logger instance for recording search operations, errors, and warnings instance
config ConfigParser Configuration object containing API keys and other settings instance
serper_api_key str or None API key for Google Serper service, retrieved from config or None if not provided instance
search_tool GoogleSerperAPIWrapper LangChain wrapper instance for executing searches via the Serper API instance

Dependencies

  • logging
  • typing
  • configparser
  • langchain_community

Required Imports

import logging
from typing import List
from configparser import ConfigParser
from langchain_community.utilities import GoogleSerperAPIWrapper

Usage Example

from configparser import ConfigParser
from google_search_client import GoogleSearchClient

# Setup configuration
config = ConfigParser()
config.add_section('api_keys')
config.set('api_keys', 'serper_api_key', 'your-serper-api-key-here')

# Initialize the client
client = GoogleSearchClient(config)

# Perform a single search
results = client.search('Python programming tutorials', max_results=5)
print(results)

# Perform multiple searches
queries = ['machine learning basics', 'neural networks explained', 'deep learning frameworks']
all_results = client.search_all(queries, max_results_per_query=3)
for result in all_results:
    print(result)
    print('---')

Best Practices

  • Always provide a valid Serper API key in the configuration to enable search functionality
  • Handle the error message 'Error retrieving search results.' returned by search() method when API calls fail
  • Use search_all() for batch operations to efficiently process multiple queries
  • The max_results parameter in search() may not be respected by the underlying GoogleSerperAPIWrapper
  • Check logger warnings during initialization to ensure API key is properly configured
  • The class maintains state through instance attributes (logger, config, serper_api_key, search_tool), so reuse the same instance for multiple searches
  • Be aware of Serper API rate limits and quotas when performing multiple searches
  • The search_all() method filters out error results automatically, so check the returned list length
  • Commented-out code in search_all() suggests future support for search operators and domain restrictions

Similar Components

AI-powered semantic similarity - components with related functionality:

  • class LiteratureClient 48.8% similar

    A client class for searching and retrieving scientific literature from multiple academic databases including PubMed, Semantic Scholar, arXiv, and ScienceOpen.

    From: /tf/active/vicechatdev/QA_updater/data_access/literature_client.py
  • class CompanyNewsClient 48.8% similar

    A client class for accessing company news and information from multiple sources including GDELT Project and NewsAPI, with built-in rate limiting and error handling.

    From: /tf/active/vicechatdev/QA_updater/data_access/company_news_client.py
  • class PatentClient 48.2% similar

    A client class for searching and retrieving patent data from multiple sources including USPTO, EPO (European Patent Office), and The Lens API.

    From: /tf/active/vicechatdev/QA_updater/data_access/patent_client.py
  • class QueryParser 43.7% similar

    A parser class that converts LLM-generated query response text into structured dictionaries containing various search query types, metadata, and parameters.

    From: /tf/active/vicechatdev/QA_updater/core/query_parser.py
  • class ClinicalTrialsClient 43.4% similar

    A client class for searching and retrieving clinical trial data from multiple international sources including ClinicalTrials.gov, EU Clinical Trials Register, WHO ICTRP, and OpenTrials.

    From: /tf/active/vicechatdev/QA_updater/data_access/clinical_trials_client.py
← Back to Browse