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
MOTOR-689: Add async wrapper for pymongo.encryption.ClientEncryption #103
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.
Could you add some tests for the new class? It doesn't have to be as extensive as PyMongo's tests but we should at least see that create_data_key, encrypt, and decrypt work as expected.
I think @prashantmital mentioned that we would discuss this tomorrow so I'm leaving this alone for today |
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.
Great work so far!
For testing the gold standard would be to port the tests from https://github.com/mongodb/mongo-python-driver/blob/0752280adaa69b3cd80fabdf96aac31a26af826f/test/test_encryption.py#L310 in Motor
. There don't seem to be too many tests so I think we can really just port over all of them, but my mind isn't made up in this regard.
Ok I'll work on porting those tests over |
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 to update the Evergreen matrix to be able to run CSFLE tests. We can discuss offline how to do this.
Edit: on second thought, I think we also need to add an optional extra for encryption to the motor setup.py
like we do for pymongo: https://github.com/mongodb/mongo-python-driver/blob/master/setup.py#L285
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.
Great job getting this far, but I think we might have over-engineered this. I recommend rolling back the changes you made to mimic PyMongo's CSFLE testing setup and using tox
to do the same thing instead.
Tox supports installation of 'extras' - https://tox.readthedocs.io/en/latest/config.html#conf-extras
This means we can simply update the [testenv]
section to include:
[testenv]
extras =
encryption
and this will essentially install Motor as pip install -e .[encryption]
which is exactly what we need. AFAICT there is no way to conditionally do this based on whether an environment variable is defined so it will be an all-or-nothing kind of deal (unless we do something funky like dynamically generating tox.ini which I don't think is a good idea).
Thanks! This is a good point - I was curious about how much I should be actually trying to granularly test this file instead of just running every setup with these tests. |
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 other than the one minor change to .travis.yml
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.
Actually, can you also update the CSFLE doc to properly state how to get started with motor + encryption using the extra intall syntax -
https://github.com/mongodb/motor/blob/master/doc/examples/encryption.rst#dependencies
Something like
To get started using client-side field level encryption in your project, you will need to install the pymongocrypt library as well as the driver itself. Install both the driver and a compatible version of pymongocrypt like this:
$ python -m pip install 'motor[encryption]'
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.
Great work!
setup.py
Outdated
@@ -33,6 +33,10 @@ | |||
|
|||
tests_require = ['mockupdb>=1.4.0'] | |||
|
|||
extras_require = { | |||
'encryption': ['pymongo[encryption]>=3.11,<4'], |
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.
Do we need to add the >=3.11,<4
here? I would hope that the version reqs are added transitively from pymongo in install_requires.
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.
@prashantmital thoughts on this?
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 extras are applied on top of (i.e. after) install_requiries
so we would probably need this. I'll run a quick test and get back to you.
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.
With a setup.py
that looks like:
setup(
name='mypackage',
version='0.1.0',
packages=find_packages(),
ext_modules=get_extension_modules(),
install_requires=['pymongo==3.10'],
extras_require={'foo': ['pymongo[srv]']},
)
installing the package has a rather strange output log:
➜ pip install -e '.[foo]'
Obtaining file:///Users/pmital/Developer/playgrounds/python-packaging
Collecting pymongo==3.10
Downloading pymongo-3.10.0-cp37-cp37m-macosx_10_9_x86_64.whl (350 kB)
|████████████████████████████████| 350 kB 1.6 MB/s
Collecting pymongo[srv]
Using cached pymongo-3.11.3-cp37-cp37m-macosx_10_6_intel.whl (414 kB)
Downloading pymongo-3.11.2-cp37-cp37m-macosx_10_6_intel.whl (414 kB)
|████████████████████████████████| 414 kB 1.7 MB/s
Downloading pymongo-3.11.1-cp37-cp37m-macosx_10_6_intel.whl (414 kB)
|████████████████████████████████| 414 kB 2.6 MB/s
Downloading pymongo-3.11.0-cp37-cp37m-macosx_10_9_x86_64.whl (378 kB)
|████████████████████████████████| 378 kB 3.2 MB/s
Downloading pymongo-3.10.1-cp37-cp37m-macosx_10_9_x86_64.whl (350 kB)
|████████████████████████████████| 350 kB 3.8 MB/s
Collecting dnspython<2.0.0,>=1.16.0
Using cached dnspython-1.16.0-py2.py3-none-any.whl (188 kB)
Installing collected packages: pymongo, dnspython, mypackage
Attempting uninstall: mypackage
Found existing installation: mypackage 0.1.0
Uninstalling mypackage-0.1.0:
Successfully uninstalled mypackage-0.1.0
Running setup.py develop for mypackage
Successfully installed dnspython-1.16.0 mypackage pymongo-3.10.0
➜ pip list
Package Version Location
---------- ------- ----------------------------------------------------
Cython 0.29.22
dnspython 1.16.0
mypackage 0.1.0 /Users/pmital/Developer/playgrounds/python-packaging
pip 21.0.1
pymongo 3.10.0
setuptools 47.1.0
wheel 0.36.2
for some reason, it downloads all the versions between 3.10 and latest but ends up only installing the one in install_requires
. So @ShaneHarvey does seem to be correct in that pip
honors the install_requires
version. That being said, it might result in longer install times if there are a lot versions to download.
Specifying the version in extras_require
eliminates the extra downloads:
➜ pip --no-cache-dir install -e '.[foo]'
Obtaining file:///Users/pmital/Developer/playgrounds/python-packaging
Collecting pymongo==3.10
Downloading pymongo-3.10.0-cp37-cp37m-macosx_10_9_x86_64.whl (350 kB)
|████████████████████████████████| 350 kB 2.1 MB/s
Requirement already satisfied: dnspython<2.0.0,>=1.16.0 in /Users/pmital/.pyenv/versions/3.7.10/envs/packaging/lib/python3.7/site-packages (from pymongo==3.10->mypackage==0.1.0) (1.16.0)
Installing collected packages: pymongo, mypackage
Running setup.py develop for mypackage
Successfully installed mypackage pymongo-3.10.0
@ShaneHarvey how would you like to proceed?
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.
Oh well. Let's keep >=3.11,<4
. We'll just need to ensure those two reqs never drift apart.
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.
Ah I see your concern. Let's single-source the PyMongo dependency. Maybe something like:
pymongo_ver = ">=3.11,<4"
install_requires = ["pymongo" + pymongo_ver]
extras_require = {'encryption': ["pymongo" + "[encryption]" + pymongo_ver]}
Thoughts @ShaneHarvey ?
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.
Yes let's do your single-source option.
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.
@guanlinzhou can you implement this?
setup.py
Outdated
@@ -33,6 +33,10 @@ | |||
|
|||
tests_require = ['mockupdb>=1.4.0'] | |||
|
|||
extras_require = { | |||
'encryption': ['pymongo[encryption]>=3.11,<4'], |
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.
Ah I see your concern. Let's single-source the PyMongo dependency. Maybe something like:
pymongo_ver = ">=3.11,<4"
install_requires = ["pymongo" + pymongo_ver]
extras_require = {'encryption': ["pymongo" + "[encryption]" + pymongo_ver]}
Thoughts @ShaneHarvey ?
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 after you've address the last comment.
setup.py
Outdated
|
||
install_requires = ["pymongo" + pymongo_ver] | ||
|
||
extras_require = {'encryption': ["pymongo" + "[encryption]" + pymongo_ver]} |
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 suppose this can just be
["pymongo[encryption]" + pymongo_ver]
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.
Great work!
Add
AsyncIOMotorClientEncryption
class as a wrapper for Explicit Client Encryptionoops branch was named wrong