def get_asset_metadata()

in source/dataplaneapi/app.py [0:0]


def get_asset_metadata(asset_id):
    """
    Retrieves all of the metadata for a specified asset.

    The first call to this method will return a dictionary containing the asset_id, a results key containing
    global asset information, and a cursor to iterate through each stored metadata type.

    To receive the additional metadata, make additional calls to this endpoint and pass in the value of the cursor
    response key as the value for the cursor query parameter.

    Once all results have been retrieved, no cursor key will be present in the response.

    Returns:
        All asset metadata

        .. code-block:: python

            {
                "asset_id": asset_id,
                "operator": operator_name,
                "cursor": encoded_cursor_value,
                "results": global_asset_info (if first call) / operator metadata
            }

    Raises:
        ChaliceViewError - 500
    """

    logging.info("Returning all metadata for asset: {asset_id}".format(asset_id=asset_id))
    table_name = dataplane_table_name

    # Check if cursor is present, if not this is the first request

    query_params = app.current_request.query_params

    if query_params is None:
        first_call = True
    else:
        # TODO: Do I want to add another check here?
        cursor = app.current_request.query_params['cursor']
        first_call = False

    if first_call is True:
        try:
            table = dynamo_resource.Table(table_name)
            asset_item = table.get_item(
                Key={
                    'AssetId': asset_id
                }
            )
        except ClientError as e:
            error = e.response['Error']['Message']
            logger.error("Exception occurred while retreiving metadata for {asset}: {e}".format(asset=asset_id, e=error))
            raise ChaliceViewError("Unable to retrieve metadata: {e}".format(e=error))
        except Exception as e:
            logger.error(
                "Exception occurred while retreiving metadata for {asset}: {e}".format(asset=asset_id, e=e))
            raise ChaliceViewError("Unable to retrieve metadata: {e}".format(e=e))
        else:
            # TODO: Should clarify varaible names for first page in the context of the
            #  entire request vs. a page for a specific operator
            if "Item" in asset_item:
                asset_attributes = asset_item["Item"]
                global_attributes = ['MediaType', 'S3Key', 'S3Bucket', 'AssetId', 'Created']
                remaining_attributes = list(set(asset_attributes.keys()) - set(global_attributes))
                remaining = []

                global_asset_info = {}

                for attr in global_attributes:
                    if attr == "AssetId":
                        pass
                    else:
                        global_asset_info[attr] = asset_attributes[attr]

                if not remaining_attributes:
                    response = {"asset_id": asset_id, "results": global_asset_info}

                else:
                    for attr in remaining_attributes:
                        # Ignore the attributes used for checkout/checkin
                        if attr == "Locked":
                            continue
                        if attr == "LockedAt":
                            continue
                        if attr == "LockedBy":
                            continue
                        attr_name = attr
                        attr_pointer = asset_attributes[attr_name][0]["pointer"]
                        remaining.append({attr_name: attr_pointer})

                    next = remaining[0]
                    next["page"] = 0

                    new_cursor = build_cursor_object(next, remaining)

                    # TODO: Maybe return the list of attributes in the response?
                    response = {"asset_id": asset_id,
                                "cursor": encode_cursor(new_cursor),
                                "results": global_asset_info}

                return response
    else:
        decoded_cursor = decode_cursor(cursor)
        # TODO: Can probably move this to an ordered dict, but this works for now
        operator_name = list(decoded_cursor["next"].keys())[0]
        pointer = decoded_cursor["next"][operator_name]
        page_num = decoded_cursor["next"]["page"]
        remaining = decoded_cursor["remaining"]

        s3_object = read_metadata_from_s3(dataplane_s3_bucket, pointer)
        # TODO: Add error handling for s3 call
        operator_metadata = json.loads(s3_object["Object"])
        if is_metadata_list(operator_metadata) is True:
            next_page_num = page_num + 1

            page_data = operator_metadata[page_num]

            if next_page_valid(operator_metadata, next_page_num) is True:
                next = {operator_name: pointer, "page": next_page_num}
                new_cursor = build_cursor_object(next, remaining)
                response = {"asset_id": asset_id, "operator": operator_name,
                            "cursor": encode_cursor(new_cursor),
                            "results": page_data}
            else:
                del remaining[0]

                if not remaining:
                    response = {"asset_id": asset_id, "operator": operator_name,
                                "results": page_data}
                else:
                    next = remaining[0]
                    next["page"] = 0
                    new_cursor = build_cursor_object(next, remaining)
                    response = {"asset_id": asset_id, "operator": operator_name, "cursor": encode_cursor(new_cursor),
                                "results": page_data}
            return response
        else:
            page = operator_metadata

            del remaining[0]

            if not remaining:
                response = {"asset_id": asset_id, "operator": operator_name,
                            "results": page}

            else:
                next = remaining[0]
                next["page"] = 0
                new_cursor = build_cursor_object(next, remaining)
                response = {"asset_id": asset_id, "operator": operator_name, "cursor": encode_cursor(new_cursor),
                            "results": page}
            return response