Skip to content

Commit

Permalink
feat!: upgrade pymongo
Browse files Browse the repository at this point in the history
  • Loading branch information
mumarkhan999 committed Jul 18, 2024
1 parent 058870e commit b840069
Show file tree
Hide file tree
Showing 16 changed files with 241 additions and 85 deletions.
3 changes: 0 additions & 3 deletions conf/locale/en/LC_MESSAGES/.gitignore

This file was deleted.

2 changes: 1 addition & 1 deletion requirements/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ django-simple-history==3.4.0

# constrained in opaque_keys. migration guide here: https://pymongo.readthedocs.io/en/4.0/migrate-to-pymongo4.html
# Major upgrade will be done in separate ticket.
pymongo<4.0.0
pymongo<4.4.1

# greater version has breaking changes and requires some migration steps.
django-webpack-loader==0.7.0
Expand Down
10 changes: 7 additions & 3 deletions requirements/edx/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ bridgekeeper==0.9
# via -r requirements/edx/kernel.in
camel-converter[pydantic]==3.1.2
# via meilisearch
celery==5.4.0
celery==5.3.6
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/kernel.in
Expand Down Expand Up @@ -374,6 +374,10 @@ djangorestframework==3.14.0
# super-csv
djangorestframework-xml==2.0.0
# via edx-enterprise
dnspython==2.6.1
# via
# -r requirements/edx/paver.txt
# pymongo
done-xblock==2.3.0
# via -r requirements/edx/bundled.in
drf-jwt==1.19.2
Expand Down Expand Up @@ -534,7 +538,7 @@ enmerkar==0.7.1
# via enmerkar-underscore
enmerkar-underscore==2.3.0
# via -r requirements/edx/kernel.in
event-tracking==2.4.0
event-tracking==2.4.1
# via
# -r requirements/edx/kernel.in
# edx-completion
Expand Down Expand Up @@ -862,7 +866,7 @@ pylti1p3==2.0.0
# via -r requirements/edx/kernel.in
pymemcache==4.0.0
# via -r requirements/edx/paver.txt
pymongo==3.13.0
pymongo==4.4.0
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/kernel.in
Expand Down
8 changes: 5 additions & 3 deletions requirements/edx/development.txt
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ camel-converter[pydantic]==3.1.2
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
# meilisearch
celery==5.4.0
celery==5.3.6
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/doc.txt
Expand Down Expand Up @@ -612,8 +612,10 @@ djangorestframework-xml==2.0.0
# edx-enterprise
dnspython==2.6.1
# via
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
# email-validator
# pymongo
docutils==0.21.2
# via
# -r requirements/edx/doc.txt
Expand Down Expand Up @@ -851,7 +853,7 @@ enmerkar-underscore==2.3.0
# via
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
event-tracking==2.4.0
event-tracking==2.4.1
# via
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
Expand Down Expand Up @@ -1532,7 +1534,7 @@ pymemcache==4.0.0
# via
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
pymongo==3.13.0
pymongo==4.4.0
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/doc.txt
Expand Down
10 changes: 7 additions & 3 deletions requirements/edx/doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ camel-converter[pydantic]==3.1.2
# via
# -r requirements/edx/base.txt
# meilisearch
celery==5.4.0
celery==5.3.6
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/base.txt
Expand Down Expand Up @@ -438,6 +438,10 @@ djangorestframework-xml==2.0.0
# via
# -r requirements/edx/base.txt
# edx-enterprise
dnspython==2.6.1
# via
# -r requirements/edx/base.txt
# pymongo
docutils==0.21.2
# via
# pydata-sphinx-theme
Expand Down Expand Up @@ -612,7 +616,7 @@ enmerkar==0.7.1
# enmerkar-underscore
enmerkar-underscore==2.3.0
# via -r requirements/edx/base.txt
event-tracking==2.4.0
event-tracking==2.4.1
# via
# -r requirements/edx/base.txt
# edx-completion
Expand Down Expand Up @@ -1023,7 +1027,7 @@ pylti1p3==2.0.0
# via -r requirements/edx/base.txt
pymemcache==4.0.0
# via -r requirements/edx/base.txt
pymongo==3.13.0
pymongo==4.4.0
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/base.txt
Expand Down
4 changes: 3 additions & 1 deletion requirements/edx/paver.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ charset-normalizer==2.0.12
# via
# -c requirements/edx/../constraints.txt
# requests
dnspython==2.6.1
# via pymongo
edx-opaque-keys==2.10.0
# via -r requirements/edx/paver.in
idna==3.7
Expand All @@ -36,7 +38,7 @@ psutil==6.0.0
# via -r requirements/edx/paver.in
pymemcache==4.0.0
# via -r requirements/edx/paver.in
pymongo==3.13.0
pymongo==4.4.0
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/paver.in
Expand Down
11 changes: 7 additions & 4 deletions requirements/edx/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ camel-converter[pydantic]==3.1.2
# via
# -r requirements/edx/base.txt
# meilisearch
celery==5.4.0
celery==5.3.6
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/base.txt
Expand Down Expand Up @@ -474,7 +474,10 @@ djangorestframework-xml==2.0.0
# -r requirements/edx/base.txt
# edx-enterprise
dnspython==2.6.1
# via email-validator
# via
# -r requirements/edx/base.txt
# email-validator
# pymongo
done-xblock==2.3.0
# via -r requirements/edx/base.txt
drf-jwt==1.19.2
Expand Down Expand Up @@ -648,7 +651,7 @@ enmerkar==0.7.1
# enmerkar-underscore
enmerkar-underscore==2.3.0
# via -r requirements/edx/base.txt
event-tracking==2.4.0
event-tracking==2.4.1
# via
# -r requirements/edx/base.txt
# edx-completion
Expand Down Expand Up @@ -1138,7 +1141,7 @@ pylti1p3==2.0.0
# via -r requirements/edx/base.txt
pymemcache==4.0.0
# via -r requirements/edx/base.txt
pymongo==3.13.0
pymongo==4.4.0
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/base.txt
Expand Down
4 changes: 3 additions & 1 deletion scripts/structures_pruning/requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ click==8.1.6
# click-log
click-log==0.4.0
# via -r scripts/structures_pruning/requirements/base.in
dnspython==2.6.1
# via pymongo
edx-opaque-keys==2.10.0
# via -r scripts/structures_pruning/requirements/base.in
pbr==6.0.0
# via stevedore
pymongo==3.13.0
pymongo==4.4.0
# via
# -c scripts/structures_pruning/requirements/../../../requirements/constraints.txt
# -r scripts/structures_pruning/requirements/base.in
Expand Down
6 changes: 5 additions & 1 deletion scripts/structures_pruning/requirements/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ click-log==0.4.0
# via -r scripts/structures_pruning/requirements/base.txt
ddt==1.7.2
# via -r scripts/structures_pruning/requirements/testing.in
dnspython==2.6.1
# via
# -r scripts/structures_pruning/requirements/base.txt
# pymongo
edx-opaque-keys==2.10.0
# via -r scripts/structures_pruning/requirements/base.txt
iniconfig==2.0.0
Expand All @@ -24,7 +28,7 @@ pbr==6.0.0
# stevedore
pluggy==1.5.0
# via pytest
pymongo==3.13.0
pymongo==4.4.0
# via
# -r scripts/structures_pruning/requirements/base.txt
# edx-opaque-keys
Expand Down
2 changes: 1 addition & 1 deletion scripts/user_retirement/requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ lxml==4.9.4
# zeep
more-itertools==10.3.0
# via simple-salesforce
newrelic==9.12.0

# via edx-django-utils
pbr==6.0.0
# via stevedore
Expand Down
2 changes: 1 addition & 1 deletion scripts/user_retirement/requirements/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ more-itertools==10.3.0
# simple-salesforce
moto==4.2.14
# via -r scripts/user_retirement/requirements/testing.in
newrelic==9.12.0

# via
# -r scripts/user_retirement/requirements/base.txt
# edx-django-utils
Expand Down
65 changes: 53 additions & 12 deletions xmodule/contentstore/mongo.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""


import hashlib
import json
import os

Expand Down Expand Up @@ -40,23 +41,55 @@ def __init__(
# GridFS will throw an exception if the Database is wrapped in a MongoProxy. So don't wrap it.
# The appropriate methods below are marked as autoretry_read - those methods will handle
# the AutoReconnect errors.
proxy = False
mongo_db = connect_to_mongodb(
db, host,
port=port, tz_aware=tz_aware, user=user, password=password, proxy=proxy, **kwargs
)
self.connection_params = {
'db': db,
'host': host,
'port': port,
'tz_aware': tz_aware,
'user': user,
'password': password,
'proxy': False,
**kwargs
}
self.bucket = bucket
self.do_connection()

def do_connection(self):
"""
Connects to mongodb.
"""
mongo_db = connect_to_mongodb(**self.connection_params)

self.fs = gridfs.GridFS(mongo_db, bucket) # pylint: disable=invalid-name
self.fs = gridfs.GridFS(mongo_db, self.bucket) # pylint: disable=invalid-name

self.fs_files = mongo_db[bucket + ".files"] # the underlying collection GridFS uses
self.chunks = mongo_db[bucket + ".chunks"]
self.fs_files = mongo_db[self.bucket + ".files"] # the underlying collection GridFS uses
self.chunks = mongo_db[self.bucket + ".chunks"]

def close_connections(self):
"""
Closes any open connections to the underlying databases
"""
self.fs_files.database.client.close()

def ensure_connection(self):
"""
Ensure that mongodb connection is open.
"""
if self.check_connection():
return
self.do_connection()

def check_connection(self):
"""
Check if mongodb connection is open or not.
"""
connection = self.fs_files.database.client
try:
connection.admin.command('ping')
return True
except pymongo.errors.InvalidOperation:
return False

def _drop_database(self, database=True, collections=True, connections=True):
"""
A destructive operation to drop the underlying database and close all connections.
Expand All @@ -69,8 +102,8 @@ def _drop_database(self, database=True, collections=True, connections=True):
If connections is True, then close the connection to the database as well.
"""
self.ensure_connection()
connection = self.fs_files.database.client

if database:
connection.drop_database(self.fs_files.database.name)
elif collections:
Expand Down Expand Up @@ -103,16 +136,22 @@ def save(self, content):
# but many more objects have this in python3 and shouldn't be using the chunking logic. For string and
# byte streams we write them directly to gridfs and convert them to byetarrys if necessary.
if hasattr(content.data, '__iter__') and not isinstance(content.data, (bytes, (str,))):
custom_md5 = hashlib.md5()
for chunk in content.data:
fp.write(chunk)
custom_md5.update(chunk)
fp.custom_md5 = custom_md5.hexdigest()
else:
# Ideally we could just ensure that we don't get strings in here and only byte streams
# but being confident of that wolud be a lot more work than we have time for so we just
# handle both cases here.
if isinstance(content.data, str):
fp.write(content.data.encode('utf-8'))
encoded_data = content.data.encode('utf-8')
fp.write(encoded_data)
fp.custom_md5 = hashlib.md5(encoded_data).hexdigest()
else:
fp.write(content.data)
fp.custom_md5 = hashlib.md5(content.data).hexdigest()

return content

Expand Down Expand Up @@ -142,12 +181,13 @@ def find(self, location, throw_on_not_found=True, as_stream=False): # lint-amne
'thumbnail',
thumbnail_location[4]
)

return StaticContentStream(
location, fp.displayname, fp.content_type, fp, last_modified_at=fp.uploadDate,
thumbnail_location=thumbnail_location,
import_path=getattr(fp, 'import_path', None),
length=fp.length, locked=getattr(fp, 'locked', False),
content_digest=getattr(fp, 'md5', None),
content_digest=getattr(fp, 'custom_md5', None),
)
else:
with self.fs.get(content_id) as fp:
Expand All @@ -161,12 +201,13 @@ def find(self, location, throw_on_not_found=True, as_stream=False): # lint-amne
'thumbnail',
thumbnail_location[4]
)

return StaticContent(
location, fp.displayname, fp.content_type, fp.read(), last_modified_at=fp.uploadDate,
thumbnail_location=thumbnail_location,
import_path=getattr(fp, 'import_path', None),
length=fp.length, locked=getattr(fp, 'locked', False),
content_digest=getattr(fp, 'md5', None),
content_digest=getattr(fp, 'custom_md5', None),
)
except NoFile:
if throw_on_not_found: # lint-amnesty, pylint: disable=no-else-raise
Expand Down
Loading

0 comments on commit b840069

Please sign in to comment.