from dataclasses import dataclass from anydi import singleton from fansifter_common.auth.account import Account from fansifter_common.auth.types import Permission from dmp.adapters.db import ReportingDB from dmp.artists.cache import ArtistCache, cached_artist_data from dmp.artists.dtos import ArtistFansCount from dmp.artists.services import ArtistAccessService @dataclass(kw_only=True) class GetArtistFansCountRequest: identity_id: str global_participant_id: str vendor_id: int | None subaccount_id: int | None countries: list[str] | None = None @property def account(self) -> Account | None: if self.vendor_id is not None and self.subaccount_id is not None: return Account(vendor_id=self.vendor_id, subaccount_id=self.subaccount_id) return None @singleton class GetArtistFansCountHandler: permission = Permission("fan_data_list", "view") def __init__( self, db: ReportingDB, artist_access_service: ArtistAccessService, artist_cache: ArtistCache, ) -> None: self.db = db self.artist_access_service = artist_access_service self.artist_cache = artist_cache def handle(self, request: GetArtistFansCountRequest) -> ArtistFansCount: artist_access = self.artist_access_service.check_artist_access( request.identity_id, request.global_participant_id, request.account, permission=self.permission, ) return self._get_fans_count( request.global_participant_id, vendor_id=request.vendor_id, subaccount_id=request.subaccount_id, countries=request.countries, is_global=artist_access.is_global, ) @cached_artist_data("fans-count:v2") def _get_fans_count( self, global_participant_id: str, vendor_id: int | None, subaccount_id: int | None, countries: list[str] | None, is_global: bool, ) -> ArtistFansCount: if countries: template_name = "artist/get-artist-fans-count-by-country.sql" else: template_name = "artist/get-artist-fans-count.sql" query = self.db.query_from_template( template_name, context={ "global_participant_id": global_participant_id, "vendor_id": vendor_id, "subaccount_id": subaccount_id, "countries": countries, "is_global": is_global, }, ) result = self.db.session.execute(query).one_or_none() if not result: return ArtistFansCount() return ArtistFansCount.model_validate(result)