from typing import TypeVar, Generic from utils.exceptions import ValidationError from global_search.schemas import ( GlobalSearchQueryParams, GlobalSearchResponse, GlobalSearchResponseMetadata, GlobalSearchResponseMetadataCounts ) from global_search.providers.campaigns_search_provider import CampaignsSearchProvider from global_search.providers.projects_search_provider import ProjectsSearchProvider from global_search.providers.artists_search_provider import ArtistsSearchProvider T = TypeVar("T") class GlobalSearchService: def get_search_results(self, params: GlobalSearchQueryParams): if not params.query: raise ValidationError("Search query should be present") if params.include_artists: artists, artists_count = self.__search_by_query(provider=ArtistsSearchProvider, params=params) else: artists, artists_count = [], None if params.include_campaigns: campaigns, campaigns_count = self.__search_by_query(provider=CampaignsSearchProvider, params=params) else: campaigns, campaigns_count = [], None if params.include_projects: projects, projects_count = self.__search_by_query(provider=ProjectsSearchProvider, params=params) else: projects, projects_count = [], None metadata = self.__build_global_search_metadata(artists_count, campaigns_count, projects_count) return GlobalSearchResponse( artists=artists, campaigns=campaigns, projects=projects, limit=params.limit, offset=params.offset, metadata=metadata, ) def __search_by_query(self, provider: Generic[T], params: GlobalSearchQueryParams): return provider(query=params.query, limit=params.limit, offset=params.offset).search() def __build_global_search_metadata(self, artists_count, campaigns_count, projects_count): return GlobalSearchResponseMetadata( GlobalSearchResponseMetadataCounts( artists=artists_count, campaigns=campaigns_count, projects=projects_count, ) )