129 lines
4.8 KiB
Python
129 lines
4.8 KiB
Python
import logging
|
|
from typing import Optional, List, Dict, Any
|
|
from fastapi import APIRouter, Depends, Query, Request, HTTPException, status
|
|
|
|
from src.auth.security import get_current_user
|
|
from src.dependencies import SearchServiceDep
|
|
from src.models.user import UserModel
|
|
from src.schemas.search import SearchResponse, SearchRequest
|
|
from src.utils.logging import log_request
|
|
from src.utils.authorization import (
|
|
create_auth_context,
|
|
log_authorization_context,
|
|
get_team_filter,
|
|
AuthorizationError
|
|
)
|
|
from src.api.v1.error_handlers import handle_service_error
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(tags=["Search"], prefix="/search")
|
|
|
|
@router.get("", response_model=SearchResponse)
|
|
async def search_images(
|
|
request: Request,
|
|
q: str = Query(..., description="Search query for semantic image search"),
|
|
limit: int = Query(10, ge=1, le=50, description="Number of results to return (1-50)"),
|
|
similarity_threshold: float = Query(0.65, ge=0.0, le=1.0, description="Similarity threshold (0.0-1.0)"),
|
|
collection_id: Optional[str] = Query(None, description="Filter results by collection ID"),
|
|
current_user: UserModel = Depends(get_current_user),
|
|
search_service: SearchServiceDep = Depends()
|
|
):
|
|
"""
|
|
Search for images using semantic similarity
|
|
|
|
Performs a semantic search across images using AI-powered similarity matching.
|
|
Regular users can only search within their team's images, while admin users
|
|
can search across all teams.
|
|
|
|
Args:
|
|
q: The search query text to find similar images
|
|
limit: Maximum number of results to return (1-50, default: 10)
|
|
similarity_threshold: Minimum similarity score (0.0-1.0, default: 0.65)
|
|
collection_id: Optional filter to search within a specific collection
|
|
current_user: The authenticated user performing the search
|
|
search_service: Injected search service
|
|
|
|
Returns:
|
|
SearchResponse: List of matching images with similarity scores
|
|
|
|
Raises:
|
|
400: Invalid search parameters or query format
|
|
500: Search service errors
|
|
"""
|
|
auth_context = create_auth_context(
|
|
user=current_user,
|
|
resource_type="image",
|
|
action="search",
|
|
query=q,
|
|
limit=limit,
|
|
similarity_threshold=similarity_threshold,
|
|
collection_id=collection_id,
|
|
team_filter=get_team_filter(current_user),
|
|
path=request.url.path,
|
|
method=request.method
|
|
)
|
|
log_authorization_context(auth_context, success=True)
|
|
|
|
try:
|
|
response = await search_service.search_images(
|
|
query=q,
|
|
user=current_user,
|
|
request=request,
|
|
limit=limit,
|
|
similarity_threshold=similarity_threshold,
|
|
collection_id=collection_id
|
|
)
|
|
logger.info(f"Search completed: '{q}' returned {len(response.results)} results for user {current_user.id}")
|
|
return response
|
|
except Exception as e:
|
|
raise handle_service_error(e, "image search")
|
|
|
|
@router.post("", response_model=SearchResponse)
|
|
async def search_images_advanced(
|
|
search_request: SearchRequest,
|
|
request: Request,
|
|
current_user: UserModel = Depends(get_current_user),
|
|
search_service: SearchServiceDep = Depends()
|
|
):
|
|
"""
|
|
Advanced search for images with extended options
|
|
|
|
Provides advanced search capabilities with more filtering and configuration
|
|
options than the basic search endpoint. Supports complex queries and
|
|
multiple search parameters.
|
|
|
|
Args:
|
|
search_request: Advanced search request with detailed parameters
|
|
current_user: The authenticated user performing the search
|
|
search_service: Injected search service
|
|
|
|
Returns:
|
|
SearchResponse: List of matching images with similarity scores and metadata
|
|
|
|
Raises:
|
|
400: Invalid search request or validation errors
|
|
500: Search service errors
|
|
"""
|
|
auth_context = create_auth_context(
|
|
user=current_user,
|
|
resource_type="image",
|
|
action="advanced_search",
|
|
search_request=search_request.dict(),
|
|
team_filter=get_team_filter(current_user),
|
|
path=request.url.path,
|
|
method=request.method
|
|
)
|
|
log_authorization_context(auth_context, success=True)
|
|
|
|
try:
|
|
response = await search_service.search_images_advanced(
|
|
search_request=search_request,
|
|
user=current_user,
|
|
request=request
|
|
)
|
|
logger.info(f"Advanced search completed: '{search_request.query}' returned {len(response.results)} results for user {current_user.id}")
|
|
return response
|
|
except Exception as e:
|
|
raise handle_service_error(e, "advanced image search")
|