Refactor CustomSearchService to use updated environment variable names and add search endpoint with error handling
parent
8d9b084a0b
commit
cc9466ab60
|
|
@ -15,14 +15,14 @@ class CustomSearchService:
|
||||||
cx: Optional[str] = None,
|
cx: Optional[str] = None,
|
||||||
timeout: float = 30.0,
|
timeout: float = 30.0,
|
||||||
):
|
):
|
||||||
self.api_key = api_key or os.getenv("GOOGLE_CSE_API_KEY")
|
self.api_key = api_key or os.getenv("GEMINI_API_KEY")
|
||||||
self.cx = cx or os.getenv("GOOGLE_CSE_CX")
|
self.cx = cx or os.getenv("SEARCH_ENGINE_ID")
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
|
|
||||||
if not self.api_key:
|
if not self.api_key:
|
||||||
raise ValueError("GOOGLE_CSE_API_KEY is not set in environment")
|
raise ValueError("GEMINI_API_KEY is not set in environment")
|
||||||
if not self.cx:
|
if not self.cx:
|
||||||
raise ValueError("GOOGLE_CSE_CX is not set in environment")
|
raise ValueError("SEARCH_ENGINE_ID is not set in environment")
|
||||||
|
|
||||||
async def search(
|
async def search(
|
||||||
self,
|
self,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
import logging
|
||||||
|
from typing import Optional
|
||||||
|
from fastapi import APIRouter, HTTPException, Query
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from .service import CustomSearchService
|
||||||
|
from .serializers import SearchResponse, SearchResultItem
|
||||||
|
|
||||||
|
app_router = APIRouter()
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@app_router.get("/search", response_model=SearchResponse)
|
||||||
|
async def search_endpoint(
|
||||||
|
q: str = Query(..., description="Search query string"),
|
||||||
|
num: int = Query(10, ge=1, le=10, description="Number of results to return (1-10)"),
|
||||||
|
start: int = Query(1, ge=1, description="Start index for pagination"),
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
service = CustomSearchService()
|
||||||
|
data = await service.search(query=q, num=num, start=start)
|
||||||
|
|
||||||
|
items = [
|
||||||
|
SearchResultItem(
|
||||||
|
title=item.get("title"),
|
||||||
|
link=item.get("link"),
|
||||||
|
displayLink=item.get("displayLink"),
|
||||||
|
snippet=item.get("snippet"),
|
||||||
|
formattedUrl=item.get("formattedUrl"),
|
||||||
|
pagemap=item.get("pagemap"),
|
||||||
|
)
|
||||||
|
for item in data.get("items", [])
|
||||||
|
]
|
||||||
|
|
||||||
|
search_info = data.get("searchInformation", {}) or {}
|
||||||
|
|
||||||
|
return SearchResponse(
|
||||||
|
query=q,
|
||||||
|
total_results=search_info.get("totalResults"),
|
||||||
|
search_time=search_info.get("searchTime"),
|
||||||
|
items=items,
|
||||||
|
raw=data,
|
||||||
|
)
|
||||||
|
|
||||||
|
except ValueError as e:
|
||||||
|
log.error(f"Configuration error: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
except httpx.HTTPStatusError as e:
|
||||||
|
log.error(f"Google CSE returned {e.response.status_code}: {e.response.text}")
|
||||||
|
raise HTTPException(status_code=e.response.status_code, detail=e.response.text)
|
||||||
|
except httpx.RequestError as e:
|
||||||
|
log.error(f"Network error calling Google CSE: {e}")
|
||||||
|
raise HTTPException(status_code=502, detail=f"Upstream request failed: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
log.error(f"Unexpected error: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
Loading…
Reference in New Issue