Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Blob][Datalake] STG76 Preview #16349

Merged
merged 12 commits into from
Feb 3, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -574,9 +574,40 @@ def delete_container(
timeout=timeout,
**kwargs)

@distributed_trace
def _rename_container(self, name, new_name, **kwargs):
# type: (str, str, **Any) -> ContainerClient
"""Renames a container.

Operation is successful only if the source container exists.

:param str name:
The name of the container to rename.
:param str new_name:
The new container name the user wants to rename to.
:keyword lease:
Specify this to perform only if the lease ID given
matches the active lease ID of the source container.
:paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
:keyword int timeout:
The timeout parameter is expressed in seconds.
:rtype: ~azure.storage.blob.ContainerClient
"""
renamed_container = self.get_container_client(new_name)
lease = kwargs.pop('lease', None)
try:
kwargs['source_lease_id'] = lease.id # type: str
except AttributeError:
kwargs['source_lease_id'] = lease
try:
renamed_container._client.container.rename(name, **kwargs) # pylint: disable = protected-access
return renamed_container
except HttpResponseError as error:
process_storage_error(error)

@distributed_trace
def undelete_container(self, deleted_container_name, deleted_container_version, **kwargs):
# type: (str, str, str, **Any) -> ContainerClient
# type: (str, str, **Any) -> ContainerClient
"""Restores soft-deleted container.

Operation will only be successful if used within the specified number of days
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,40 @@ def create_container(self, metadata=None, public_access=None, **kwargs):
except HttpResponseError as error:
process_storage_error(error)

@distributed_trace
def _rename_container(self, new_name, **kwargs):
# type: (str, **Any) -> ContainerClient
"""Renames a container.

Operation is successful only if the source container exists.

:param str new_name:
The new container name the user wants to rename to.
:keyword lease:
Specify this to perform only if the lease ID given
matches the active lease ID of the source container.
:paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
:keyword int timeout:
The timeout parameter is expressed in seconds.
:rtype: ~azure.storage.blob.ContainerClient
"""
lease = kwargs.pop('lease', None)
try:
kwargs['source_lease_id'] = lease.id # type: str
except AttributeError:
kwargs['source_lease_id'] = lease
try:
renamed_container = ContainerClient(
"{}://{}".format(self.scheme, self.primary_hostname), container_name=new_name,
credential=self.credential, api_version=self.api_version, _configuration=self._config,
_pipeline=self._pipeline, _location_mode=self._location_mode, _hosts=self._hosts,
require_encryption=self.require_encryption, key_encryption_key=self.key_encryption_key,
key_resolver_function=self.key_resolver_function)
renamed_container._client.container.rename(self.container_name, **kwargs) # pylint: disable = protected-access
return renamed_container
except HttpResponseError as error:
process_storage_error(error)

@distributed_trace
def delete_container(
self, **kwargs):
Expand Down Expand Up @@ -1096,7 +1130,9 @@ def _generate_delete_blobs_options(self,
if_tags_match_condition = kwargs.pop('if_tags_match_condition', None)
kwargs.update({'raise_on_any_failure': raise_on_any_failure,
'sas': self._query_str.replace('?', '&'),
'timeout': '&timeout=' + str(timeout) if timeout else ""
'timeout': '&timeout=' + str(timeout) if timeout else "",
'path': self.container_name,
'restype': 'restype=container&'
})

reqs = []
Expand Down Expand Up @@ -1278,7 +1314,9 @@ def _generate_set_tiers_options(self,
if_tags = kwargs.pop('if_tags_match_condition', None)
kwargs.update({'raise_on_any_failure': raise_on_any_failure,
'sas': self._query_str.replace('?', '&'),
'timeout': '&timeout=' + str(timeout) if timeout else ""
'timeout': '&timeout=' + str(timeout) if timeout else "",
'path': self.container_name,
'restype': 'restype=container&'
})

reqs = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ async def download(
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['x-ms-is-current-version']=self._deserialize('bool', response.headers.get('x-ms-is-current-version'))
response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
Expand Down Expand Up @@ -254,6 +255,7 @@ async def download(
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['x-ms-is-current-version']=self._deserialize('bool', response.headers.get('x-ms-is-current-version'))
response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------
import datetime
from typing import Any, Callable, Dict, Generic, List, Optional, TypeVar, Union
from typing import Any, Callable, Dict, Generic, IO, List, Optional, TypeVar, Union
import warnings

from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
Expand Down Expand Up @@ -699,6 +699,174 @@ async def restore(

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

async def rename(
self,
source_container_name: str,
timeout: Optional[int] = None,
request_id_parameter: Optional[str] = None,
source_lease_id: Optional[str] = None,
**kwargs
) -> None:
"""Renames an existing container.

:param source_container_name: Required. Specifies the name of the container to rename.
:type source_container_name: 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 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_lease_id: A lease ID for the source path. If specified, the source path must have
an active lease and the lease ID must match.
:type source_lease_id: str
: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', {}))
restype = "container"
comp = "rename"
accept = "application/xml"

# Construct URL
url = self.rename.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['restype'] = self._serialize.query("restype", restype, 'str')
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]
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['x-ms-source-container-name'] = self._serialize.header("source_container_name", source_container_name, 'str')
if source_lease_id is not None:
header_parameters['x-ms-source-lease-id'] = self._serialize.header("source_lease_id", source_lease_id, 'str')
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

request = self._client.put(url, query_parameters, header_parameters)
pipeline_response = await 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['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'))

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

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

async def submit_batch(
self,
content_length: int,
multipart_content_type: str,
body: IO,
timeout: Optional[int] = None,
request_id_parameter: Optional[str] = None,
**kwargs
) -> IO:
"""The Batch operation allows multiple API calls to be embedded into a single HTTP request.

:param content_length: The length of the request.
:type content_length: long
:param multipart_content_type: Required. The value of this header must be multipart/mixed with
a batch boundary. Example header value: multipart/mixed; boundary=batch_:code:`<GUID>`.
:type multipart_content_type: str
: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 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
:keyword callable cls: A custom type or function that will be passed the direct response
:return: IO, or the result of cls(response)
:rtype: IO
:raises: ~azure.core.exceptions.HttpResponseError
"""
cls = kwargs.pop('cls', None) # type: ClsType[IO]
error_map = {
401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
}
error_map.update(kwargs.pop('error_map', {}))
restype = "container"
comp = "batch"
content_type = kwargs.pop("content_type", "application/xml")
accept = "application/xml"

# Construct URL
url = self.submit_batch.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['restype'] = self._serialize.query("restype", restype, 'str')
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]
header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
header_parameters['Content-Type'] = self._serialize.header("multipart_content_type", multipart_content_type, '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 = self._serialize.body(body, 'IO', is_xml=True)
body_content_kwargs['content'] = body_content
request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
pipeline_response = await self._client._pipeline.run(request, stream=True, **kwargs)
response = pipeline_response.http_response

if response.status_code not in [202]:
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-Type']=self._deserialize('str', response.headers.get('Content-Type'))
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'))
deserialized = response.stream_download(self._client._pipeline)

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

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

async def acquire_lease(
self,
timeout: Optional[int] = None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from ._models_py3 import CpkInfo
from ._models_py3 import CpkScopeInfo
from ._models_py3 import DataLakeStorageError
from ._models_py3 import DataLakeStorageErrorDetails
from ._models_py3 import DataLakeStorageErrorAutoGenerated
from ._models_py3 import DelimitedTextConfiguration
from ._models_py3 import DirectoryHttpHeaders
from ._models_py3 import FilterBlobItem
Expand Down Expand Up @@ -85,7 +85,7 @@
from ._models import CpkInfo # type: ignore
from ._models import CpkScopeInfo # type: ignore
from ._models import DataLakeStorageError # type: ignore
from ._models import DataLakeStorageErrorDetails # type: ignore
from ._models import DataLakeStorageErrorAutoGenerated # type: ignore
from ._models import DelimitedTextConfiguration # type: ignore
from ._models import DirectoryHttpHeaders # type: ignore
from ._models import FilterBlobItem # type: ignore
Expand Down Expand Up @@ -167,7 +167,7 @@
'CpkInfo',
'CpkScopeInfo',
'DataLakeStorageError',
'DataLakeStorageErrorDetails',
'DataLakeStorageErrorAutoGenerated',
'DelimitedTextConfiguration',
'DirectoryHttpHeaders',
'FilterBlobItem',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -955,11 +955,12 @@ class DataLakeStorageError(msrest.serialization.Model):
"""DataLakeStorageError.

:param data_lake_storage_error_details: The service error response object.
:type data_lake_storage_error_details: ~azure.storage.blob.models.DataLakeStorageErrorDetails
:type data_lake_storage_error_details:
~azure.storage.blob.models.DataLakeStorageErrorAutoGenerated
"""

_attribute_map = {
'data_lake_storage_error_details': {'key': 'error', 'type': 'DataLakeStorageErrorDetails'},
'data_lake_storage_error_details': {'key': 'error', 'type': 'DataLakeStorageErrorAutoGenerated'},
}

def __init__(
Expand All @@ -970,7 +971,7 @@ def __init__(
self.data_lake_storage_error_details = kwargs.get('data_lake_storage_error_details', None)


class DataLakeStorageErrorDetails(msrest.serialization.Model):
class DataLakeStorageErrorAutoGenerated(msrest.serialization.Model):
"""The service error response object.

:param code: The service error code.
Expand All @@ -988,7 +989,7 @@ def __init__(
self,
**kwargs
):
super(DataLakeStorageErrorDetails, self).__init__(**kwargs)
super(DataLakeStorageErrorAutoGenerated, self).__init__(**kwargs)
self.code = kwargs.get('code', None)
self.message = kwargs.get('message', None)

Expand Down
Loading