ira/sim-search-api/app/api/routes/search.py

178 lines
5.0 KiB
Python

"""
Search routes for the sim-search API.
This module defines the routes for search execution and history.
"""
from typing import Any, List
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from app.api.dependencies import get_current_active_user
from app.db.models import User, Search
from app.db.session import get_db
from app.schemas.search import SearchExecute, SearchResults, SearchHistory, SearchHistoryList
from app.services.search_service import SearchService
router = APIRouter()
search_service = SearchService()
@router.post("/execute", response_model=SearchResults)
async def execute_search(
search_in: SearchExecute,
current_user: User = Depends(get_current_active_user),
db: Session = Depends(get_db),
) -> Any:
"""
Execute a search with the given parameters.
Args:
search_in: Search parameters
current_user: Current authenticated user
db: Database session
Returns:
Search results
"""
try:
# Get the structured query from the input
structured_query = search_in.structured_query.model_dump() if search_in.structured_query else {}
# Print for debugging
print(f"Executing search with structured_query: {structured_query}")
# Call the search service
search_results = await search_service.execute_search(
structured_query=structured_query, # Explicitly use keyword argument
search_engines=search_in.search_engines,
num_results=search_in.num_results,
timeout=search_in.timeout,
user_id=current_user.id,
db=db,
)
return search_results
except Exception as e:
import traceback
traceback.print_exc()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Error executing search: {str(e)}",
)
@router.get("/engines", response_model=List[str])
async def get_available_search_engines(
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Get a list of available search engines.
Args:
current_user: Current authenticated user
Returns:
List of available search engine names
"""
try:
engines = await search_service.get_available_search_engines()
return engines
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Error getting available search engines: {str(e)}",
)
@router.get("/history", response_model=SearchHistoryList)
async def get_search_history(
skip: int = 0,
limit: int = 100,
current_user: User = Depends(get_current_active_user),
db: Session = Depends(get_db),
) -> Any:
"""
Get the user's search history.
Args:
skip: Number of records to skip
limit: Maximum number of records to return
current_user: Current authenticated user
db: Database session
Returns:
List of search history records
"""
searches = db.query(Search).filter(Search.user_id == current_user.id).order_by(
Search.created_at.desc()
).offset(skip).limit(limit).all()
total = db.query(Search).filter(Search.user_id == current_user.id).count()
return {"searches": searches, "total": total}
@router.get("/{search_id}", response_model=SearchResults)
async def get_search_results(
search_id: str,
current_user: User = Depends(get_current_active_user),
db: Session = Depends(get_db),
) -> Any:
"""
Get results for a specific search.
Args:
search_id: ID of the search
current_user: Current authenticated user
db: Database session
Returns:
Search results
Raises:
HTTPException: If the search is not found or doesn't belong to the user
"""
search = db.query(Search).filter(
Search.id == search_id, Search.user_id == current_user.id
).first()
if not search:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Search not found",
)
return await search_service.get_search_results(search)
@router.delete("/{search_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_search(
search_id: str,
current_user: User = Depends(get_current_active_user),
db: Session = Depends(get_db),
) -> None:
"""
Delete a search from history.
Args:
search_id: ID of the search to delete
current_user: Current authenticated user
db: Database session
Raises:
HTTPException: If the search is not found or doesn't belong to the user
"""
search = db.query(Search).filter(
Search.id == search_id, Search.user_id == current_user.id
).first()
if not search:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Search not found",
)
db.delete(search)
db.commit()