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