Refactor CustomSearchService to use updated environment variable names and add search endpoint with error handling

main
bahawal.baloch 2026-05-14 15:53:21 +05:00
parent 8d9b084a0b
commit cc9466ab60
2 changed files with 63 additions and 4 deletions

View File

@ -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,

View File

@ -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))