"""lookup-video-product.""" import uuid from typing import Optional from ddex_ingester_common.helpers.s3_ddex import load_ddex_json from ddex_ingester_common.lambda_exceptions import ( InvalidProductTypeException, OrchardProductNotFoundException) from ddex_ingester_common.logging import utils as logging_utils from ddex_ingester_common.models.state_machine.body import \ Body as StateMachineContext from ddex_ingester_common.schemas.s3_schema import S3Schema from ddex_ingester_common.schemas.state_machine_schema import \ StateMachineSchema from marshmallow.utils import get_value import config from config import graphql_gateway from constants import queries from constants.track import MUSIC_TRACK, SINGLE_FORMAT logger = logging_utils.get_logger(config.app_logger) def handler(event, context): """Lambda entry point.""" s3_context = S3Schema().load(load_ddex_json(event)) context = StateMachineSchema().load(event) correlation_id = context.correlation_id or str(uuid.uuid4()) context.correlation_id = correlation_id logging_utils.update_logger_correlation_id(logger, correlation_id) logging_utils.update_logger_with_message_ids( logger, context.message_id, context.message_thread_id, context.execution_name ) graphql_gateway.set_headers( { 'Orchard-User-Id': config.OA_USER, 'Correlation-Id': correlation_id, } ) upc = context.product.upc graphql_result = graphql_gateway.execute( queries.get_video_product_by_upc, {'upc': upc} )['data']['productByUpc'] logger.info(f'Check if product exists: {graphql_result}') if not graphql_result: raise OrchardProductNotFoundException( f'Product id was not found for UPC: {context.product.upc}') if not graphql_result.get('typeOfVideo'): raise InvalidProductTypeException( f'Product with UPC {context.product.upc} is not a video') product_id = graphql_result.get('productId') context.product.status = graphql_result.get('status') context.product.display_status = graphql_result.get('displayStatus') context.orchard_label = graphql_result.get('label', {}).get('name') context.video.current_channel = graphql_result.get('channelSelection') # It's possible for us not to have an associated track ISRC if s3_context.video.associated_track_isrc: context.video.associated_track_tuid = get_associated_track_tuid( context, s3_context.video.associated_track_isrc, ) if not product_id: raise ValueError('Product ID not found.') logger.info(f'Found product id: {product_id}') context.product.product_id = product_id return StateMachineSchema().dump(context) def get_associated_track_tuid( context: StateMachineContext, isrc: str) -> Optional[str]: """Get the tuid of the associated track using the ISRC.""" payload = { 'isrc': isrc, 'orchardLabelId': { 'vendorId': context.product.vendor_id, 'subaccountId': context.product.subaccount_id or 0, } } logger.info( f'Checking for tracks with isrc {isrc} using payload {payload}') graphql_result = graphql_gateway.execute( queries.get_tracks_by_isrc, payload )['data']['orchardLabel'] logger.info( f'Checked for tracks with isrc {isrc} and received {graphql_result}') tracks = get_value( graphql_result, 'labelSoundRecording.tracks', [] ) tuid = None for track in tracks: if track['trackType'] == MUSIC_TRACK: # If there is no single release, default to the first music track if not tuid: tuid = track['tuid'] # If there are multiple tracks, prefer the single release if track['product']['format'] == SINGLE_FORMAT: tuid = track['tuid'] return tuid