Skip to content

Commit 2548384

Browse files
simorenohannatischgahl-levytjprescott
authored
[Cosmos] create new async user agent for async client (#22263)
* 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 * create async user agent for debugging * added basic tests * made user agent private so users know it's not something they need to use * bring in private user agent Co-authored-by: annatisch <[email protected]> Co-authored-by: Gahl Levy <[email protected]> Co-authored-by: Travis Prescott <[email protected]>
1 parent f116225 commit 2548384

File tree

5 files changed

+70
-3
lines changed

5 files changed

+70
-3
lines changed

sdk/cosmos/azure-cosmos/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
This version and all future versions will require Python 3.6+. Python 2.7 is no longer supported.
66
We will also be removing support for Python 3.6 and will only support Python 3.7+ starting December 2022.
77

8+
#### Other Changes
9+
- Added async user agent for async client
10+
811
### 4.3.0b1 (2021-12-14)
912
**New features**
1013
- Added language native async i/o client

sdk/cosmos/azure-cosmos/azure/cosmos/_cosmos_client_connection.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,12 @@ def __init__(
182182
proxy = host if url.port else host + ":" + str(self.connection_policy.ProxyConfiguration.Port)
183183
proxies.update({url.scheme: proxy})
184184

185+
self._user_agent = _utils.get_user_agent()
186+
185187
policies = [
186188
HeadersPolicy(**kwargs),
187189
ProxyPolicy(proxies=proxies),
188-
UserAgentPolicy(base_user_agent=_utils.get_user_agent(), **kwargs),
190+
UserAgentPolicy(base_user_agent=self._user_agent, **kwargs),
189191
ContentDecodePolicy(),
190192
retry_policy,
191193
CustomHookPolicy(**kwargs),

sdk/cosmos/azure-cosmos/azure/cosmos/_utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ def get_user_agent():
3434
return user_agent
3535

3636

37+
def get_user_agent_async():
38+
os_name = safe_user_agent_header(platform.platform())
39+
python_version = safe_user_agent_header(platform.python_version())
40+
user_agent = "azsdk-python-cosmos-async/{} Python/{} ({})".format(VERSION, python_version, os_name)
41+
return user_agent
42+
43+
3744
def safe_user_agent_header(s):
3845
if s is None:
3946
s = "unknown"

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,14 @@ def __init__(
178178
host = self.connection_policy.ProxyConfiguration.Host
179179
url = urlparse(host)
180180
proxy = host if url.port else host + ":" + str(self.connection_policy.ProxyConfiguration.Port)
181-
proxies.update({url.scheme : proxy})
181+
proxies.update({url.scheme: proxy})
182+
183+
self._user_agent = _utils.get_user_agent_async()
182184

183185
policies = [
184186
HeadersPolicy(**kwargs),
185187
ProxyPolicy(proxies=proxies),
186-
UserAgentPolicy(base_user_agent=_utils.get_user_agent(), **kwargs),
188+
UserAgentPolicy(base_user_agent=self._user_agent, **kwargs),
187189
ContentDecodePolicy(),
188190
retry_policy,
189191
CustomHookPolicy(**kwargs),
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# The MIT License (MIT)
2+
# Copyright (c) 2021 Microsoft Corporation
3+
4+
# Permission is hereby granted, free of charge, to any person obtaining a copy
5+
# of this software and associated documentation files (the "Software"), to deal
6+
# in the Software without restriction, including without limitation the rights
7+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
# copies of the Software, and to permit persons to whom the Software is
9+
# furnished to do so, subject to the following conditions:
10+
11+
# The above copyright notice and this permission notice shall be included in all
12+
# copies or substantial portions of the Software.
13+
14+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
# SOFTWARE.
21+
22+
import unittest
23+
24+
import azure.cosmos.cosmos_client as sync_client
25+
import azure.cosmos.aio.cosmos_client as async_client
26+
import pytest
27+
import asyncio
28+
from test_config import _test_config
29+
30+
# This test class serves to test user-configurable options and verify they are
31+
# properly set and saved into the different object instances that use these
32+
# user-configurable settings.
33+
34+
pytestmark = pytest.mark.cosmosEmulator
35+
36+
37+
@pytest.mark.usefixtures("teardown")
38+
class TestClientUserAgent(unittest.TestCase):
39+
40+
async def test_client_user_agent(self):
41+
client_sync = sync_client.CosmosClient(url=_test_config.host, credential=_test_config.masterKey)
42+
client_async = async_client.CosmosClient(url=_test_config.host, credential=_test_config.masterKey)
43+
44+
self.assertTrue(client_sync.client_connection._user_agent.startswith("azsdk-python-cosmos/"))
45+
self.assertTrue(client_async.client_connection._user_agent.startswith("azsdk-python-cosmos-async/"))
46+
self.assertTrue(client_async.client_connection._user_agent != client_sync.client_connection._user_agent)
47+
48+
await client_async.close()
49+
50+
51+
if __name__ == "__main__":
52+
event_loop = asyncio.get_event_loop()
53+
event_loop.run_until_complete(unittest.main())

0 commit comments

Comments
 (0)