"""Lambda function to get proces_participants.""" from common.schemas.state_machine_schema import StateMachineSchema import config from config import graphql_gateway from src.constants import queries logger = config.app_logger def handler(event, input_context): """Lambda function to proces_participants.""" sm_context = StateMachineSchema().load(event) correlation_id = sm_context.correlation_id graphql_gateway.set_headers( { 'Orchard-User-Id': config.OA_USER, 'Correlation-Id': correlation_id, } ) participants = get_participants(sm_context) participants_dict = {} participants_renaming = {} vendor_id = sm_context.product.vendor_id subaccount_id = sm_context.product.subaccount_id for participant in participants: logger.info(f'Processing Participant: {participant}') artist = get_artist(participant, vendor_id) if not artist: artist = create_artist( participant, vendor_id, subaccount_id ) label_participant = create_label_participant( participant, vendor_id, subaccount_id ) if label_participant.get('id') not in participants_dict: participants_dict[label_participant.get('id')] = { 'name': participant['name'], 'artist_id': artist.get('artistId'), 'label_participant_id': label_participant.get('id'), 'label_participant_uuid': label_participant.get('uuid'), } else: if participants_dict[label_participant.get('id')]['name'] != \ participant['name']: participants_renaming[participant['name']] = \ participants_dict[label_participant.get('id')]['name'] sm_context.label_participants = [p for p in participants_dict.values()] rename_participants(sm_context, participants_renaming) remove_duplicates(sm_context) return StateMachineSchema().dump(sm_context) def get_participants(sm_context: StateMachineSchema) -> list[dict]: """Collect all participants and merge data for those with the same name.""" participants_dict = {} all_participants = get_all_participants(sm_context) for participant in all_participants: name = participant.name if participants_dict.get(name) is None: participants_dict[name] = { 'name': name, 'roles': participant.roles, } if participant.apple_id: participants_dict[name]['apple_id'] = participant.apple_id if participant.spotify_uri: participants_dict[name]['spotify_uri'] = participant.spotify_uri return [p for p in participants_dict.values()] def get_all_participants(sm_context: StateMachineSchema) -> list: """Collect all participants, including duplicates. Returns: list """ all_participants = [] if sm_context.project and sm_context.project.artist: all_participants.append(sm_context.project.artist) if sm_context.product.display_artists: all_participants.extend(sm_context.product.display_artists) for track in sm_context.tracks: if track.display_artists: all_participants.extend(track.display_artists) return all_participants def get_artist(participant, vendor_id): """Format payload and call GraphQL query to get artist data. Args: participant (dict): dict with participant data vendor_id (str): Product vendor_id Returns: dict """ payload = { 'artistName': participant.get('name'), 'vendorId': vendor_id } logger.info(f'Executing filterArtists with payload: {payload}') result = graphql_gateway.execute(queries.GET_ARTIST, payload) logger.info(f'filterArtists returned: {result}') if result['data']['filterArtists']: return result['data']['filterArtists'][0] else: return None def create_artist( participant, vendor_id, subaccount_id): """Format payload and call GraphQL mutation to create artist. Args: participant (dict): dict with participant data vendor_id (str): Product vendor_id subaccount_id (str): Product subaccount_id Returns: dict """ payload = { 'create': [ { 'artistName': participant.get('name'), 'vendorId': vendor_id, 'subaccountId': subaccount_id, } ] } logger.info(f'Executing saveArtists with payload: {payload}') result = graphql_gateway.execute(queries.SAVE_ARTIST, {'data': payload}) logger.info(f'saveArtists returned: {result}') if result['data']['saveArtists']: return result['data']['saveArtists'][0] else: return {} def create_label_participant( participant, vendor_id, subaccount_id): """Format payload and call GraphQL mutation to create label participant. Args: participant (dict): dict with participant data vendor_id (str): Product vendor_id subaccount_id (str): Product subaccount_id Returns: dict """ payload = { 'name': participant.get('name'), 'spotifyId': participant.get('spotify_uri'), 'appleMusicId': participant.get('apple_id') } # Remove keys with null values payload = { key: value for key, value in payload.items() if value is not None} logger.info(f'Executing createLabelParticipant with payload: {payload}') result = graphql_gateway.execute( queries.GET_OR_CREATE_LABEL_PARTICIPANT, { 'data': payload, 'vendorId': vendor_id, 'subaccountId': subaccount_id or 0, # Mutation expects 0 if there is no subaccountId } ) logger.info(f'createLabelParticipant returned: {result}') return result['data']['createLabelParticipant'] def rename_participants(sm_context, participants_renaming): """Rename participants to be consistent with label_participant_id.""" participants = get_all_participants(sm_context) for participant in participants: if participant.name in participants_renaming: participant.name = participants_renaming[participant.name] def remove_duplicates(sm_context): """Remove duplicated artists after renaming.""" def _remove_duplicates(artists): deduplicated_artists = [] added_artists = [] for artist in artists: if artist.name not in added_artists: added_artists.append(artist.name) deduplicated_artists.append(artist) return deduplicated_artists if sm_context.product.display_artists: sm_context.product.display_artists = _remove_duplicates( sm_context.product.display_artists) for track in sm_context.tracks: if track.display_artists: track.display_artists = _remove_duplicates( track.display_artists)