-
Notifications
You must be signed in to change notification settings - Fork 1.1k
PYTHON-2823 Allow custom service names with srvServiceName URI option #749
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to add documentation for the new option in the docstring for MongoClient, and a mention in the changelog.
pymongo/srv_resolver.py
Outdated
try: | ||
results = _resolve('_mongodb._tcp.' + self.__fqdn, 'SRV', | ||
lifetime=self.__connect_timeout) | ||
results = _resolve('_'+str(self.__srv)+'._tcp.' + self.__fqdn, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add spaces around the '+' characters. Also, why do you have to wrap self.__srv in str? Is it being converted to a bytes before it gets here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you are right and we can remove that.
pymongo/uri_parser.py
Outdated
options[opt] = val | ||
if "tls" not in options and "ssl" not in options: | ||
options["tls"] = True if validate else 'true' | ||
#elif not is_srv and options.get("srvServiceName", None) is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the dead code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't dead code, it was to fix the test that was testing for a configuration to be raised under those conditions. So I restored it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a grep through the codebase we also need to pass the new option to the _SrvResolver in pymongo/monitor.py. It's somewhat concerning that the tests pass without this change (but not your fault at all of course). Does the spec change have any test coverage for mongos SRV polling?
pymongo/mongo_client.py
Outdated
Starting in version 4.0 you can pass a custom SRV service name by | ||
using the ``srvServiceName`` option like so:: | ||
MongoClient("mongodb+srv://test22.test.build.10gen.cc/?srvServiceName=customname") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be documented at the bottom of the **Other optional parameters can be passed as keyword arguments:**
section below. Please also note the new parameter name in the existing versonchanged:: 4.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
nodes = [ | ||
(maybe_decode(res.target.to_text(omit_final_dot=True)), res.port) | ||
for res in results] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is uneeded.
pymongo/srv_resolver.py
Outdated
class _SrvResolver(object): | ||
def __init__(self, fqdn, connect_timeout=None): | ||
def __init__(self, fqdn, | ||
connect_timeout=None, srv_service_name="mongodb"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we should always pass connect_timeout and srv_service_name when creating a _SrvResolver. Can you make both of them required arguments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'm not sure how to get the value of srv_service_name from within monitor.py where _SrvResolver is called, so I don't know how to make them required arguments because I don't know where the values that should go in those arguments are stored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind I figured out the plumbing. However, I don't think that connect_timeout is always passed when creating a _SrvResolver.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
connect_timeout needs to always be passed. The fact that it's not already is an oversight. Please update SrvMonitor to get the timeout from topology_settings (self._settings).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/srv_resolver.py
Outdated
results = _resolve('_mongodb._tcp.' + self.__fqdn, 'SRV', | ||
lifetime=self.__connect_timeout) | ||
results = _resolve('_' + self.__srv+'._tcp.' + self.__fqdn, | ||
'SRV', lifetime=self.__connect_timeout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please match the surrounding code style. Second line is indented too much. Spaces around +
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/uri_parser.py
Outdated
|
||
# get the srvservicename from options so that we can pass it to | ||
# _SrvResolver | ||
# constructor below |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is unneeded. Writing useful comments is a tough skill to learn. Usually you want a comment to explain some tricky or non-obvious code (which this is not) or to explain why the code is needed (which is obvious here). Please read this blog for some good guidelines: https://stackoverflow.blog/2021/07/05/best-practices-for-writing-code-comments/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/uri_parser.py
Outdated
options[opt] = val | ||
if "tls" not in options and "ssl" not in options: | ||
options["tls"] = True if validate else 'true' | ||
elif not is_srv and options.get("srvServiceName", None) is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.get("srvServiceName", None)
is the same as .get("srvServiceName")
. Let's use the second.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/uri_parser.py
Outdated
options["tls"] = True if validate else 'true' | ||
elif not is_srv and options.get("srvServiceName", None) is not None: | ||
raise ConfigurationError("You cannot use the srvServiceName option " | ||
"with non-SRV URIs.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest: "The srvServiceName option is only allowed with 'mongodb+srv://' URIs"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/mongo_client.py
Outdated
There is a new parameter for SRV URIs ``srvServiceName`` which | ||
can be used like so:: | ||
MongoClient("mongodb+srv://test22.test.build.10gen.cc/?srvServiceName=customname") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not repeat the docs here. We should just say:
Added the ``srvServiceName`` URI and keyword argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/mongo_client.py
Outdated
- Starting in version 4.0 you can pass a custom SRV service name by | ||
using the ``srvServiceName`` option like so:: | ||
MongoClient("mongodb+srv://test22.test.build.10gen.cc/?srvServiceName=customname") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move this to the bottom of this list (under unicode_decode_error_handler). Also please match the doc formatting and style of the other options here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/mongo_client.py
Outdated
dbase = res["database"] or dbase | ||
opts = res["options"] | ||
fqdn = res["fqdn"] | ||
srv_service_name = opts.get("srvServiceName", "mongodb") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please refactor the default "mongodb" value into a global variable. You can add it to common.py next to the other default global settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/monitor.py
Outdated
seedlist, ttl = _SrvResolver(self._fqdn).get_hosts_and_min_ttl() | ||
seedlist, ttl = _SrvResolver(self._fqdn, | ||
srv_service_name=self._srv_service_name | ||
).get_hosts_and_min_ttl() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The style here would be cleaner like this:
try:
resolver = _SrvResolver(
self._fqdn,
srv_service_name=self._srv_service_name)
seedlist, ttl = resolver.get_hosts_and_min_ttl()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
pymongo/srv_resolver.py
Outdated
class _SrvResolver(object): | ||
def __init__(self, fqdn, connect_timeout=None): | ||
def __init__(self, fqdn, | ||
connect_timeout=None, srv_service_name="mongodb"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
connect_timeout needs to always be passed. The fact that it's not already is an oversight. Please update SrvMonitor to get the timeout from topology_settings (self._settings).
pymongo/srv_resolver.py
Outdated
results = _resolve('_mongodb._tcp.' + self.__fqdn, 'SRV', | ||
lifetime=self.__connect_timeout) | ||
results = _resolve('_' + self.__srv + '._tcp.' + self.__fqdn, | ||
'SRV', lifetime=self.__connect_timeout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The indentation here still looks off, should be:
results = _resolve('_' + self.__srv + '._tcp.' + self.__fqdn,
'SRV', lifetime=self.__connect_timeout)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
doc/changelog.rst
Outdated
- The ``hint`` option is now required when using ``min`` or ``max`` queries | ||
with :meth:`~pymongo.collection.Collection.find`. | ||
- ``name`` is now a required argument for the :class:`pymongo.driver_info.DriverInfo` class. | ||
- When providing a URI to the :class:`~pymongo.mongo_client.MongoClient` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest: When providing a "mongodb+srv://" URI to :class:...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/common.py
Outdated
_MAX_END_SESSIONS = 10000 | ||
|
||
# Default value for srvServiceName | ||
SRV_SERVICE_NAME_DEFAULT = "mongodb" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd omit the _DEFAULT
because none of the other constants have it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/mongo_client.py
Outdated
- Starting in version 4.0 you can pass a custom SRV service name by | ||
using the ``srvServiceName`` option like so:: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not match how we document the other options. The line needs to start with:
- `<option name>`: description.
There's also no need to mention the Starting in version 4.0
part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/uri_parser.py
Outdated
from urllib.parse import unquote_plus | ||
|
||
from pymongo.common import ( | ||
from pymongo.common import (SRV_SERVICE_NAME_DEFAULT, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This import should be on a new line to match the existing style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/test_client.py
Outdated
client = MongoClient('mongodb+srv://test22.test.build.10gen.cc', | ||
srvServiceName='namefromkwarg') | ||
self.assertEqual(client._topology_settings._srv_service_name, | ||
'namefromkwarg') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/test_client.py
Outdated
|
||
def test_service_name_from_kwargs(self): | ||
client = MongoClient('mongodb+srv://test22.test.build.10gen.cc', | ||
srvServiceName='namefromkwarg') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add connect=False since this test doesn't need to open the topology.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
… selecting between default, kwargs, and URI opts
with self.assertRaisesRegex(AutoReconnect, expected): | ||
client.pymongo_test.test.find_one({}) | ||
|
||
def test_service_name_from_kwargs(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs:
@unittest.skipUnless(
_HAVE_DNSPYTHON, "DNS-related tests need dnspython to be installed")
def test_service_name_from_kwargs(self):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
'/?srvServiceName=customname', | ||
connect=False) | ||
self.assertEqual(client._topology_settings._srv_service_name, | ||
'customname') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a test which actually checks that the kwarg overrides the URI. Like this:
client = MongoClient(
'mongodb+srv://user:[email protected]'
'/?srvServiceName=shouldBeOverridden',
srvServiceName='customname',
connect=False)
self.assertEqual(client._topology_settings._srv_service_name,
'customname')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
def parse_uri(uri, default_port=DEFAULT_PORT, validate=True, warn=False, | ||
normalize=True, connect_timeout=None): | ||
normalize=True, connect_timeout=None, srv_service_name=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the docstring below to reflect the new srv_service_name param.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
and decoding of custom types. | ||
| **Other optional parameters can be passed as keyword arguments:** | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please undo this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pymongo/mongo_client.py
Outdated
a Unicode-related error occurs during BSON decoding that would | ||
otherwise raise :exc:`UnicodeDecodeError`. Valid options include | ||
'strict', 'replace', and 'ignore'. Defaults to 'strict'. | ||
- `srvServiceName`: A custom SRV service name. Use it like so:: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest:
`srvServiceName`: (string) The SRV service name to use for "mongodb+srv://" URIs. Defaults to "mongodb". Use it like so::
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
I know you've already addressed the option plumbing but do you have any thoughts on the test coverage issue? |
I'm not sure about the test coverage. I think that our new tests cover most of the behavior, but I didn't see anything else in the spec tests besides the ones for this PR. I think one thing we could do is maybe check and make sure that the value of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
I'm not sure about the test coverage. ...
Please file a DRIVERS ticket to request test coverage here. The problem is that there is no test coverage for SRV polling with a custom service name.
No description provided.