from typing import Annotated, Any from anydi.ext.fastapi import Inject from fansifter_common.api.schemas import response_errors from fastapi import APIRouter, Depends, Path, Query from dmp.api import auth from dmp.api.artists import schemas from dmp.api.schemas import LabelId from dmp.artists.handlers import ( GetArtistAccountsAllHandler, GetArtistAccountsAllRequest, GetArtistAccountsHandler, GetArtistAccountsRequest, GetArtistAccountsWithFanDataHandler, GetArtistAccountsWithFanDataRequest, GetArtistFansAlsoListeningHandler, GetArtistFansAlsoListeningRequest, GetArtistFansCountByCampaignSummaryHandler, GetArtistFansCountByCampaignSummaryRequest, GetArtistFansCountBySegmentHandler, GetArtistFansCountBySegmentRequest, GetArtistFansCountByTypeSummaryHandler, GetArtistFansCountByTypeSummaryRequest, GetArtistFansCountByTypeTimeseriesHandler, GetArtistFansCountByTypeTimeseriesRequest, GetArtistFansCountHandler, GetArtistFansCountRequest, GetArtistFansShareByAgeRangeHandler, GetArtistFansShareByAgeRangeRequest, GetArtistFansShareByGenderHandler, GetArtistFansShareByGenderRequest, GetArtistFansShareByHeavyRotationHandler, GetArtistFansShareByHeavyRotationRequest, GetArtistFansShareByLocationHandler, GetArtistFansShareByLocationRequest, GetArtistFansShareBySegmentActivityHandler, GetArtistFansShareBySegmentActivityRequest, GetArtistMainRepAccountsHandler, GetArtistMainRepAccountsRequest, GetArtistMaxSpendHandler, GetArtistMaxSpendRequest, GetArtistSegmentsExplainedHandler, GetArtistSegmentsExplainedRequest, GetArtistsHandler, GetArtistsRequest, GetArtistsV2Handler, GetArtistsV2Request, GetParticipantsHandler, GetParticipantsRequest, ) from dmp.rosters.exceptions import GlobalFanDataListNotAvailableError router = APIRouter(tags=["Artists"]) @router.get( "/artists", operation_id="getArtists", response_model=schemas.GetArtistsOutput, response_model_by_alias=True, ) def get_artists( identity_id: auth.IdentityId, data: Annotated[schemas.GetArtistsInput, Query()], handler: Annotated[GetArtistsHandler, Inject()], ) -> Any: limit = data.limit or GetArtistsRequest.DEFAULT_LIMIT offset = data.offset or GetArtistsRequest.DEFAULT_OFFSET response = handler.handle( GetArtistsRequest( identity_id=identity_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, search=data.search, limit=limit, offset=offset, ) ) return { "items": response.items, "total": response.total, "limit": limit, "offset": offset, } @router.get( "/artists/v2", operation_id="getArtistsV2", response_model=schemas.GetArtistsV2Output, response_model_by_alias=True, ) def get_artists_v2( identity_id: auth.IdentityId, data: Annotated[schemas.GetArtistsInput, Query()], handler: Annotated[GetArtistsV2Handler, Inject()], ) -> Any: limit = data.limit or GetArtistsV2Request.DEFAULT_LIMIT offset = data.offset or GetArtistsV2Request.DEFAULT_OFFSET response = handler.handle( GetArtistsV2Request( identity_id=identity_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, search=data.search, participant_type=data.participant_type, virtual_participant_ids=data.virtual_participant_ids, limit=limit, offset=offset, ) ) return { "items": response.items, "total": response.total, "limit": limit, "offset": offset, } @router.get( "/artists/{globalParticipantId}/accounts", operation_id="getArtistAccounts", response_model=list[schemas.ArtistAccount], response_model_by_alias=True, deprecated=True, ) def get_artist_accounts( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], handler: Annotated[GetArtistAccountsHandler, Inject()], ) -> Any: return handler.handle( GetArtistAccountsRequest( identity_id=identity_id, global_participant_id=global_participant_id, ) ) @router.get( "/artists/{globalParticipantId}/accounts-with-fandata", operation_id="getArtistAccountsWithFanData", response_model=schemas.GetArtistAccountsWithFanDataOutput, response_model_by_alias=True, ) def get_artist_accounts_with_fandata( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], handler: Annotated[GetArtistAccountsWithFanDataHandler, Inject()], ) -> Any: return handler.handle( GetArtistAccountsWithFanDataRequest( identity_id=identity_id, global_participant_id=global_participant_id, ) ) @router.get( "/artists/{globalParticipantId}/accounts/all", tags=["internal"], operation_id="getArtistAccountsAll", response_model=list[LabelId], response_model_by_alias=True, ) def get_artist_accounts_all( global_participant_id: Annotated[str, Path(alias="globalParticipantId")], handler: Annotated[GetArtistAccountsAllHandler, Inject()], ) -> Any: return handler.handle( GetArtistAccountsAllRequest( global_participant_id=global_participant_id, ) ) @router.get( "/artists/{globalParticipantId}/main-rep-accounts", operation_id="getArtistMainRepAccounts", response_model=list[LabelId], response_model_by_alias=True, ) def get_artist_main_rep_accounts( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], params: Annotated[schemas.GetArtistMainRepAccountsInput, Query()], handler: Annotated[GetArtistMainRepAccountsHandler, Inject()], ) -> Any: return handler.handle( GetArtistMainRepAccountsRequest( global_participant_id=global_participant_id, identity_id=identity_id, campaign_type=params.campaign_type, ) ) @router.get( "/artists/{globalParticipantId}/fans-count", operation_id="getArtistFansCount", response_model=schemas.ArtistFansCountOutput, response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_fans_count( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.GetArtistFanReportByCountriesInput, Query()], handler: Annotated[GetArtistFansCountHandler, Inject()], ) -> Any: return handler.handle( GetArtistFansCountRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, countries=data.countries, ) ) @router.get( "/artists/{globalParticipantId}/segments", operation_id="getArtistFansCountBySegment", response_model=list[schemas.ArtistFansSegmentValue], response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_fans_count_by_segment( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.GetArtistFanReportByCountriesInput, Query()], handler: Annotated[GetArtistFansCountBySegmentHandler, Inject()], ) -> Any: return handler.handle( GetArtistFansCountBySegmentRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, countries=data.countries, ) ) @router.get( "/artists/{globalParticipantId}/timeseries", operation_id="getArtistFansCountByTypeTimeseries", response_model=list[schemas.ArtistFansTimeseries], response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_fans_count_by_type_timeseries( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.GetArtistFanTimeseriesByTypeInput, Query()], handler: Annotated[GetArtistFansCountByTypeTimeseriesHandler, Inject()], ) -> Any: return handler.handle( GetArtistFansCountByTypeTimeseriesRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, start_date=data.start_date, end_date=data.end_date, countries=data.countries, type=data.type, totals_countries=data.totals_countries, ) ) @router.get( "/artists/{globalParticipantId}/summary", operation_id="getArtistFansCountByTypeSummary", response_model=list[schemas.ArtistFansSummaryValue], response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_fans_count_by_type_summary( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.GetArtistFanReportByTypeInput, Query()], handler: Annotated[GetArtistFansCountByTypeSummaryHandler, Inject()], ) -> Any: return handler.handle( GetArtistFansCountByTypeSummaryRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, start_date=data.start_date, end_date=data.end_date, countries=data.countries, type=data.type, ) ) @router.get( "/artists/{globalParticipantId}/locations", operation_id="getArtistFansShareByLocation", response_model=schemas.ArtistFansShareByLocationOutput, response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_fans_share_by_location( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.ArtistAccountInput, Query()], handler: Annotated[GetArtistFansShareByLocationHandler, Inject()], ) -> Any: return handler.handle( GetArtistFansShareByLocationRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, ) ) @router.get( "/artists/{globalParticipantId}/genders", operation_id="getArtistFansShareByGender", response_model=schemas.ArtistFansShareByGenderOutput, response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_fans_share_by_gender( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.GetArtistFanReportByCountriesInput, Query()], handler: Annotated[GetArtistFansShareByGenderHandler, Inject()], ) -> Any: return handler.handle( GetArtistFansShareByGenderRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, countries=data.countries, ) ) @router.get( "/artists/{globalParticipantId}/heavy-rotation", operation_id="getArtistFansShareByHeavyRotation", response_model=schemas.ArtistFansShareByHeavyRotationOutput, response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_fans_share_by_heavy_rotation( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.GetArtistFanReportByCountriesInput, Query()], handler: Annotated[GetArtistFansShareByHeavyRotationHandler, Inject()], ) -> Any: return handler.handle( GetArtistFansShareByHeavyRotationRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, countries=data.countries, ) ) @router.get( "/artists/{globalParticipantId}/max-spend", operation_id="getArtistMaxSpend", response_model=schemas.GetArtistMaxSpendOutput, response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_max_spend( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.ArtistAccountInput, Query()], handler: Annotated[GetArtistMaxSpendHandler, Inject()], ) -> Any: max_spend = handler.handle( GetArtistMaxSpendRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, ) ) return { "maxSpend": max_spend, } @router.get( "/artists/{globalParticipantId}/age-ranges", operation_id="getArtistFansShareByAgeRange", response_model=schemas.ArtistFansShareByAgeRangeOutput, response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_fans_share_by_age_range( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.GetArtistFanReportByCountriesInput, Query()], handler: Annotated[GetArtistFansShareByAgeRangeHandler, Inject()], ) -> Any: return handler.handle( GetArtistFansShareByAgeRangeRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, countries=data.countries, ) ) @router.get( "/artists/{globalParticipantId}/fans-also-listening", operation_id="getArtistFansAlsoListening", response_model=schemas.ArtistFansAlsoListeningOutput, response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_fans_also_listening( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.GetArtistFanReportByCountriesInput, Query()], handler: Annotated[GetArtistFansAlsoListeningHandler, Inject()], ) -> Any: return handler.handle( GetArtistFansAlsoListeningRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, countries=data.countries, ) ) @router.get( "/artists/{globalParticipantId}/segments-activities", operation_id="GetArtistSegmentActivityBreakdown", response_model=list[schemas.ArtistSegmentActivityBreakdownOutput], response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_segment_activity_breakdown( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.GetArtistFanReportByCountriesInput, Query()], handler: Annotated[GetArtistFansShareBySegmentActivityHandler, Inject()], ) -> Any: return handler.handle( GetArtistFansShareBySegmentActivityRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, countries=data.countries, ) ) @router.get( "/artists/{globalParticipantId}/explain-segments", operation_id="getArtistSegmentsExplained", response_model=list[schemas.ArtistSegmentExplainedValue], response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_segments_explained( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.GetArtistSegmenstExplainedByCountriesInput, Query()], handler: Annotated[GetArtistSegmentsExplainedHandler, Inject()], ) -> Any: return handler.handle( GetArtistSegmentsExplainedRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, countries=data.countries, language=data.language, ) ) @router.get( "/artists/participants", tags=["internal"], operation_id="getParticipants", response_model=schemas.GetParticipantsOutput, response_model_by_alias=True, dependencies=[Depends(auth.validate_fan_response_jwt)], ) def get_participants( params: Annotated[schemas.GetParticipantsInput, Query()], handler: Annotated[GetParticipantsHandler, Inject()], ) -> Any: limit = params.limit or GetParticipantsRequest.DEFAULT_LIMIT offset = params.offset or GetParticipantsRequest.DEFAULT_OFFSET response = handler.handle( GetParticipantsRequest( vendor_id=params.vendor_id, subaccount_id=params.subaccount_id, search=params.search, participant_type=params.participant_type, virtual_participant_ids=params.virtual_participant_ids, limit=limit, offset=offset, ) ) return { "items": response.items, "total": response.total, "limit": limit, "offset": offset, } @router.get( "/artists/{globalParticipantId}/summary-by-campaign", operation_id="getArtistFansCountByCampaignSummary", response_model=list[schemas.ArtistFansCampaignSummaryValue], response_model_by_alias=True, responses=response_errors( GlobalFanDataListNotAvailableError, ), ) def get_artist_fans_count_by_campaign_summary( identity_id: auth.IdentityId, global_participant_id: Annotated[str, Path(alias="globalParticipantId")], data: Annotated[schemas.GetArtistFanReportByCampaignInput, Query()], handler: Annotated[GetArtistFansCountByCampaignSummaryHandler, Inject()], ) -> Any: return handler.handle( GetArtistFansCountByCampaignSummaryRequest( identity_id=identity_id, global_participant_id=global_participant_id, vendor_id=data.vendor_id, subaccount_id=data.subaccount_id, start_date=data.start_date, end_date=data.end_date, countries=data.countries, ) )