Skip to content

Commit ec1b7e4

Browse files
simorenohannatischgahl-levytjprescott
authored
[Cosmos] use python3 typehints and move options to kwargs on async client (#23933)
* initial commit * Client Constructor (#20310) * Removed some stuff * Looking at constructors * Updated request * Added client close * working client creation Co-authored-by: simorenoh <[email protected]> * read database database read works, but ignored exception is returned: Fatal error on SSL transport NoneType has no attribute 'send' (_loop._proactor.send) RuntimeError: Event loop is closed Unclosed connector/ connection * Update simon_testfile.py * with coroutine Added methods needed to use async with when initializing client, but logs output "Exception ignored... Runtime Error: Event loop is closed" * Update simon_testfile.py * small changes * async with returns no exceptions * async read container * async item read * cleaning up * create item/ database methods * item delete working * docs replace functionality missing upsert and other resources * upsert functionality missing read_all_items and both query methods for container class * missing query methods * CRUD for udf, sproc, triggers * initial query logic + container methods * missing some execution logic and tests * oops * fully working queries * small fix to query_items() also fixed README and added examples_async * Update _cosmos_client_connection_async.py * Update _cosmos_client_connection.py * documentation update * updated MIT dates and get_user_client() description * Update CHANGELOG.md * Delete simon_testfile.py * leftover retry utility * Update README.md * docs and removed six package * changes based on comments still missing discussion resolution on SSL verification and tests for async functionality under test module (apart from samples which are basically end to end tests) * small change in type hints * updated readme * fixes based on conversations * added missing type comments * update changelog for ci pipeline * added typehints, moved params into keywords, added decorators, made _connection_policy private * changes based on sync with central sdk * remove is_system_key from scripts (only used in execute_sproc) is_system_key verifies that an empty partition key is properly dealt with if ['partitionKey']['systemKey'] exists in the container options - however, we do not allow containers to be created with empty partition key values in the python sdk, so the functionality is needless * Revert "remove is_system_key from scripts (only used in execute_sproc)" Reverting last commit, will find way to init is_system_key for now * async script proxy using composition * pylint * capitalized constants * Apply suggestions from code review Clarifying comments for README Co-authored-by: Gahl Levy <[email protected]> * closing python code snippet * last doc updates * Update sdk/cosmos/azure-cosmos/CHANGELOG.md Co-authored-by: Simon Moreno <[email protected]> * version update * cosmos updates for release * public surface area python3 typehints * fix connection string comma * Update CHANGELOG.md * fixing extra await keyword in sample * Update CHANGELOG.md * Update CHANGELOG.md * simplified short types into one line and moved many options to kwargs * missed additional Callable definitions * pylint * addressed several comments, thank you Travis * Update CHANGELOG.md * Callable typehints * Update CHANGELOG.md * bets practices recommends using string partition keys * Revert "bets practices recommends using string partition keys" This reverts commit d44502f. * Update sdk/cosmos/azure-cosmos/azure/cosmos/container.py Co-authored-by: Anna Tisch <[email protected]> * changes from meeting * Update CHANGELOG.md * update query types * Update dev_requirements.txt * Update setup.py * type checking for tokencredential * Revert "type checking for tokencredential" This reverts commit 4eadc97. * update shared_requirements * anna comments * pylint? * Update _scripts.py Co-authored-by: annatisch <[email protected]> Co-authored-by: Gahl Levy <[email protected]> Co-authored-by: Travis Prescott <[email protected]>
1 parent 54ef18d commit ec1b7e4

File tree

11 files changed

+743
-615
lines changed

11 files changed

+743
-615
lines changed

sdk/cosmos/azure-cosmos/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
### 4.3.0b5 (Unreleased)
44

55
#### Breaking Changes
6+
- Method signatures have been updated to use keyword arguments instead of positional arguments for most method options in the async client.
67
- Bugfix: Automatic Id generation for items was turned on for `upsert_items()` method when no 'id' value was present in document body.
78
Method call will now require an 'id' field to be present in the document body.
89

910
#### Other Changes
10-
- Marked the GetAuthorizationMethod for deprecation since it will no longer be public in a future release.
11+
- Marked the GetAuthorizationHeader method for deprecation since it will no longer be public in a future release.
1112
- Added samples showing how to configure retry options for both the sync and async clients.
1213
- Deprecated the `connection_retry_policy` and `retry_options` options in the sync client.
1314

sdk/cosmos/azure-cosmos/azure/cosmos/aio/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2020
# SOFTWARE.
2121

22-
from .container import ContainerProxy
22+
from ._container import ContainerProxy
2323
from .cosmos_client import CosmosClient
24-
from .database import DatabaseProxy
25-
from .user import UserProxy
26-
from .scripts import ScriptsProxy
24+
from ._database import DatabaseProxy
25+
from ._user import UserProxy
26+
from ._scripts import ScriptsProxy
2727

2828
__all__ = (
2929
"CosmosClient",

sdk/cosmos/azure-cosmos/azure/cosmos/aio/container.py renamed to sdk/cosmos/azure-cosmos/azure/cosmos/aio/_container.py

Lines changed: 195 additions & 160 deletions
Large diffs are not rendered by default.

sdk/cosmos/azure-cosmos/azure/cosmos/aio/database.py renamed to sdk/cosmos/azure-cosmos/azure/cosmos/aio/_database.py

Lines changed: 214 additions & 184 deletions
Large diffs are not rendered by default.

sdk/cosmos/azure-cosmos/azure/cosmos/aio/scripts.py renamed to sdk/cosmos/azure-cosmos/azure/cosmos/aio/_scripts.py

Lines changed: 141 additions & 108 deletions
Large diffs are not rendered by default.

sdk/cosmos/azure-cosmos/azure/cosmos/aio/user.py renamed to sdk/cosmos/azure-cosmos/azure/cosmos/aio/_user.py

Lines changed: 79 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@
2424
"""Create, read, update and delete users in the Azure Cosmos DB SQL API service.
2525
"""
2626

27-
from typing import Any, List, Dict, Union, cast, Optional
27+
from typing import Any, Dict, Union, cast
2828
from azure.core.async_paging import AsyncItemPaged
2929

3030
from azure.core.tracing.decorator_async import distributed_trace_async
3131
from azure.core.tracing.decorator import distributed_trace
3232

3333
from ._cosmos_client_connection_async import CosmosClientConnection
3434
from .._base import build_options
35-
from ..permission import Permission as _permission
35+
from ..permission import Permission
3636

3737

3838
class UserProxy(object):
@@ -42,19 +42,22 @@ class UserProxy(object):
4242
:func:`DatabaseProxy.get_user_client` method.
4343
"""
4444

45-
def __init__(self, client_connection, id, database_link, properties=None): # pylint: disable=redefined-builtin
46-
# type: (CosmosClientConnection, str, str, Dict[str, Any]) -> None
45+
def __init__(
46+
self,
47+
client_connection: CosmosClientConnection,
48+
id: str, # pylint: disable=redefined-builtin
49+
database_link: str,
50+
properties: Dict[str, Any] = None
51+
) -> None:
4752
self.client_connection = client_connection
4853
self.id = id
4954
self.user_link = u"{}/users/{}".format(database_link, id)
5055
self._properties = properties
5156

52-
def __repr__(self):
53-
# type () -> str
57+
def __repr__(self) -> str:
5458
return "<UserProxy [{}]>".format(self.user_link)[:1024]
5559

56-
def _get_permission_link(self, permission_or_id):
57-
# type: (Union[Permission, str, Dict[str, Any]]) -> str
60+
def _get_permission_link(self, permission_or_id: Union[Permission, str, Dict[str, Any]]) -> str:
5861
if isinstance(permission_or_id, str):
5962
return u"{}/permissions/{}".format(self.user_link, permission_or_id)
6063
try:
@@ -63,21 +66,20 @@ def _get_permission_link(self, permission_or_id):
6366
pass
6467
return u"{}/permissions/{}".format(self.user_link, cast("Dict[str, str]", permission_or_id)["id"])
6568

66-
async def _get_properties(self):
67-
# type: () -> Dict[str, Any]
69+
async def _get_properties(self) -> Dict[str, Any]:
6870
if self._properties is None:
6971
self._properties = await self.read()
7072
return self._properties
7173

7274
@distributed_trace_async
73-
async def read(self, **kwargs):
74-
# type: (Any) -> Dict[str, Any]
75-
"""Read user propertes.
75+
async def read(self, **kwargs: Any) -> Dict[str, Any]:
76+
"""Read user properties.
7677
77-
:keyword Callable response_hook: A callable invoked with the response metadata.
78-
:returns: A dictionary of the retrieved user properties.
78+
:keyword response_hook: A callable invoked with the response metadata.
79+
:paramtype response_hook: Callable[[Dict[str, str], Dict[str, Any]], None]
7980
:raises ~azure.cosmos.exceptions.CosmosHttpResponseError: If the given user couldn't be retrieved.
80-
:rtype: dict[str, Any]
81+
:returns: A dictionary of the retrieved user properties.
82+
:rtype: Dict[str, Any]
8183
"""
8284
request_options = build_options(kwargs)
8385
response_hook = kwargs.pop('response_hook', None)
@@ -91,17 +93,18 @@ async def read(self, **kwargs):
9193
return cast('Dict[str, Any]', self._properties)
9294

9395
@distributed_trace
94-
def list_permissions(self, max_item_count=None, **kwargs):
95-
# type: (Optional[int], Any) -> AsyncItemPaged[Dict[str, Any]]
96+
def list_permissions(self, **kwargs: Any) -> AsyncItemPaged[Dict[str, Any]]:
9697
"""List all permission for the user.
9798
98-
:param max_item_count: Max number of permissions to be returned in the enumeration operation.
99-
:keyword Callable response_hook: A callable invoked with the response metadata.
99+
:keyword int max_item_count: Max number of permissions to be returned in the enumeration operation.
100+
:keyword response_hook: A callable invoked with the response metadata.
101+
:paramtype response_hook: Callable[[Dict[str, str], AsyncItemPaged[Dict[str, Any]], None]
100102
:returns: An AsyncItemPaged of permissions (dicts).
101-
:rtype: AsyncItemPaged[dict[str, Any]]
103+
:rtype: AsyncItemPaged[Dict[str, Any]]
102104
"""
103105
feed_options = build_options(kwargs)
104106
response_hook = kwargs.pop('response_hook', None)
107+
max_item_count = kwargs.pop('max_item_count', None)
105108
if max_item_count is not None:
106109
feed_options["maxItemCount"] = max_item_count
107110

@@ -115,26 +118,27 @@ def list_permissions(self, max_item_count=None, **kwargs):
115118
@distributed_trace
116119
def query_permissions(
117120
self,
118-
query,
119-
parameters=None,
120-
max_item_count=None,
121-
**kwargs
122-
):
123-
# type: (str, Optional[List[str]], Optional[int], Any) -> AsyncItemPaged[Dict[str, Any]]
121+
query: Union[str, Dict[str, Any]],
122+
**kwargs: Any
123+
) -> AsyncItemPaged[Dict[str, Any]]:
124124
"""Return all permissions matching the given `query`.
125125
126-
:param query: The Azure Cosmos DB SQL query to execute.
127-
:param parameters: Optional array of parameters to the query. Ignored if no query is provided.
128-
:param max_item_count: Max number of permissions to be returned in the enumeration operation.
129-
:keyword Callable response_hook: A callable invoked with the response metadata.
126+
:param Union[str, Dict[str, Any]] query: The Azure Cosmos DB SQL query to execute.
127+
:keyword parameters: Optional array of parameters to the query. Ignored if no query is provided.
128+
:paramtype parameters: Optional[List[Dict[str, Any]]]
129+
:keyword int max_item_count: Max number of permissions to be returned in the enumeration operation.
130+
:keyword response_hook: A callable invoked with the response metadata.
131+
:paramtype response_hook: Callable[[Dict[str, str], AsyncItemPaged[Dict[str, Any]]], None]
130132
:returns: An AsyncItemPaged of permissions (dicts).
131-
:rtype: AsyncItemPaged[dict[str, Any]]
133+
:rtype: AsyncItemPaged[Dict[str, Any]]
132134
"""
133135
feed_options = build_options(kwargs)
134136
response_hook = kwargs.pop('response_hook', None)
137+
max_item_count = kwargs.pop('max_item_count', None)
135138
if max_item_count is not None:
136139
feed_options["maxItemCount"] = max_item_count
137140

141+
parameters = kwargs.pop('parameters', None)
138142
result = self.client_connection.QueryPermissions(
139143
user_link=self.user_link,
140144
query=query if parameters is None else dict(query=query, parameters=parameters),
@@ -148,16 +152,21 @@ def query_permissions(
148152
return result
149153

150154
@distributed_trace_async
151-
async def get_permission(self, permission, **kwargs):
152-
# type: (Union[str, Dict[str, Any], Permission], Any) -> Permission
155+
async def get_permission(
156+
self,
157+
permission: Union[str, Dict[str, Any], Permission],
158+
**kwargs: Any
159+
) -> Permission:
153160
"""Get the permission identified by `id`.
154161
155162
:param permission: The ID (name), dict representing the properties or :class:`Permission`
156163
instance of the permission to be retrieved.
157-
:keyword Callable response_hook: A callable invoked with the response metadata.
158-
:returns: A dict representing the retrieved permission.
164+
:type permission: Union[str, Dict[str, Any], ~azure.cosmos.Permission]
165+
:keyword response_hook: A callable invoked with the response metadata.
166+
:paramtype response_hook: Callable[[Dict[str, str], Dict[str, Any]], None]
159167
:raises ~azure.cosmos.exceptions.CosmosHttpResponseError: If the given permission couldn't be retrieved.
160-
:rtype: dict[str, Any]
168+
:returns: The retrieved permission object.
169+
:rtype: ~azure.cosmos.Permission
161170
"""
162171
request_options = build_options(kwargs)
163172
response_hook = kwargs.pop('response_hook', None)
@@ -169,7 +178,7 @@ async def get_permission(self, permission, **kwargs):
169178
if response_hook:
170179
response_hook(self.client_connection.last_response_headers, permission_resp)
171180

172-
return _permission(
181+
return Permission(
173182
id=permission_resp["id"],
174183
user_link=self.user_link,
175184
permission_mode=permission_resp["permissionMode"],
@@ -178,17 +187,18 @@ async def get_permission(self, permission, **kwargs):
178187
)
179188

180189
@distributed_trace_async
181-
async def create_permission(self, body, **kwargs):
182-
# type: (Dict[str, Any], Any) -> Permission
190+
async def create_permission(self, body: Dict[str, Any], **kwargs: Any) -> Permission:
183191
"""Create a permission for the user.
184192
185-
To update or replace an existing permision, use the :func:`UserProxy.upsert_permission` method.
193+
To update or replace an existing permission, use the :func:`UserProxy.upsert_permission` method.
186194
187195
:param body: A dict-like object representing the permission to create.
188-
:keyword Callable response_hook: A callable invoked with the response metadata.
189-
:returns: A dict representing the new permission.
196+
:type body: Dict[str, Any]
197+
:keyword response_hook: A callable invoked with the response metadata.
198+
:paramtype response_hook: Callable[[Dict[str, str], Dict[str, Any]], None]
190199
:raises ~azure.cosmos.exceptions.CosmosHttpResponseError: If the given permission couldn't be created.
191-
:rtype: dict[str, Any]
200+
:returns: A permission object representing the new permission.
201+
:rtype: ~azure.cosmos.Permission
192202
"""
193203
request_options = build_options(kwargs)
194204
response_hook = kwargs.pop('response_hook', None)
@@ -200,7 +210,7 @@ async def create_permission(self, body, **kwargs):
200210
if response_hook:
201211
response_hook(self.client_connection.last_response_headers, permission)
202212

203-
return _permission(
213+
return Permission(
204214
id=permission["id"],
205215
user_link=self.user_link,
206216
permission_mode=permission["permissionMode"],
@@ -209,18 +219,19 @@ async def create_permission(self, body, **kwargs):
209219
)
210220

211221
@distributed_trace_async
212-
async def upsert_permission(self, body, **kwargs):
213-
# type: (Dict[str, Any], Any) -> Permission
222+
async def upsert_permission(self, body: Dict[str, Any], **kwargs: Any) -> Permission:
214223
"""Insert or update the specified permission.
215224
216225
If the permission already exists in the container, it is replaced. If
217226
the permission does not exist, it is inserted.
218227
219228
:param body: A dict-like object representing the permission to update or insert.
220-
:param Callable response_hook: A callable invoked with the response metadata.
221-
:returns: A dict representing the upserted permission.
229+
:type body: Dict[str, Any]
230+
:keyword response_hook: A callable invoked with the response metadata.
231+
:paramtype response_hook: Callable[[Dict[str, str], Dict[str, Any]], None]
222232
:raises ~azure.cosmos.exceptions.CosmosHttpResponseError: If the given permission could not be upserted.
223-
:rtype: dict[str, Any]
233+
:returns: A dict representing the upserted permission.
234+
:rtype: ~azure.cosmos.Permission
224235
"""
225236
request_options = build_options(kwargs)
226237
response_hook = kwargs.pop('response_hook', None)
@@ -232,7 +243,7 @@ async def upsert_permission(self, body, **kwargs):
232243
if response_hook:
233244
response_hook(self.client_connection.last_response_headers, permission)
234245

235-
return _permission(
246+
return Permission(
236247
id=permission["id"],
237248
user_link=self.user_link,
238249
permission_mode=permission["permissionMode"],
@@ -241,20 +252,27 @@ async def upsert_permission(self, body, **kwargs):
241252
)
242253

243254
@distributed_trace_async
244-
async def replace_permission(self, permission, body, **kwargs):
245-
# type: (str, Union[str, Dict[str, Any], Permission], Any) -> Permission
255+
async def replace_permission(
256+
self,
257+
permission: Union[str, Dict[str, Any], Permission],
258+
body: Dict[str, Any],
259+
**kwargs: Any
260+
) -> Permission:
246261
"""Replaces the specified permission if it exists for the user.
247262
248263
If the permission does not already exist, an exception is raised.
249264
250265
:param permission: The ID (name), dict representing the properties or :class:`Permission`
251266
instance of the permission to be replaced.
267+
:type permission: Union[str, Dict[str, Any], ~azure.cosmos.Permission]
252268
:param body: A dict-like object representing the permission to replace.
253-
:keyword Callable response_hook: A callable invoked with the response metadata.
254-
:returns: A dict representing the permission after replace went through.
269+
:type body: Dict[str, Any]
270+
:keyword response_hook: A callable invoked with the response metadata.
271+
:paramtype response_hook: Callable[[Dict[str, str], Dict[str, Any]], None]
255272
:raises ~azure.cosmos.exceptions.CosmosHttpResponseError: If the replace failed or the permission
256273
with given id does not exist.
257-
:rtype: dict[str, Any]
274+
:returns: A permission object representing the permission after the replace went through.
275+
:rtype: ~azure.cosmos.Permission
258276
"""
259277
request_options = build_options(kwargs)
260278
response_hook = kwargs.pop('response_hook', None)
@@ -266,7 +284,7 @@ async def replace_permission(self, permission, body, **kwargs):
266284
if response_hook:
267285
response_hook(self.client_connection.last_response_headers, permission_resp)
268286

269-
return _permission(
287+
return Permission(
270288
id=permission_resp["id"],
271289
user_link=self.user_link,
272290
permission_mode=permission_resp["permissionMode"],
@@ -275,15 +293,16 @@ async def replace_permission(self, permission, body, **kwargs):
275293
)
276294

277295
@distributed_trace_async
278-
async def delete_permission(self, permission, **kwargs):
279-
# type: (Union[str, Dict[str, Any], Permission], Any) -> None
296+
async def delete_permission(self, permission: Union[str, Dict[str, Any], Permission], **kwargs: Any) -> None:
280297
"""Delete the specified permission from the user.
281298
282299
If the permission does not already exist, an exception is raised.
283300
284301
:param permission: The ID (name), dict representing the properties or :class:`Permission`
285302
instance of the permission to be deleted.
286-
:keyword Callable response_hook: A callable invoked with the response metadata.
303+
:type permission: Union[str, Dict[str, Any], ~azure.cosmos.Permission]
304+
:keyword response_hook: A callable invoked with the response metadata.
305+
:paramtype response_hook: Callable[[Dict[str, str], None], None]
287306
:raises ~azure.cosmos.exceptions.CosmosHttpResponseError: The permission wasn't deleted successfully.
288307
:raises ~azure.cosmos.exceptions.CosmosResourceNotFoundError: The permission does not exist for the user.
289308
:rtype: None

0 commit comments

Comments
 (0)