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