PYTHON-4662 - Capture Async PyMongo metadata (#1814)

This commit is contained in:
Noah Stapp 2024-08-28 08:31:42 -04:00 committed by GitHub
parent fd0787a57b
commit e430d2e2fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 31 additions and 7 deletions

View File

@ -830,7 +830,7 @@ class AsyncMongoClient(common.BaseObject, Generic[_DocumentType]):
# Username and password passed as kwargs override user info in URI.
username = opts.get("username", username)
password = opts.get("password", password)
self._options = options = ClientOptions(username, password, dbase, opts)
self._options = options = ClientOptions(username, password, dbase, opts, _IS_SYNC)
self._default_database_name = dbase
self._lock = _ALock(_create_lock())

View File

@ -144,7 +144,11 @@ def _parse_ssl_options(options: Mapping[str, Any]) -> tuple[Optional[SSLContext]
def _parse_pool_options(
username: str, password: str, database: Optional[str], options: Mapping[str, Any]
username: str,
password: str,
database: Optional[str],
options: Mapping[str, Any],
is_sync: bool,
) -> PoolOptions:
"""Parse connection pool options."""
credentials = _parse_credentials(username, password, database, options)
@ -183,6 +187,7 @@ def _parse_pool_options(
server_api=server_api,
load_balanced=load_balanced,
credentials=credentials,
is_sync=is_sync,
)
@ -195,7 +200,12 @@ class ClientOptions:
"""
def __init__(
self, username: str, password: str, database: Optional[str], options: Mapping[str, Any]
self,
username: str,
password: str,
database: Optional[str],
options: Mapping[str, Any],
is_sync: bool = True,
):
self.__options = options
self.__codec_options = _parse_codec_options(options)
@ -206,7 +216,7 @@ class ClientOptions:
self.__server_selection_timeout = options.get(
"serverselectiontimeoutms", common.SERVER_SELECTION_TIMEOUT
)
self.__pool_options = _parse_pool_options(username, password, database, options)
self.__pool_options = _parse_pool_options(username, password, database, options, is_sync)
self.__read_preference = _parse_read_preference(options)
self.__replica_set_name = options.get("replicaset")
self.__write_concern = _parse_write_concern(options)

View File

@ -331,6 +331,7 @@ class PoolOptions:
server_api: Optional[ServerApi] = None,
load_balanced: Optional[bool] = None,
credentials: Optional[MongoCredential] = None,
is_sync: Optional[bool] = True,
):
self.__max_pool_size = max_pool_size
self.__min_pool_size = min_pool_size
@ -350,6 +351,7 @@ class PoolOptions:
self.__load_balanced = load_balanced
self.__credentials = credentials
self.__metadata = copy.deepcopy(_METADATA)
if appname:
self.__metadata["application"] = {"name": appname}
@ -361,10 +363,15 @@ class PoolOptions:
# },
# 'platform': 'CPython 3.8.0|MyPlatform'
# }
if not is_sync:
self.__metadata["driver"]["name"] = "{}|{}".format(
self.__metadata["driver"]["name"],
"async",
)
if driver:
if driver.name:
self.__metadata["driver"]["name"] = "{}|{}".format(
_METADATA["driver"]["name"],
self.__metadata["driver"]["name"],
driver.name,
)
if driver.version:

View File

@ -829,7 +829,7 @@ class MongoClient(common.BaseObject, Generic[_DocumentType]):
# Username and password passed as kwargs override user info in URI.
username = opts.get("username", username)
password = opts.get("password", password)
self._options = options = ClientOptions(username, password, dbase, opts)
self._options = options = ClientOptions(username, password, dbase, opts, _IS_SYNC)
self._default_database_name = dbase
self._lock = _create_lock()

View File

@ -341,6 +341,7 @@ class AsyncClientUnitTest(AsyncUnitTest):
def test_metadata(self):
metadata = copy.deepcopy(_METADATA)
metadata["driver"]["name"] = "PyMongo|async"
metadata["application"] = {"name": "foobar"}
client = AsyncMongoClient("mongodb://foo:27017/?appname=foobar&connect=false")
options = client.options
@ -359,7 +360,7 @@ class AsyncClientUnitTest(AsyncUnitTest):
self.assertRaises(TypeError, AsyncMongoClient, driver="abc")
self.assertRaises(TypeError, AsyncMongoClient, driver=("Foo", "1", "a"))
# Test appending to driver info.
metadata["driver"]["name"] = "PyMongo|FooDriver"
metadata["driver"]["name"] = "PyMongo|async|FooDriver"
metadata["driver"]["version"] = "{}|1.2.3".format(_METADATA["driver"]["version"])
client = AsyncMongoClient(
"foo",
@ -403,6 +404,7 @@ class AsyncClientUnitTest(AsyncUnitTest):
@mock.patch.dict("os.environ", {ENV_VAR_K8S: "1"})
def test_container_metadata(self):
metadata = copy.deepcopy(_METADATA)
metadata["driver"]["name"] = "PyMongo|async"
metadata["env"] = {}
metadata["env"]["container"] = {"orchestrator": "kubernetes"}
client = AsyncMongoClient("mongodb://foo:27017/?appname=foobar&connect=false")
@ -1938,6 +1940,7 @@ class TestClient(AsyncIntegrationTest):
async def _test_handshake(self, env_vars, expected_env):
with patch.dict("os.environ", env_vars):
metadata = copy.deepcopy(_METADATA)
metadata["driver"]["name"] = "PyMongo|async"
if expected_env is not None:
metadata["env"] = expected_env

View File

@ -337,6 +337,7 @@ class ClientUnitTest(UnitTest):
def test_metadata(self):
metadata = copy.deepcopy(_METADATA)
metadata["driver"]["name"] = "PyMongo"
metadata["application"] = {"name": "foobar"}
client = MongoClient("mongodb://foo:27017/?appname=foobar&connect=false")
options = client.options
@ -399,6 +400,7 @@ class ClientUnitTest(UnitTest):
@mock.patch.dict("os.environ", {ENV_VAR_K8S: "1"})
def test_container_metadata(self):
metadata = copy.deepcopy(_METADATA)
metadata["driver"]["name"] = "PyMongo"
metadata["env"] = {}
metadata["env"]["container"] = {"orchestrator": "kubernetes"}
client = MongoClient("mongodb://foo:27017/?appname=foobar&connect=false")
@ -1894,6 +1896,7 @@ class TestClient(IntegrationTest):
def _test_handshake(self, env_vars, expected_env):
with patch.dict("os.environ", env_vars):
metadata = copy.deepcopy(_METADATA)
metadata["driver"]["name"] = "PyMongo"
if expected_env is not None:
metadata["env"] = expected_env

View File

@ -96,6 +96,7 @@ replacements = {
"async-transactions-ref": "transactions-ref",
"async-snapshot-reads-ref": "snapshot-reads-ref",
"default_async": "default",
"PyMongo|async": "PyMongo",
}
docstring_replacements: dict[tuple[str, str], str] = {