mgbam commited on
Commit
7c12196
·
verified ·
1 Parent(s): d18fdd2

Create src/chimera/api_clients/serp_client.py

Browse files
src/chimera/api_clients/serp_client.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # src/chimera/api_clients/serp_client.py
2
+ import httpx # Using httpx for async requests
3
+ from ..config import SERPAPI_API_KEY # Assuming SerpApi service
4
+ from ..utils.logging_config import logger
5
+ import json
6
+
7
+ # If using the official serpapi library:
8
+ # from serpapi import GoogleSearch
9
+ # Note: The official library might be synchronous. You might need
10
+ # asyncio.to_thread like in the Gemini example if using it in async code.
11
+
12
+ # Example using httpx for a generic SERP API endpoint (adjust URL/params)
13
+ # This is a simplified example assuming a REST API like SerpApi.
14
+ # You'd replace this with the actual client/method for your chosen service.
15
+
16
+ async def search_google(query: str, num_results=5, location=None) -> dict:
17
+ """
18
+ Performs a search using a SERP API (example uses SerpApi parameters).
19
+ """
20
+ if not SERPAPI_API_KEY:
21
+ logger.error("SERP API Key not configured.")
22
+ return {"error": "SERP API Key not configured."}
23
+
24
+ params = {
25
+ "q": query,
26
+ "api_key": SERPAPI_API_KEY,
27
+ "num": str(num_results), # API might expect string
28
+ # Add other parameters like location, gl (country), hl (language) as needed
29
+ # "location": location,
30
+ "engine": "google", # Specify search engine for APIs like SerpApi
31
+ }
32
+ if location:
33
+ params["location"] = location
34
+
35
+ # Adjust URL for your specific SERP provider
36
+ SEARCH_URL = "https://serpapi.com/search"
37
+
38
+ try:
39
+ async with httpx.AsyncClient() as client:
40
+ logger.info(f"Querying SERP API for: {query}")
41
+ response = await client.get(SEARCH_URL, params=params, timeout=20.0) # Add timeout
42
+ response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
43
+
44
+ results = response.json()
45
+ logger.info(f"Received {len(results.get('organic_results', []))} results from SERP API.")
46
+ # You might want to process/filter results here before returning
47
+ return results # Return the raw JSON or processed data
48
+
49
+ except httpx.HTTPStatusError as e:
50
+ logger.error(f"SERP API request failed: {e.response.status_code} - {e.response.text}")
51
+ return {"error": f"SERP API request failed: {e.response.status_code}"}
52
+ except httpx.RequestError as e:
53
+ logger.error(f"SERP API request error: {e}")
54
+ return {"error": f"SERP API connection error: {e}"}
55
+ except json.JSONDecodeError as e:
56
+ logger.error(f"Failed to decode SERP API JSON response: {e}")
57
+ return {"error": "Failed to parse SERP API response."}
58
+ except Exception as e:
59
+ logger.exception("Unexpected error during SERP API call.")
60
+ return {"error": f"An unexpected error occurred: {e}"}
61
+
62
+ # Add similar functions or a class for other external APIs (Weather, Finance etc.)
63
+ # in external_apis.py, using httpx for async calls.