""" Search API routes. """ from fastapi import APIRouter, HTTPException, Query from typing import Optional from ..models import ( SearchRequest, ImageSearchRequest, SearchResponse, DocumentResponse, ErrorResponse ) router = APIRouter(prefix="/search", tags=["search"]) @router.post("/", response_model=SearchResponse) async def search(request: SearchRequest): """ Execute text search query. Supports: - Multi-language query processing - Boolean operators (AND, OR, RANK, ANDNOT) - Semantic search with embeddings - Custom ranking functions - Filters and aggregations """ from fastapi import Request as FastAPIRequest req: FastAPIRequest = None try: # Get searcher from app state from main import get_searcher searcher = get_searcher() # Execute search result = searcher.search( query=request.query, size=request.size, from_=request.from_, filters=request.filters, enable_translation=request.enable_translation, enable_embedding=request.enable_embedding, enable_rerank=request.enable_rerank, min_score=request.min_score ) # Convert to response model return SearchResponse( hits=result.hits, total=result.total, max_score=result.max_score, took_ms=result.took_ms, aggregations=result.aggregations, query_info=result.query_info ) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/image", response_model=SearchResponse) async def search_by_image(request: ImageSearchRequest): """ Search by image similarity. Uses image embeddings to find visually similar products. """ try: from main import get_searcher searcher = get_searcher() # Execute image search result = searcher.search_by_image( image_url=request.image_url, size=request.size, filters=request.filters ) return SearchResponse( hits=result.hits, total=result.total, max_score=result.max_score, took_ms=result.took_ms, aggregations=result.aggregations, query_info=result.query_info ) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/{doc_id}", response_model=DocumentResponse) async def get_document(doc_id: str): """ Get a single document by ID. """ try: from main import get_searcher searcher = get_searcher() doc = searcher.get_document(doc_id) if doc is None: raise HTTPException(status_code=404, detail=f"Document {doc_id} not found") return DocumentResponse(id=doc_id, source=doc) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e))