def upload_blob(cmd, client, file_path, container_name=None, blob_name=None, blob_type=None, metadata=None, validate_content=False, maxsize_condition=None, max_connections=2, lease_id=None, if_modified_since=None, if_unmodified_since=None, if_match=None, if_none_match=None, timeout=None, progress_callback=None, encryption_scope=None, overwrite=None, **kwargs): """Upload a blob to a container.""" upload_args = { 'blob_type': transform_blob_type(cmd, blob_type), 'lease': lease_id, 'max_concurrency': max_connections } if overwrite is not None: upload_args['overwrite'] = overwrite if maxsize_condition: upload_args['maxsize_condition'] = maxsize_condition if cmd.supported_api_version(min_api='2016-05-31'): upload_args['validate_content'] = validate_content if progress_callback: upload_args['raw_response_hook'] = progress_callback check_blob_args = { 'lease': lease_id, 'if_modified_since': if_modified_since, 'if_unmodified_since': if_unmodified_since, 'if_match': if_match, 'if_none_match': if_none_match, 'timeout': timeout } # used to check for the preconditions as upload_append_blob() cannot if blob_type == 'append': from azure.core.exceptions import HttpResponseError if exists(cmd, client, timeout=timeout): client.get_blob_properties(**check_blob_args) # Because the contents of the uploaded file may be too large, it should be passed into the a stream object, # upload_blob() read file data in batches to avoid OOM problems count = os.path.getsize(file_path) with open(file_path, 'rb') as stream: response = client.upload_blob(data=stream, length=count, metadata=metadata, encryption_scope=encryption_scope, **upload_args, **kwargs) # PageBlobChunkUploader verifies the file when uploading the chunk data, If the contents of the file are # all null byte("\x00"), the file will not be uploaded, and the response will be none. # Therefore, the compatibility logic for response is added to keep it consistent with track 1 if response is None: return { "etag": None, "lastModified": None } from msrest import Serializer if 'content_md5' in response and response['content_md5'] is not None: response['content_md5'] = Serializer.serialize_bytearray(response['content_md5']) if 'content_crc64' in response and response['content_crc64'] is not None: response['content_crc64'] = Serializer.serialize_bytearray(response['content_crc64']) return response
def transform_response_with_bytearray(response): """ transform bytearray to string """ from msrest import Serializer for item in response: if response[item] and isinstance(response[item], (bytes, bytearray)): response[item] = Serializer.serialize_bytearray(response[item]) return response
def get_file_properties(client, timeout=None): from .._transformers import transform_fs_access_output prop = client.get_file_properties(timeout=timeout) if prop.content_settings.content_md5 is not None: from msrest import Serializer prop.content_settings.content_md5 = Serializer.serialize_bytearray( prop.content_settings.content_md5) acl = transform_fs_access_output( client.get_access_control(timeout=timeout)) result = dict(prop, **acl) return result
def upload_blob(cmd, client, file_path, container_name=None, blob_name=None, blob_type=None, content_settings=None, metadata=None, validate_content=False, maxsize_condition=None, max_connections=2, lease_id=None, tier=None, if_modified_since=None, if_unmodified_since=None, if_match=None, if_none_match=None, timeout=None, progress_callback=None, encryption_scope=None): """Upload a blob to a container.""" if encryption_scope: count = os.path.getsize(file_path) with open(file_path, 'rb') as stream: data = stream.read(count) from azure.core import MatchConditions upload_args = { 'content_settings': content_settings, 'metadata': metadata, 'timeout': timeout, 'if_modified_since': if_modified_since, 'if_unmodified_since': if_unmodified_since, 'blob_type': transform_blob_type(cmd, blob_type), 'validate_content': validate_content, 'lease': lease_id, 'max_concurrency': max_connections, } if cmd.supported_api_version(min_api='2017-04-17') and tier: upload_args['premium_page_blob_tier'] = tier if maxsize_condition: upload_args['maxsize_condition'] = maxsize_condition if cmd.supported_api_version(min_api='2016-05-31'): upload_args['validate_content'] = validate_content # Precondition Check if if_match: if if_match == '*': upload_args['match_condition'] = MatchConditions.IfPresent else: upload_args['etag'] = if_match upload_args['match_condition'] = MatchConditions.IfNotModified if if_none_match: upload_args['etag'] = if_none_match upload_args['match_condition'] = MatchConditions.IfModified response = client.upload_blob(data=data, length=count, encryption_scope=encryption_scope, **upload_args) if response['content_md5'] is not None: from msrest import Serializer response['content_md5'] = Serializer.serialize_bytearray(response['content_md5']) return response t_content_settings = cmd.get_models('blob.models#ContentSettings') content_settings = guess_content_type(file_path, content_settings, t_content_settings) def upload_append_blob(): check_blob_args = { 'container_name': container_name, 'blob_name': blob_name, 'lease_id': lease_id, 'if_modified_since': if_modified_since, 'if_unmodified_since': if_unmodified_since, 'if_match': if_match, 'if_none_match': if_none_match, 'timeout': timeout } if client.exists(container_name, blob_name): # used to check for the preconditions as append_blob_from_path() cannot client.get_blob_properties(**check_blob_args) else: client.create_blob(content_settings=content_settings, metadata=metadata, **check_blob_args) append_blob_args = { 'container_name': container_name, 'blob_name': blob_name, 'file_path': file_path, 'progress_callback': progress_callback, 'maxsize_condition': maxsize_condition, 'lease_id': lease_id, 'timeout': timeout } if cmd.supported_api_version(min_api='2016-05-31'): append_blob_args['validate_content'] = validate_content return client.append_blob_from_path(**append_blob_args) def upload_block_blob(): # increase the block size to 100MB when the block list will contain more than 50,000 blocks if os.path.isfile(file_path) and os.stat(file_path).st_size > 50000 * 4 * 1024 * 1024: client.MAX_BLOCK_SIZE = 100 * 1024 * 1024 client.MAX_SINGLE_PUT_SIZE = 256 * 1024 * 1024 create_blob_args = { 'container_name': container_name, 'blob_name': blob_name, 'file_path': file_path, 'progress_callback': progress_callback, 'content_settings': content_settings, 'metadata': metadata, 'max_connections': max_connections, 'lease_id': lease_id, 'if_modified_since': if_modified_since, 'if_unmodified_since': if_unmodified_since, 'if_match': if_match, 'if_none_match': if_none_match, 'timeout': timeout } if cmd.supported_api_version(min_api='2017-04-17') and tier: create_blob_args['premium_page_blob_tier'] = tier if cmd.supported_api_version(min_api='2016-05-31'): create_blob_args['validate_content'] = validate_content return client.create_blob_from_path(**create_blob_args) type_func = { 'append': upload_append_blob, 'block': upload_block_blob, 'page': upload_block_blob # same implementation } return type_func[blob_type]()