Skip to content

Commit 51b4670

Browse files
[Storage] Decoupled Client Context Manager Methods from Base Client (#41442)
1 parent e74d5ff commit 51b4670

34 files changed

+424
-219
lines changed

sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,22 @@ def __init__(
190190
self._client._config.version = get_api_version(kwargs) # type: ignore [assignment]
191191
self._configure_encryption(kwargs)
192192

193+
def __enter__(self) -> Self:
194+
self._client.__enter__()
195+
return self
196+
197+
def __exit__(self, *args) -> None:
198+
self._client.__exit__(*args)
199+
200+
def close(self) -> None:
201+
"""This method is to close the sockets opened by the client.
202+
It need not be used when using with a context manager.
203+
204+
:return: None
205+
:rtype: None
206+
"""
207+
self._client.close()
208+
193209
def _format_url(self, hostname: str) -> str:
194210
return _format_url(
195211
container_name=self.container_name,

sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,22 @@ def __init__(
131131
self._client._config.version = get_api_version(kwargs) # type: ignore [assignment]
132132
self._configure_encryption(kwargs)
133133

134+
def __enter__(self) -> Self:
135+
self._client.__enter__()
136+
return self
137+
138+
def __exit__(self, *args) -> None:
139+
self._client.__exit__(*args)
140+
141+
def close(self) -> None:
142+
"""This method is to close the sockets opened by the client.
143+
It need not be used when using with a context manager.
144+
145+
:return: None
146+
:rtype: None
147+
"""
148+
self._client.close()
149+
134150
def _format_url(self, hostname):
135151
"""Format the endpoint URL according to the current location
136152
mode hostname.

sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,22 @@ def __init__(
150150
self._client = self._build_generated_client()
151151
self._configure_encryption(kwargs)
152152

153+
def __enter__(self) -> Self:
154+
self._client.__enter__()
155+
return self
156+
157+
def __exit__(self, *args) -> None:
158+
self._client.__exit__(*args)
159+
160+
def close(self) -> None:
161+
"""This method is to close the sockets opened by the client.
162+
It need not be used when using with a context manager.
163+
164+
:return: None
165+
:rtype: None
166+
"""
167+
self._client.close()
168+
153169
def _build_generated_client(self) -> AzureBlobStorage:
154170
client = AzureBlobStorage(self.url, base_url=self.url, pipeline=self._pipeline)
155171
client._config.version = self._api_version # type: ignore [assignment] # pylint: disable=protected-access

sdk/storage/azure-storage-blob/azure/storage/blob/_shared/base_client.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,6 @@ def __init__(
127127
self._sdk_moniker = f"storage-{service}/{VERSION}"
128128
self._config, self._pipeline = self._create_pipeline(self.credential, sdk_moniker=self._sdk_moniker, **kwargs)
129129

130-
def __enter__(self):
131-
self._client.__enter__()
132-
return self
133-
134-
def __exit__(self, *args):
135-
self._client.__exit__(*args)
136-
137-
def close(self) -> None:
138-
"""This method is to close the sockets opened by the client.
139-
It need not be used when using with a context manager.
140-
"""
141-
self._client.close()
142-
143130
@property
144131
def url(self) -> str:
145132
"""The full endpoint URL to this entity, including SAS token if used.

sdk/storage/azure-storage-blob/azure/storage/blob/_shared/base_client_async.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,28 +51,6 @@
5151

5252
class AsyncStorageAccountHostsMixin(object):
5353

54-
def __enter__(self):
55-
raise TypeError("Async client only supports 'async with'.")
56-
57-
def __exit__(self, *args):
58-
pass
59-
60-
async def __aenter__(self):
61-
await self._client.__aenter__()
62-
return self
63-
64-
async def __aexit__(self, *args):
65-
await self._client.__aexit__(*args)
66-
67-
async def close(self) -> None:
68-
"""This method is to close the sockets opened by the client.
69-
It need not be used when using with a context manager.
70-
71-
:return: None
72-
:rtype: None
73-
"""
74-
await self._client.close()
75-
7654
def _format_query_string(
7755
self,
7856
sas_token: Optional[str],

sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,22 @@ def __init__(
196196
self._client._config.version = get_api_version(kwargs) # type: ignore [assignment]
197197
self._configure_encryption(kwargs)
198198

199+
async def __aenter__(self) -> Self:
200+
await self._client.__aenter__()
201+
return self
202+
203+
async def __aexit__(self, *args) -> None:
204+
await self._client.__aexit__(*args)
205+
206+
async def close(self) -> None:
207+
"""This method is to close the sockets opened by the client.
208+
It need not be used when using with a context manager.
209+
210+
:return: None
211+
:rtype: None
212+
"""
213+
await self._client.close()
214+
199215
def _format_url(self, hostname: str) -> str:
200216
return _format_url(
201217
container_name=self.container_name,

sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,22 @@ def __init__(
139139
self._client._config.version = get_api_version(kwargs) # type: ignore [assignment]
140140
self._configure_encryption(kwargs)
141141

142+
async def __aenter__(self) -> Self:
143+
await self._client.__aenter__()
144+
return self
145+
146+
async def __aexit__(self, *args) -> None:
147+
await self._client.__aexit__(*args)
148+
149+
async def close(self) -> None:
150+
"""This method is to close the sockets opened by the client.
151+
It need not be used when using with a context manager.
152+
153+
:return: None
154+
:rtype: None
155+
"""
156+
await self._client.close()
157+
142158
def _format_url(self, hostname):
143159
"""Format the endpoint URL according to the current location
144160
mode hostname.

sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,22 @@ def __init__(
143143
self._client = self._build_generated_client()
144144
self._configure_encryption(kwargs)
145145

146+
async def __aenter__(self) -> Self:
147+
await self._client.__aenter__()
148+
return self
149+
150+
async def __aexit__(self, *args) -> None:
151+
await self._client.__aexit__(*args)
152+
153+
async def close(self) -> None:
154+
"""This method is to close the sockets opened by the client.
155+
It need not be used when using with a context manager.
156+
157+
:return: None
158+
:rtype: None
159+
"""
160+
await self._client.close()
161+
146162
def _build_generated_client(self) -> AzureBlobStorage:
147163
client = AzureBlobStorage(self.url, base_url=self.url, pipeline=self._pipeline)
148164
client._config.version = self._api_version # type: ignore [assignment] # pylint: disable=protected-access

sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_service_client.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,23 @@ def __init__(
120120
self._client._config.version = get_api_version(kwargs) # type: ignore [assignment]
121121

122122
def __enter__(self) -> Self:
123+
self._client.__enter__()
123124
self._blob_service_client.__enter__()
124125
return self
125126

126127
def __exit__(self, *args: Any) -> None:
127-
self._blob_service_client.close()
128-
super(DataLakeServiceClient, self).__exit__(*args)
128+
self._blob_service_client.__exit__(*args)
129+
self._client.__exit__(*args)
129130

130131
def close(self) -> None:
131-
""" This method is to close the sockets opened by the client.
132+
"""This method is to close the sockets opened by the client.
132133
It need not be used when using with a context manager.
134+
135+
:return: None
136+
:rtype: None
133137
"""
134-
self.__exit__()
138+
self._blob_service_client.close()
139+
self._client.close()
135140

136141
def _format_url(self, hostname: str) -> str:
137142
"""Format the endpoint URL according to hostname.

sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_file_system_client.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,28 @@ def __init__(
132132
self._client = self._build_generated_client(self.url)
133133
self._datalake_client_for_blob_operation = self._build_generated_client(self._container_client.url)
134134

135+
def __enter__(self) -> Self:
136+
self._client.__enter__()
137+
self._container_client.__enter__()
138+
self._datalake_client_for_blob_operation.__enter__()
139+
return self
140+
141+
def __exit__(self, *args: Any) -> None:
142+
self._datalake_client_for_blob_operation.__exit__(*args)
143+
self._container_client.__exit__(*args)
144+
self._client.__exit__(*args)
145+
146+
def close(self) -> None:
147+
"""This method is to close the sockets opened by the client.
148+
It need not be used when using with a context manager.
149+
150+
:return: None
151+
:rtype: None
152+
"""
153+
self._datalake_client_for_blob_operation.close()
154+
self._container_client.close()
155+
self._client.close()
156+
135157
def _build_generated_client(self, url: str) -> AzureDataLakeStorageRESTAPI:
136158
client = AzureDataLakeStorageRESTAPI(
137159
url,
@@ -145,17 +167,6 @@ def _build_generated_client(self, url: str) -> AzureDataLakeStorageRESTAPI:
145167
def _format_url(self, hostname: str) -> str:
146168
return _format_url(self.scheme, hostname, self.file_system_name, self._query_str)
147169

148-
def __exit__(self, *args: Any) -> None:
149-
self._container_client.close()
150-
self._datalake_client_for_blob_operation.close()
151-
super(FileSystemClient, self).__exit__(*args)
152-
153-
def close(self) -> None:
154-
"""This method is to close the sockets opened by the client.
155-
It need not be used when using with a context manager.
156-
"""
157-
self.__exit__()
158-
159170
@classmethod
160171
def from_connection_string(
161172
cls, conn_str: str,

0 commit comments

Comments
 (0)