File size: 3,436 Bytes
b62e029
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9496080
 
 
b62e029
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9496080
b62e029
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# api/v1/search.py

from fastapi import APIRouter, Depends, Form, HTTPException, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

from api.dependencies import get_search_service
from api.schemas.search import SearchRequest, SearchResponse
from core.logger import setup_logger
from services.search_service import HybridSearchService

logger = setup_logger("search_api")

router = APIRouter(prefix="/search", tags=["Search"])
templates = Jinja2Templates(directory="templates")

# -------------------------------------
# Json API Endpoint for Hybrid Search
# -------------------------------------
@router.post("/", response_model=SearchResponse, summary="Execute Hybrid Search (JSON)")
async def execute_search(
    request_data: SearchRequest,
    search_service: HybridSearchService = Depends(get_search_service)
):
    """
    Execute a hybrid search using the provided query and parameters.
    """
    try:
        search_output = search_service.search(
            query=request_data.query, 
            top_k=request_data.top_k,
            use_reranking=request_data.use_reranking,
            include_llm_context=request_data.include_llm_context
        )
        return SearchResponse(
            query=search_output["query"], 
            results=search_output["results"], 
            latency_ms=search_output["latency_ms"]
        )
        
    except ValueError as ve:
        logger.warning(f"Invalid search request: {ve}")
        raise HTTPException(status_code=400, detail=str(ve))
    except Exception as e:
        logger.error(f"Search Execution Failed: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail="Internal server error during search.")

# -------------------------------------
# HTML Demo Endpoint for Manual Testing
# -------------------------------------
@router.get("/demo", response_class=HTMLResponse, summary="Search Demo UI (GET)")
async def demo_page_get(request: Request):
    """
    Render a simple HTML page with a search form for manual testing of the hybrid search functionality.
    """
    return templates.TemplateResponse(
        "index.html", 
        {"request": request, "results": None, "query": ""}
    )

@router.post("/demo", response_class=HTMLResponse, summary="Search Demo UI (POST)")
async def demo_page_post(
    request: Request,
    query: str = Form(...),
    search_service: HybridSearchService = Depends(get_search_service)
):
    """
    Handle form submission from the demo page, execute the search, and render results in the same template.
    """
    try:
        search_output = search_service.search(query=query, top_k=5, use_reranking=False, include_llm_context=False)
        
        return templates.TemplateResponse(
            "index.html",
            {
                "request": request,
                "results": search_output["results"],
                "query": query,
                "latency_ms": search_output["latency_ms"]
            }
        )
    except Exception as e:
        logger.error(f"Demo Search Failed: {e}", exc_info=True)
        return templates.TemplateResponse(
            "index.html",
            {
                "request": request,
                "results": None,
                "query": query,
                "error_message": "An error occurred while processing your search. Please try again."
            },
            status_code=500
        )