gslib/utils/metadata_util.py (37 lines of code) (raw):

# -*- coding: utf-8 -*- # Copyright 2018 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Shared utility methods for manipulating metadata of requests and resources.""" from __future__ import absolute_import from __future__ import print_function from __future__ import division from __future__ import unicode_literals import six from gslib.third_party.storage_apitools import storage_v1_messages as apitools_messages def AddAcceptEncodingGzipIfNeeded(headers_dict, compressed_encoding=False): if compressed_encoding: # If we send accept-encoding: gzip with a range request, the service # may respond with the whole object, which would be bad for resuming. # So only accept gzip encoding if the object we are downloading has # a gzip content encoding. # TODO: If we want to support compressive transcoding fully in the client, # condition on whether we are requesting the entire range of the object. # In this case, we can accept the first bytes of the object compressively # transcoded, but we must perform data integrity checking on bytes after # they are decompressed on-the-fly, and any connection break must be # resumed without compressive transcoding since we cannot specify an # offset. We would also need to ensure that hashes for downloaded data # from objects stored with content-encoding:gzip continue to be calculated # prior to our own on-the-fly decompression so they match the stored hashes. headers_dict['accept-encoding'] = 'gzip' def CreateCustomMetadata(entries=None, custom_metadata=None): """Creates a custom MetadataValue object. Inserts the key/value pairs in entries. Args: entries: (Dict[str, Any] or None) The dictionary containing key/value pairs to insert into metadata. Both the key and value must be able to be casted to a string type. custom_metadata (apitools_messages.Object.MetadataValue or None): A pre-existing custom metadata object to add to. If one is not provided, a new one will be constructed. Returns: An apitools_messages.Object.MetadataValue. """ if custom_metadata is None: custom_metadata = apitools_messages.Object.MetadataValue( additionalProperties=[]) if entries is None: entries = {} for key, value in six.iteritems(entries): custom_metadata.additionalProperties.append( apitools_messages.Object.MetadataValue.AdditionalProperty( key=str(key), value=str(value))) return custom_metadata def GetValueFromObjectCustomMetadata(obj_metadata, search_key, default_value=None): """Filters a specific element out of an object's custom metadata. Args: obj_metadata: (apitools_messages.Object) The metadata for an object. search_key: (str) The custom metadata key to search for. default_value: (Any) The default value to use for the key if it cannot be found. Returns: (Tuple(bool, Any)) A tuple indicating if the value could be found in metadata and a value corresponding to search_key (the value at the specified key in custom metadata, or the default value if the specified key does not exist in the custom metadata). """ try: value = next((attr.value for attr in obj_metadata.metadata.additionalProperties if attr.key == search_key), None) if value is None: return False, default_value return True, value except AttributeError: return False, default_value def IsCustomMetadataHeader(header): """Returns true if header (which must be lowercase) is a custom header.""" return header.startswith('x-goog-meta-') or header.startswith('x-amz-meta-') def ObjectIsGzipEncoded(obj_metadata): """Returns true if the apitools_messages.Object has gzip content-encoding.""" return (obj_metadata.contentEncoding and obj_metadata.contentEncoding.lower().endswith('gzip'))