# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------
import datetime
from typing import TYPE_CHECKING
import warnings

from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
from azure.core.pipeline import PipelineResponse
from azure.core.pipeline.transport import HttpRequest, HttpResponse

from .. import models as _models

if TYPE_CHECKING:
    # pylint: disable=unused-import,ungrouped-imports
    from typing import Any, Callable, Dict, Generic, IO, Optional, TypeVar, Union

    T = TypeVar('T')
    ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]]

class BlockBlobOperations(object):
    """BlockBlobOperations operations.

    You should not instantiate this class directly. Instead, you should create a Client instance that
    instantiates it for you and attaches it as an attribute.

    :ivar models: Alias to model classes used in this operation group.
    :type models: ~azure.storage.blob.models
    :param client: Client for service requests.
    :param config: Configuration of service client.
    :param serializer: An object model serializer.
    :param deserializer: An object model deserializer.
    """

    models = _models

    def __init__(self, client, config, serializer, deserializer):
        self._client = client
        self._serialize = serializer
        self._deserialize = deserializer
        self._config = config

    def upload(
        self,
        content_length,  # type: int
        body,  # type: IO
        timeout=None,  # type: Optional[int]
        transactional_content_md5=None,  # type: Optional[bytearray]
        metadata=None,  # type: Optional[str]
        encryption_algorithm="AES256",  # type: Optional[str]
        tier=None,  # type: Optional[Union[str, "_models.AccessTierOptional"]]
        request_id_parameter=None,  # type: Optional[str]
        blob_tags_string=None,  # type: Optional[str]
        blob_http_headers=None,  # type: Optional["_models.BlobHTTPHeaders"]
        lease_access_conditions=None,  # type: Optional["_models.LeaseAccessConditions"]
        cpk_info=None,  # type: Optional["_models.CpkInfo"]
        cpk_scope_info=None,  # type: Optional["_models.CpkScopeInfo"]
        modified_access_conditions=None,  # type: Optional["_models.ModifiedAccessConditions"]
        **kwargs  # type: Any
    ):
        # type: (...) -> None
        """The Upload Block Blob operation updates the content of an existing block blob. Updating an
        existing block blob overwrites any existing metadata on the blob. Partial updates are not
        supported with Put Blob; the content of the existing blob is overwritten with the content of
        the new blob. To perform a partial update of the content of a block blob, use the Put Block
        List operation.

        :param content_length: The length of the request.
        :type content_length: long
        :param body: Initial data.
        :type body: IO
        :param timeout: The timeout parameter is expressed in seconds. For more information, see
         :code:`<a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-
         timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>`.
        :type timeout: int
        :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
         by the service.
        :type transactional_content_md5: bytearray
        :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
         If no name-value pairs are specified, the operation will copy the metadata from the source blob
         or file to the destination blob. If one or more name-value pairs are specified, the destination
         blob is created with the specified metadata, and metadata is not copied from the source blob or
         file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
         rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
         information.
        :type metadata: str
        :param encryption_algorithm: The algorithm used to produce the encryption key hash. Currently,
         the only accepted value is "AES256". Must be provided if the x-ms-encryption-key header is
         provided.
        :type encryption_algorithm: str
        :param tier: Optional. Indicates the tier to be set on the blob.
        :type tier: str or ~azure.storage.blob.models.AccessTierOptional
        :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
         limit that is recorded in the analytics logs when storage analytics logging is enabled.
        :type request_id_parameter: str
        :param blob_tags_string: Optional.  Used to set blob tags in various blob operations.
        :type blob_tags_string: str
        :param blob_http_headers: Parameter group.
        :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
        :param lease_access_conditions: Parameter group.
        :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
        :param cpk_info: Parameter group.
        :type cpk_info: ~azure.storage.blob.models.CpkInfo
        :param cpk_scope_info: Parameter group.
        :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
        :param modified_access_conditions: Parameter group.
        :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: None, or the result of cls(response)
        :rtype: None
        :raises: ~azure.core.exceptions.HttpResponseError
        """
        cls = kwargs.pop('cls', None)  # type: ClsType[None]
        error_map = {
            401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
        }
        error_map.update(kwargs.pop('error_map', {}))
        
        _blob_content_type = None
        _blob_content_encoding = None
        _blob_content_language = None
        _blob_content_md5 = None
        _blob_cache_control = None
        _lease_id = None
        _blob_content_disposition = None
        _encryption_key = None
        _encryption_key_sha256 = None
        _encryption_scope = None
        _if_modified_since = None
        _if_unmodified_since = None
        _if_match = None
        _if_none_match = None
        _if_tags = None
        if blob_http_headers is not None:
            _blob_content_type = blob_http_headers.blob_content_type
            _blob_content_encoding = blob_http_headers.blob_content_encoding
            _blob_content_language = blob_http_headers.blob_content_language
            _blob_content_md5 = blob_http_headers.blob_content_md5
            _blob_cache_control = blob_http_headers.blob_cache_control
            _blob_content_disposition = blob_http_headers.blob_content_disposition
        if cpk_info is not None:
            _encryption_key = cpk_info.encryption_key
            _encryption_key_sha256 = cpk_info.encryption_key_sha256
        if cpk_scope_info is not None:
            _encryption_scope = cpk_scope_info.encryption_scope
        if lease_access_conditions is not None:
            _lease_id = lease_access_conditions.lease_id
        if modified_access_conditions is not None:
            _if_modified_since = modified_access_conditions.if_modified_since
            _if_unmodified_since = modified_access_conditions.if_unmodified_since
            _if_match = modified_access_conditions.if_match
            _if_none_match = modified_access_conditions.if_none_match
            _if_tags = modified_access_conditions.if_tags
        blob_type = "BlockBlob"
        content_type = kwargs.pop("content_type", "application/octet-stream")
        accept = "application/xml"

        # Construct URL
        url = self.upload.metadata['url']  # type: ignore
        path_format_arguments = {
            'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}  # type: Dict[str, Any]
        if timeout is not None:
            query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)

        # Construct headers
        header_parameters = {}  # type: Dict[str, Any]
        header_parameters['x-ms-blob-type'] = self._serialize.header("blob_type", blob_type, 'str')
        if transactional_content_md5 is not None:
            header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
        header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
        if _blob_content_type is not None:
            header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
        if _blob_content_encoding is not None:
            header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
        if _blob_content_language is not None:
            header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
        if _blob_content_md5 is not None:
            header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
        if _blob_cache_control is not None:
            header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
        if metadata is not None:
            header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
        if _lease_id is not None:
            header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
        if _blob_content_disposition is not None:
            header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
        if _encryption_key is not None:
            header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
        if _encryption_key_sha256 is not None:
            header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
        if encryption_algorithm is not None:
            header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", encryption_algorithm, 'str')
        if _encryption_scope is not None:
            header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
        if tier is not None:
            header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
        if _if_modified_since is not None:
            header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
        if _if_unmodified_since is not None:
            header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
        if _if_match is not None:
            header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
        if _if_none_match is not None:
            header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
        if _if_tags is not None:
            header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
        header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
        if request_id_parameter is not None:
            header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
        if blob_tags_string is not None:
            header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
        header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
        header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

        body_content_kwargs = {}  # type: Dict[str, Any]
        body_content_kwargs['stream_content'] = body
        request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
        pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
        response = pipeline_response.http_response

        if response.status_code not in [201]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = self._deserialize(_models.StorageError, response)
            raise HttpResponseError(response=response, model=error)

        response_headers = {}
        response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
        response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
        response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
        response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
        response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
        response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
        response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
        response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
        response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
        response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
        response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))

        if cls:
            return cls(pipeline_response, None, response_headers)

    upload.metadata = {'url': '/{containerName}/{blob}'}  # type: ignore

    def put_blob_from_url(
        self,
        content_length,  # type: int
        copy_source,  # type: str
        timeout=None,  # type: Optional[int]
        transactional_content_md5=None,  # type: Optional[bytearray]
        metadata=None,  # type: Optional[str]
        encryption_algorithm="AES256",  # type: Optional[str]
        tier=None,  # type: Optional[Union[str, "_models.AccessTierOptional"]]
        request_id_parameter=None,  # type: Optional[str]
        source_content_md5=None,  # type: Optional[bytearray]
        blob_tags_string=None,  # type: Optional[str]
        copy_source_blob_properties=None,  # type: Optional[bool]
        blob_http_headers=None,  # type: Optional["_models.BlobHTTPHeaders"]
        lease_access_conditions=None,  # type: Optional["_models.LeaseAccessConditions"]
        cpk_info=None,  # type: Optional["_models.CpkInfo"]
        cpk_scope_info=None,  # type: Optional["_models.CpkScopeInfo"]
        modified_access_conditions=None,  # type: Optional["_models.ModifiedAccessConditions"]
        source_modified_access_conditions=None,  # type: Optional["_models.SourceModifiedAccessConditions"]
        **kwargs  # type: Any
    ):
        # type: (...) -> None
        """The Put Blob from URL operation creates a new Block Blob where the contents of the blob are
        read from a given URL.  This API is supported beginning with the 2020-04-08 version. Partial
        updates are not supported with Put Blob from URL; the content of an existing blob is
        overwritten with the content of the new blob.  To perform partial updates to a block blob’s
        contents using a source URL, use the Put Block from URL API in conjunction with Put Block List.

        :param content_length: The length of the request.
        :type content_length: long
        :param copy_source: Specifies the name of the source page blob snapshot. This value is a URL of
         up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it
         would appear in a request URI. The source blob must either be public or must be authenticated
         via a shared access signature.
        :type copy_source: str
        :param timeout: The timeout parameter is expressed in seconds. For more information, see
         :code:`<a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-
         timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>`.
        :type timeout: int
        :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
         by the service.
        :type transactional_content_md5: bytearray
        :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
         If no name-value pairs are specified, the operation will copy the metadata from the source blob
         or file to the destination blob. If one or more name-value pairs are specified, the destination
         blob is created with the specified metadata, and metadata is not copied from the source blob or
         file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
         rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
         information.
        :type metadata: str
        :param encryption_algorithm: The algorithm used to produce the encryption key hash. Currently,
         the only accepted value is "AES256". Must be provided if the x-ms-encryption-key header is
         provided.
        :type encryption_algorithm: str
        :param tier: Optional. Indicates the tier to be set on the blob.
        :type tier: str or ~azure.storage.blob.models.AccessTierOptional
        :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
         limit that is recorded in the analytics logs when storage analytics logging is enabled.
        :type request_id_parameter: str
        :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
         from the copy source.
        :type source_content_md5: bytearray
        :param blob_tags_string: Optional.  Used to set blob tags in various blob operations.
        :type blob_tags_string: str
        :param copy_source_blob_properties: Optional, default is true.  Indicates if properties from
         the source blob should be copied.
        :type copy_source_blob_properties: bool
        :param blob_http_headers: Parameter group.
        :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
        :param lease_access_conditions: Parameter group.
        :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
        :param cpk_info: Parameter group.
        :type cpk_info: ~azure.storage.blob.models.CpkInfo
        :param cpk_scope_info: Parameter group.
        :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
        :param modified_access_conditions: Parameter group.
        :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
        :param source_modified_access_conditions: Parameter group.
        :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: None, or the result of cls(response)
        :rtype: None
        :raises: ~azure.core.exceptions.HttpResponseError
        """
        cls = kwargs.pop('cls', None)  # type: ClsType[None]
        error_map = {
            401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
        }
        error_map.update(kwargs.pop('error_map', {}))
        
        _blob_content_type = None
        _blob_content_encoding = None
        _blob_content_language = None
        _blob_content_md5 = None
        _blob_cache_control = None
        _lease_id = None
        _blob_content_disposition = None
        _encryption_key = None
        _encryption_key_sha256 = None
        _encryption_scope = None
        _if_modified_since = None
        _if_unmodified_since = None
        _if_match = None
        _if_none_match = None
        _if_tags = None
        _source_if_modified_since = None
        _source_if_unmodified_since = None
        _source_if_match = None
        _source_if_none_match = None
        _source_if_tags = None
        if blob_http_headers is not None:
            _blob_content_type = blob_http_headers.blob_content_type
            _blob_content_encoding = blob_http_headers.blob_content_encoding
            _blob_content_language = blob_http_headers.blob_content_language
            _blob_content_md5 = blob_http_headers.blob_content_md5
            _blob_cache_control = blob_http_headers.blob_cache_control
            _blob_content_disposition = blob_http_headers.blob_content_disposition
        if cpk_info is not None:
            _encryption_key = cpk_info.encryption_key
            _encryption_key_sha256 = cpk_info.encryption_key_sha256
        if cpk_scope_info is not None:
            _encryption_scope = cpk_scope_info.encryption_scope
        if lease_access_conditions is not None:
            _lease_id = lease_access_conditions.lease_id
        if modified_access_conditions is not None:
            _if_modified_since = modified_access_conditions.if_modified_since
            _if_unmodified_since = modified_access_conditions.if_unmodified_since
            _if_match = modified_access_conditions.if_match
            _if_none_match = modified_access_conditions.if_none_match
            _if_tags = modified_access_conditions.if_tags
        if source_modified_access_conditions is not None:
            _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
            _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
            _source_if_match = source_modified_access_conditions.source_if_match
            _source_if_none_match = source_modified_access_conditions.source_if_none_match
            _source_if_tags = source_modified_access_conditions.source_if_tags
        blob_type = "BlockBlob"
        accept = "application/xml"

        # Construct URL
        url = self.put_blob_from_url.metadata['url']  # type: ignore
        path_format_arguments = {
            'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}  # type: Dict[str, Any]
        if timeout is not None:
            query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)

        # Construct headers
        header_parameters = {}  # type: Dict[str, Any]
        header_parameters['x-ms-blob-type'] = self._serialize.header("blob_type", blob_type, 'str')
        if transactional_content_md5 is not None:
            header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
        header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
        if _blob_content_type is not None:
            header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
        if _blob_content_encoding is not None:
            header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
        if _blob_content_language is not None:
            header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
        if _blob_content_md5 is not None:
            header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
        if _blob_cache_control is not None:
            header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
        if metadata is not None:
            header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
        if _lease_id is not None:
            header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
        if _blob_content_disposition is not None:
            header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
        if _encryption_key is not None:
            header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
        if _encryption_key_sha256 is not None:
            header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
        if encryption_algorithm is not None:
            header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", encryption_algorithm, 'str')
        if _encryption_scope is not None:
            header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
        if tier is not None:
            header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
        if _if_modified_since is not None:
            header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
        if _if_unmodified_since is not None:
            header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
        if _if_match is not None:
            header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
        if _if_none_match is not None:
            header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
        if _if_tags is not None:
            header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
        if _source_if_modified_since is not None:
            header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
        if _source_if_unmodified_since is not None:
            header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
        if _source_if_match is not None:
            header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
        if _source_if_none_match is not None:
            header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
        if _source_if_tags is not None:
            header_parameters['x-ms-source-if-tags'] = self._serialize.header("source_if_tags", _source_if_tags, 'str')
        header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
        if request_id_parameter is not None:
            header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
        if source_content_md5 is not None:
            header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
        if blob_tags_string is not None:
            header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
        header_parameters['x-ms-copy-source'] = self._serialize.header("copy_source", copy_source, 'str')
        if copy_source_blob_properties is not None:
            header_parameters['x-ms-copy-source-blob-properties'] = self._serialize.header("copy_source_blob_properties", copy_source_blob_properties, 'bool')
        header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

        request = self._client.put(url, query_parameters, header_parameters)
        pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
        response = pipeline_response.http_response

        if response.status_code not in [201]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = self._deserialize(_models.StorageError, response)
            raise HttpResponseError(response=response, model=error)

        response_headers = {}
        response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
        response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
        response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
        response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
        response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
        response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
        response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
        response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
        response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
        response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
        response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))

        if cls:
            return cls(pipeline_response, None, response_headers)

    put_blob_from_url.metadata = {'url': '/{containerName}/{blob}'}  # type: ignore

    def stage_block(
        self,
        block_id,  # type: str
        content_length,  # type: int
        body,  # type: IO
        transactional_content_md5=None,  # type: Optional[bytearray]
        transactional_content_crc64=None,  # type: Optional[bytearray]
        timeout=None,  # type: Optional[int]
        encryption_algorithm="AES256",  # type: Optional[str]
        request_id_parameter=None,  # type: Optional[str]
        lease_access_conditions=None,  # type: Optional["_models.LeaseAccessConditions"]
        cpk_info=None,  # type: Optional["_models.CpkInfo"]
        cpk_scope_info=None,  # type: Optional["_models.CpkScopeInfo"]
        **kwargs  # type: Any
    ):
        # type: (...) -> None
        """The Stage Block operation creates a new block to be committed as part of a blob.

        :param block_id: A valid Base64 string value that identifies the block. Prior to encoding, the
         string must be less than or equal to 64 bytes in size. For a given blob, the length of the
         value specified for the blockid parameter must be the same size for each block.
        :type block_id: str
        :param content_length: The length of the request.
        :type content_length: long
        :param body: Initial data.
        :type body: IO
        :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
         by the service.
        :type transactional_content_md5: bytearray
        :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
         validated by the service.
        :type transactional_content_crc64: bytearray
        :param timeout: The timeout parameter is expressed in seconds. For more information, see
         :code:`<a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-
         timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>`.
        :type timeout: int
        :param encryption_algorithm: The algorithm used to produce the encryption key hash. Currently,
         the only accepted value is "AES256". Must be provided if the x-ms-encryption-key header is
         provided.
        :type encryption_algorithm: str
        :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
         limit that is recorded in the analytics logs when storage analytics logging is enabled.
        :type request_id_parameter: str
        :param lease_access_conditions: Parameter group.
        :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
        :param cpk_info: Parameter group.
        :type cpk_info: ~azure.storage.blob.models.CpkInfo
        :param cpk_scope_info: Parameter group.
        :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: None, or the result of cls(response)
        :rtype: None
        :raises: ~azure.core.exceptions.HttpResponseError
        """
        cls = kwargs.pop('cls', None)  # type: ClsType[None]
        error_map = {
            401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
        }
        error_map.update(kwargs.pop('error_map', {}))
        
        _lease_id = None
        _encryption_key = None
        _encryption_key_sha256 = None
        _encryption_scope = None
        if cpk_info is not None:
            _encryption_key = cpk_info.encryption_key
            _encryption_key_sha256 = cpk_info.encryption_key_sha256
        if cpk_scope_info is not None:
            _encryption_scope = cpk_scope_info.encryption_scope
        if lease_access_conditions is not None:
            _lease_id = lease_access_conditions.lease_id
        comp = "block"
        content_type = kwargs.pop("content_type", "application/octet-stream")
        accept = "application/xml"

        # Construct URL
        url = self.stage_block.metadata['url']  # type: ignore
        path_format_arguments = {
            'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}  # type: Dict[str, Any]
        query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
        query_parameters['blockid'] = self._serialize.query("block_id", block_id, 'str')
        if timeout is not None:
            query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)

        # Construct headers
        header_parameters = {}  # type: Dict[str, Any]
        header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
        if transactional_content_md5 is not None:
            header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
        if transactional_content_crc64 is not None:
            header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
        if _lease_id is not None:
            header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
        if _encryption_key is not None:
            header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
        if _encryption_key_sha256 is not None:
            header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
        if encryption_algorithm is not None:
            header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", encryption_algorithm, 'str')
        if _encryption_scope is not None:
            header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
        header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
        if request_id_parameter is not None:
            header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
        header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
        header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

        body_content_kwargs = {}  # type: Dict[str, Any]
        body_content_kwargs['stream_content'] = body
        request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
        pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
        response = pipeline_response.http_response

        if response.status_code not in [201]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = self._deserialize(_models.StorageError, response)
            raise HttpResponseError(response=response, model=error)

        response_headers = {}
        response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
        response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
        response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
        response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
        response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
        response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
        response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
        response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
        response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))

        if cls:
            return cls(pipeline_response, None, response_headers)

    stage_block.metadata = {'url': '/{containerName}/{blob}'}  # type: ignore

    def stage_block_from_url(
        self,
        block_id,  # type: str
        content_length,  # type: int
        source_url,  # type: str
        source_range=None,  # type: Optional[str]
        source_content_md5=None,  # type: Optional[bytearray]
        source_contentcrc64=None,  # type: Optional[bytearray]
        timeout=None,  # type: Optional[int]
        encryption_algorithm="AES256",  # type: Optional[str]
        request_id_parameter=None,  # type: Optional[str]
        cpk_info=None,  # type: Optional["_models.CpkInfo"]
        cpk_scope_info=None,  # type: Optional["_models.CpkScopeInfo"]
        lease_access_conditions=None,  # type: Optional["_models.LeaseAccessConditions"]
        source_modified_access_conditions=None,  # type: Optional["_models.SourceModifiedAccessConditions"]
        **kwargs  # type: Any
    ):
        # type: (...) -> None
        """The Stage Block operation creates a new block to be committed as part of a blob where the
        contents are read from a URL.

        :param block_id: A valid Base64 string value that identifies the block. Prior to encoding, the
         string must be less than or equal to 64 bytes in size. For a given blob, the length of the
         value specified for the blockid parameter must be the same size for each block.
        :type block_id: str
        :param content_length: The length of the request.
        :type content_length: long
        :param source_url: Specify a URL to the copy source.
        :type source_url: str
        :param source_range: Bytes of source data in the specified range.
        :type source_range: str
        :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
         from the copy source.
        :type source_content_md5: bytearray
        :param source_contentcrc64: Specify the crc64 calculated for the range of bytes that must be
         read from the copy source.
        :type source_contentcrc64: bytearray
        :param timeout: The timeout parameter is expressed in seconds. For more information, see
         :code:`<a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-
         timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>`.
        :type timeout: int
        :param encryption_algorithm: The algorithm used to produce the encryption key hash. Currently,
         the only accepted value is "AES256". Must be provided if the x-ms-encryption-key header is
         provided.
        :type encryption_algorithm: str
        :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
         limit that is recorded in the analytics logs when storage analytics logging is enabled.
        :type request_id_parameter: str
        :param cpk_info: Parameter group.
        :type cpk_info: ~azure.storage.blob.models.CpkInfo
        :param cpk_scope_info: Parameter group.
        :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
        :param lease_access_conditions: Parameter group.
        :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
        :param source_modified_access_conditions: Parameter group.
        :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: None, or the result of cls(response)
        :rtype: None
        :raises: ~azure.core.exceptions.HttpResponseError
        """
        cls = kwargs.pop('cls', None)  # type: ClsType[None]
        error_map = {
            401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
        }
        error_map.update(kwargs.pop('error_map', {}))
        
        _encryption_key = None
        _encryption_key_sha256 = None
        _encryption_scope = None
        _lease_id = None
        _source_if_modified_since = None
        _source_if_unmodified_since = None
        _source_if_match = None
        _source_if_none_match = None
        if cpk_info is not None:
            _encryption_key = cpk_info.encryption_key
            _encryption_key_sha256 = cpk_info.encryption_key_sha256
        if cpk_scope_info is not None:
            _encryption_scope = cpk_scope_info.encryption_scope
        if lease_access_conditions is not None:
            _lease_id = lease_access_conditions.lease_id
        if source_modified_access_conditions is not None:
            _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
            _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
            _source_if_match = source_modified_access_conditions.source_if_match
            _source_if_none_match = source_modified_access_conditions.source_if_none_match
        comp = "block"
        accept = "application/xml"

        # Construct URL
        url = self.stage_block_from_url.metadata['url']  # type: ignore
        path_format_arguments = {
            'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}  # type: Dict[str, Any]
        query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
        query_parameters['blockid'] = self._serialize.query("block_id", block_id, 'str')
        if timeout is not None:
            query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)

        # Construct headers
        header_parameters = {}  # type: Dict[str, Any]
        header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
        header_parameters['x-ms-copy-source'] = self._serialize.header("source_url", source_url, 'str')
        if source_range is not None:
            header_parameters['x-ms-source-range'] = self._serialize.header("source_range", source_range, 'str')
        if source_content_md5 is not None:
            header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
        if source_contentcrc64 is not None:
            header_parameters['x-ms-source-content-crc64'] = self._serialize.header("source_contentcrc64", source_contentcrc64, 'bytearray')
        if _encryption_key is not None:
            header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
        if _encryption_key_sha256 is not None:
            header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
        if encryption_algorithm is not None:
            header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", encryption_algorithm, 'str')
        if _encryption_scope is not None:
            header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
        if _lease_id is not None:
            header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
        if _source_if_modified_since is not None:
            header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
        if _source_if_unmodified_since is not None:
            header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
        if _source_if_match is not None:
            header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
        if _source_if_none_match is not None:
            header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
        header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
        if request_id_parameter is not None:
            header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
        header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

        request = self._client.put(url, query_parameters, header_parameters)
        pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
        response = pipeline_response.http_response

        if response.status_code not in [201]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = self._deserialize(_models.StorageError, response)
            raise HttpResponseError(response=response, model=error)

        response_headers = {}
        response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
        response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
        response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
        response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
        response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
        response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
        response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
        response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
        response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))

        if cls:
            return cls(pipeline_response, None, response_headers)

    stage_block_from_url.metadata = {'url': '/{containerName}/{blob}'}  # type: ignore

    def commit_block_list(
        self,
        blocks,  # type: "_models.BlockLookupList"
        timeout=None,  # type: Optional[int]
        transactional_content_md5=None,  # type: Optional[bytearray]
        transactional_content_crc64=None,  # type: Optional[bytearray]
        metadata=None,  # type: Optional[str]
        encryption_algorithm="AES256",  # type: Optional[str]
        tier=None,  # type: Optional[Union[str, "_models.AccessTierOptional"]]
        request_id_parameter=None,  # type: Optional[str]
        blob_tags_string=None,  # type: Optional[str]
        blob_http_headers=None,  # type: Optional["_models.BlobHTTPHeaders"]
        lease_access_conditions=None,  # type: Optional["_models.LeaseAccessConditions"]
        cpk_info=None,  # type: Optional["_models.CpkInfo"]
        cpk_scope_info=None,  # type: Optional["_models.CpkScopeInfo"]
        modified_access_conditions=None,  # type: Optional["_models.ModifiedAccessConditions"]
        **kwargs  # type: Any
    ):
        # type: (...) -> None
        """The Commit Block List operation writes a blob by specifying the list of block IDs that make up
        the blob. In order to be written as part of a blob, a block must have been successfully written
        to the server in a prior Put Block operation. You can call Put Block List to update a blob by
        uploading only those blocks that have changed, then committing the new and existing blocks
        together. You can do this by specifying whether to commit a block from the committed block list
        or from the uncommitted block list, or to commit the most recently uploaded version of the
        block, whichever list it may belong to.

        :param blocks:
        :type blocks: ~azure.storage.blob.models.BlockLookupList
        :param timeout: The timeout parameter is expressed in seconds. For more information, see
         :code:`<a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-
         timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>`.
        :type timeout: int
        :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
         by the service.
        :type transactional_content_md5: bytearray
        :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
         validated by the service.
        :type transactional_content_crc64: bytearray
        :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
         If no name-value pairs are specified, the operation will copy the metadata from the source blob
         or file to the destination blob. If one or more name-value pairs are specified, the destination
         blob is created with the specified metadata, and metadata is not copied from the source blob or
         file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
         rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
         information.
        :type metadata: str
        :param encryption_algorithm: The algorithm used to produce the encryption key hash. Currently,
         the only accepted value is "AES256". Must be provided if the x-ms-encryption-key header is
         provided.
        :type encryption_algorithm: str
        :param tier: Optional. Indicates the tier to be set on the blob.
        :type tier: str or ~azure.storage.blob.models.AccessTierOptional
        :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
         limit that is recorded in the analytics logs when storage analytics logging is enabled.
        :type request_id_parameter: str
        :param blob_tags_string: Optional.  Used to set blob tags in various blob operations.
        :type blob_tags_string: str
        :param blob_http_headers: Parameter group.
        :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
        :param lease_access_conditions: Parameter group.
        :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
        :param cpk_info: Parameter group.
        :type cpk_info: ~azure.storage.blob.models.CpkInfo
        :param cpk_scope_info: Parameter group.
        :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
        :param modified_access_conditions: Parameter group.
        :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: None, or the result of cls(response)
        :rtype: None
        :raises: ~azure.core.exceptions.HttpResponseError
        """
        cls = kwargs.pop('cls', None)  # type: ClsType[None]
        error_map = {
            401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
        }
        error_map.update(kwargs.pop('error_map', {}))
        
        _blob_cache_control = None
        _blob_content_type = None
        _blob_content_encoding = None
        _blob_content_language = None
        _blob_content_md5 = None
        _lease_id = None
        _blob_content_disposition = None
        _encryption_key = None
        _encryption_key_sha256 = None
        _encryption_scope = None
        _if_modified_since = None
        _if_unmodified_since = None
        _if_match = None
        _if_none_match = None
        _if_tags = None
        if blob_http_headers is not None:
            _blob_cache_control = blob_http_headers.blob_cache_control
            _blob_content_type = blob_http_headers.blob_content_type
            _blob_content_encoding = blob_http_headers.blob_content_encoding
            _blob_content_language = blob_http_headers.blob_content_language
            _blob_content_md5 = blob_http_headers.blob_content_md5
            _blob_content_disposition = blob_http_headers.blob_content_disposition
        if cpk_info is not None:
            _encryption_key = cpk_info.encryption_key
            _encryption_key_sha256 = cpk_info.encryption_key_sha256
        if cpk_scope_info is not None:
            _encryption_scope = cpk_scope_info.encryption_scope
        if lease_access_conditions is not None:
            _lease_id = lease_access_conditions.lease_id
        if modified_access_conditions is not None:
            _if_modified_since = modified_access_conditions.if_modified_since
            _if_unmodified_since = modified_access_conditions.if_unmodified_since
            _if_match = modified_access_conditions.if_match
            _if_none_match = modified_access_conditions.if_none_match
            _if_tags = modified_access_conditions.if_tags
        comp = "blocklist"
        content_type = kwargs.pop("content_type", "application/xml")
        accept = "application/xml"

        # Construct URL
        url = self.commit_block_list.metadata['url']  # type: ignore
        path_format_arguments = {
            'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}  # type: Dict[str, Any]
        query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
        if timeout is not None:
            query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)

        # Construct headers
        header_parameters = {}  # type: Dict[str, Any]
        if _blob_cache_control is not None:
            header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
        if _blob_content_type is not None:
            header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
        if _blob_content_encoding is not None:
            header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
        if _blob_content_language is not None:
            header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
        if _blob_content_md5 is not None:
            header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
        if transactional_content_md5 is not None:
            header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
        if transactional_content_crc64 is not None:
            header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
        if metadata is not None:
            header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
        if _lease_id is not None:
            header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
        if _blob_content_disposition is not None:
            header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
        if _encryption_key is not None:
            header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
        if _encryption_key_sha256 is not None:
            header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
        if encryption_algorithm is not None:
            header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", encryption_algorithm, 'str')
        if _encryption_scope is not None:
            header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
        if tier is not None:
            header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
        if _if_modified_since is not None:
            header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
        if _if_unmodified_since is not None:
            header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
        if _if_match is not None:
            header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
        if _if_none_match is not None:
            header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
        if _if_tags is not None:
            header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
        header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
        if request_id_parameter is not None:
            header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
        if blob_tags_string is not None:
            header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
        header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
        header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

        body_content_kwargs = {}  # type: Dict[str, Any]
        body_content = self._serialize.body(blocks, 'BlockLookupList', is_xml=True)
        body_content_kwargs['content'] = body_content
        request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
        pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
        response = pipeline_response.http_response

        if response.status_code not in [201]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = self._deserialize(_models.StorageError, response)
            raise HttpResponseError(response=response, model=error)

        response_headers = {}
        response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
        response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
        response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
        response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
        response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
        response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
        response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
        response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
        response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
        response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
        response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
        response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))

        if cls:
            return cls(pipeline_response, None, response_headers)

    commit_block_list.metadata = {'url': '/{containerName}/{blob}'}  # type: ignore

    def get_block_list(
        self,
        snapshot=None,  # type: Optional[str]
        list_type="committed",  # type: Union[str, "_models.BlockListType"]
        timeout=None,  # type: Optional[int]
        request_id_parameter=None,  # type: Optional[str]
        lease_access_conditions=None,  # type: Optional["_models.LeaseAccessConditions"]
        modified_access_conditions=None,  # type: Optional["_models.ModifiedAccessConditions"]
        **kwargs  # type: Any
    ):
        # type: (...) -> "_models.BlockList"
        """The Get Block List operation retrieves the list of blocks that have been uploaded as part of a
        block blob.

        :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
         specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
         see :code:`<a href="https://docs.microsoft.com/en-
         us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of
         a Blob.</a>`.
        :type snapshot: str
        :param list_type: Specifies whether to return the list of committed blocks, the list of
         uncommitted blocks, or both lists together.
        :type list_type: str or ~azure.storage.blob.models.BlockListType
        :param timeout: The timeout parameter is expressed in seconds. For more information, see
         :code:`<a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-
         timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>`.
        :type timeout: int
        :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
         limit that is recorded in the analytics logs when storage analytics logging is enabled.
        :type request_id_parameter: str
        :param lease_access_conditions: Parameter group.
        :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
        :param modified_access_conditions: Parameter group.
        :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: BlockList, or the result of cls(response)
        :rtype: ~azure.storage.blob.models.BlockList
        :raises: ~azure.core.exceptions.HttpResponseError
        """
        cls = kwargs.pop('cls', None)  # type: ClsType["_models.BlockList"]
        error_map = {
            401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
        }
        error_map.update(kwargs.pop('error_map', {}))
        
        _lease_id = None
        _if_tags = None
        if lease_access_conditions is not None:
            _lease_id = lease_access_conditions.lease_id
        if modified_access_conditions is not None:
            _if_tags = modified_access_conditions.if_tags
        comp = "blocklist"
        accept = "application/xml"

        # Construct URL
        url = self.get_block_list.metadata['url']  # type: ignore
        path_format_arguments = {
            'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}  # type: Dict[str, Any]
        query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
        if snapshot is not None:
            query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
        query_parameters['blocklisttype'] = self._serialize.query("list_type", list_type, 'str')
        if timeout is not None:
            query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)

        # Construct headers
        header_parameters = {}  # type: Dict[str, Any]
        if _lease_id is not None:
            header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
        if _if_tags is not None:
            header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
        header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
        if request_id_parameter is not None:
            header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
        header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

        request = self._client.get(url, query_parameters, header_parameters)
        pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = self._deserialize(_models.StorageError, response)
            raise HttpResponseError(response=response, model=error)

        response_headers = {}
        response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
        response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
        response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
        response_headers['x-ms-blob-content-length']=self._deserialize('long', response.headers.get('x-ms-blob-content-length'))
        response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
        response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
        response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
        response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
        deserialized = self._deserialize('BlockList', pipeline_response)

        if cls:
            return cls(pipeline_response, deserialized, response_headers)

        return deserialized
    get_block_list.metadata = {'url': '/{containerName}/{blob}'}  # type: ignore
