From a245dec4f4ff431b336832174f53421a5a1b987c Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Thu, 10 Oct 2024 12:32:14 -0400 Subject: [PATCH 01/17] feat: Use jammy repositories for mongo installation. Unclear if there was a change in the focal repositories or if there was an issue with something else. The noble repositories don't support 7.0, so we're stuck here until we upgrade to 8.0. --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 5fef1c8352ce..900489256ab5 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -94,7 +94,7 @@ jobs: run: | if [[ "${{ matrix.mongo-version }}" != "4.4" ]]; then wget -qO - https://www.mongodb.org/static/pgp/server-${{ matrix.mongo-version }}.asc | sudo apt-key add - - echo "deb https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/${{ matrix.mongo-version }} multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-${{ matrix.mongo-version }}.list + echo "deb https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/${{ matrix.mongo-version }} multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-${{ matrix.mongo-version }}.list sudo apt-get update && sudo apt-get install -y mongodb-org="${{ matrix.mongo-version }}.*" fi From 6c045c7b390aa051484cee459a767b246f04e7d8 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Thu, 10 Oct 2024 14:07:17 -0400 Subject: [PATCH 02/17] feat: Unpin xmlsec and lxml. We are now on Python 3.11 and running tests on the latest version of Ubuntu, which seems to mean we don't need these pins anymore. In fact, it seems to break while on these pins. --- requirements/constraints.txt | 19 --- requirements/edx-sandbox/base.txt | 5 +- requirements/edx/base.txt | 74 ++++++------ requirements/edx/coverage.txt | 4 +- requirements/edx/development.txt | 110 ++++++++++-------- requirements/edx/doc.txt | 77 ++++++------ requirements/edx/paver.txt | 6 +- requirements/edx/semgrep.txt | 8 +- requirements/edx/testing.txt | 96 ++++++++------- requirements/pip-tools.txt | 4 +- .../structures_pruning/requirements/base.txt | 2 +- .../requirements/testing.txt | 2 +- scripts/user_retirement/requirements/base.txt | 23 ++-- .../user_retirement/requirements/testing.txt | 23 ++-- 14 files changed, 224 insertions(+), 229 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index dd727a4b1801..2fc1a1e745f3 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -84,13 +84,6 @@ django-storages<1.14.4 # for them. edx-enterprise==4.27.2 -# Date: 2024-05-09 -# This has to be constrained as well because newer versions of edx-i18n-tools need the -# newer version of lxml but that requirement was not made expilict in the 1.6.0 version -# of the package. This can be un-pinned when we're upgrading lxml. -# Issue for unpinning: https://github.com/openedx/edx-platform/issues/35274 -edx-i18n-tools<1.6.0 - # Date: 2024-07-26 # To override the constraint of edx-lint # This can be removed once https://github.com/openedx/edx-platform/issues/34586 is resolved @@ -105,13 +98,6 @@ event-tracking==3.0.0 # https://github.com/openedx/edx-platform/issues/31616 libsass==0.10.0 -# Date: 2024-04-30 -# lxml>=5.0 introduced breaking changes related to system dependencies -# lxml==5.2.1 introduced new extra so we'll nee to rename lxml --> lxml[html-clean] -# This constraint can be removed once we upgrade to Python 3.11 -# Issue for unpinning: https://github.com/openedx/edx-platform/issues/35272 -lxml<5.0 - # Date: 2018-12-14 # markdown>=3.4.0 has failures due to internal refactorings which causes the tests to fail # pinning the version untill the issue gets resolved in the package itself @@ -187,8 +173,3 @@ social-auth-app-django<=5.4.1 # which require urllib3<2 for now. # Issue for unpinning: https://github.com/openedx/edx-platform/issues/32222 urllib3<2.0.0 - -# Date: 2024-04-24 -# xmlsec==1.3.14 breaking tests or all builds, can be removed once a fix is available -# Issue for unpinning: https://github.com/openedx/edx-platform/issues/35264 -xmlsec<1.3.14 diff --git a/requirements/edx-sandbox/base.txt b/requirements/edx-sandbox/base.txt index bf0a4376da70..0a708b2bbf52 100644 --- a/requirements/edx-sandbox/base.txt +++ b/requirements/edx-sandbox/base.txt @@ -26,12 +26,11 @@ joblib==1.4.2 # via nltk kiwisolver==1.4.7 # via matplotlib -lxml==4.9.4 +lxml==5.3.0 # via - # -c requirements/edx-sandbox/../constraints.txt # -r requirements/edx-sandbox/base.in # openedx-calc -markupsafe==2.1.5 +markupsafe==3.0.1 # via # chem # openedx-calc diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 55793bd0c5af..c7f7828f4115 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -6,11 +6,11 @@ # -e git+https://github.com/anupdhabarde/edx-proctoring-proctortrack.git@31c6c9923a51c903ae83760ecbbac191363aa2a2#egg=edx_proctoring_proctortrack # via -r requirements/edx/github.in -acid-xblock==0.3.1 +acid-xblock==0.4.1 # via -r requirements/edx/kernel.in -aiohappyeyeballs==2.4.0 +aiohappyeyeballs==2.4.3 # via aiohttp -aiohttp==3.10.6 +aiohttp==3.10.9 # via # geoip2 # openai @@ -70,13 +70,13 @@ bleach[css]==6.1.0 # xblock-poll boto==2.49.0 # via -r requirements/edx/kernel.in -boto3==1.35.27 +boto3==1.35.37 # via # -r requirements/edx/kernel.in # django-ses # fs-s3fs # ora2 -botocore==1.35.27 +botocore==1.35.37 # via # -r requirements/edx/kernel.in # boto3 @@ -87,7 +87,7 @@ cachecontrol==0.14.0 # via firebase-admin cachetools==5.5.0 # via google-auth -camel-converter[pydantic]==3.1.2 +camel-converter[pydantic]==4.0.1 # via meilisearch celery==5.4.0 # via @@ -328,7 +328,7 @@ django-sekizai==4.1.0 # via # -r requirements/edx/kernel.in # openedx-django-wiki -django-ses==4.1.1 +django-ses==4.2.0 # via -r requirements/edx/bundled.in django-simple-history==3.4.0 # via @@ -387,7 +387,7 @@ djangorestframework==3.14.0 # super-csv djangorestframework-xml==2.0.0 # via edx-enterprise -dnspython==2.6.1 +dnspython==2.7.0 # via # -r requirements/edx/paver.txt # pymongo @@ -429,7 +429,7 @@ edx-celeryutils==1.3.0 # super-csv edx-codejail==3.4.1 # via -r requirements/edx/kernel.in -edx-completion==4.7.1 +edx-completion==4.7.2 # via -r requirements/edx/kernel.in edx-django-release-util==1.4.0 # via @@ -438,7 +438,7 @@ edx-django-release-util==1.4.0 # edxval edx-django-sites-extensions==4.2.0 # via -r requirements/edx/kernel.in -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r requirements/edx/kernel.in # django-config-models @@ -475,9 +475,8 @@ edx-event-bus-kafka==5.8.1 # via -r requirements/edx/kernel.in edx-event-bus-redis==0.5.0 # via -r requirements/edx/kernel.in -edx-i18n-tools==1.5.0 +edx-i18n-tools==1.6.3 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/bundled.in # ora2 edx-milestones==0.6.0 @@ -517,7 +516,7 @@ edx-search==4.0.0 # via -r requirements/edx/kernel.in edx-sga==0.25.0 # via -r requirements/edx/bundled.in -edx-submissions==3.8.0 +edx-submissions==3.8.1 # via # -r requirements/edx/kernel.in # ora2 @@ -584,14 +583,14 @@ geoip2==4.8.0 # via -r requirements/edx/kernel.in glob2==0.7 # via -r requirements/edx/kernel.in -google-api-core[grpc]==2.20.0 +google-api-core[grpc]==2.21.0 # via # firebase-admin # google-api-python-client # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.147.0 +google-api-python-client==2.149.0 # via firebase-admin google-auth==2.35.0 # via @@ -621,11 +620,11 @@ googleapis-common-protos==1.65.0 # via # google-api-core # grpcio-status -grpcio==1.66.1 +grpcio==1.66.2 # via # google-api-core # grpcio-status -grpcio-status==1.66.1 +grpcio-status==1.66.2 # via google-api-core gunicorn==23.0.0 # via -r requirements/edx/kernel.in @@ -639,7 +638,7 @@ httplib2==0.22.0 # via # google-api-python-client # google-auth-httplib2 -icalendar==5.0.13 +icalendar==6.0.0 # via -r requirements/edx/kernel.in idna==3.10 # via @@ -658,7 +657,7 @@ interchange==2021.0.4 # via py2neo ipaddress==1.0.23 # via -r requirements/edx/kernel.in -isodate==0.6.1 +isodate==0.7.2 # via python3-saml jinja2==3.1.4 # via code-annotations @@ -683,7 +682,7 @@ jsonschema==4.23.0 # via # drf-spectacular # optimizely-sdk -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via jsonschema jwcrypto==1.5.6 # via @@ -708,19 +707,21 @@ loremipsum==1.0.5 # via ora2 lti-consumer-xblock==9.11.3 # via -r requirements/edx/kernel.in -lxml==4.9.4 +lxml[html-clean]==5.3.0 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/kernel.in # edx-i18n-tools # edxval # lti-consumer-xblock + # lxml-html-clean # olxcleaner # openedx-calc # ora2 # python3-saml # xblock # xmlsec +lxml-html-clean==0.3.1 + # via lxml mailsnake==1.6.4 # via -r requirements/edx/bundled.in mako==1.3.5 @@ -737,7 +738,7 @@ markdown==3.3.7 # openedx-django-wiki # staff-graded-xblock # xblock-poll -markupsafe==2.1.5 +markupsafe==3.0.1 # via # -r requirements/edx/paver.txt # chem @@ -769,7 +770,7 @@ multidict==6.1.0 # yarl mysqlclient==2.2.4 # via -r requirements/edx/kernel.in -newrelic==9.13.0 +newrelic==10.0.0 # via # -r requirements/edx/bundled.in # edx-django-utils @@ -820,7 +821,7 @@ openedx-events==9.14.1 # edx-name-affirmation # event-tracking # ora2 -openedx-filters==1.10.0 +openedx-filters==1.11.0 # via # -r requirements/edx/kernel.in # lti-consumer-xblock @@ -829,7 +830,7 @@ openedx-learning==0.13.1 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/kernel.in -openedx-mongodbproxy==0.2.1 +openedx-mongodbproxy==0.2.2 # via -r requirements/edx/kernel.in optimizely-sdk==4.1.1 # via @@ -881,6 +882,8 @@ polib==1.2.0 # via edx-i18n-tools prompt-toolkit==3.0.48 # via click-repl +propcache==0.2.0 + # via yarl proto-plus==1.24.0 # via # google-api-core @@ -911,7 +914,7 @@ pycountry==24.6.1 # via -r requirements/edx/kernel.in pycparser==2.22 # via cffi -pycryptodomex==3.20.0 +pycryptodomex==3.21.0 # via # -r requirements/edx/kernel.in # edx-proctoring @@ -1017,7 +1020,6 @@ pytz==2024.2 # edx-tincan-py35 # event-tracking # fs - # icalendar # interchange # olxcleaner # ora2 @@ -1039,7 +1041,7 @@ random2==1.0.2 # via -r requirements/edx/kernel.in recommender-xblock==2.2.1 # via -r requirements/edx/bundled.in -redis==5.0.8 +redis==5.1.1 # via # -r requirements/edx/kernel.in # walrus @@ -1092,7 +1094,7 @@ rules==3.5 # edx-enterprise # edx-proctoring # openedx-learning -s3transfer==0.10.2 +s3transfer==0.10.3 # via boto3 sailthru-client==2.2.3 # via edx-ace @@ -1131,7 +1133,6 @@ six==1.16.0 # fs-s3fs # html5lib # interchange - # isodate # libsass # optimizely-sdk # pansi @@ -1208,6 +1209,7 @@ typing-extensions==4.12.2 tzdata==2024.2 # via # celery + # icalendar # kombu unicodecsv==0.14.1 # via @@ -1237,7 +1239,7 @@ voluptuous==0.15.2 # via ora2 walrus==0.9.4 # via edx-event-bus-redis -watchdog==5.0.2 +watchdog==5.0.3 # via -r requirements/edx/paver.txt wcwidth==0.2.13 # via prompt-toolkit @@ -1285,13 +1287,11 @@ xblock-utils==4.0.0 # via # edx-sga # xblock-poll -xmlsec==1.3.13 - # via - # -c requirements/edx/../constraints.txt - # python3-saml +xmlsec==1.3.14 + # via python3-saml xss-utils==0.6.0 # via -r requirements/edx/kernel.in -yarl==1.12.1 +yarl==1.14.0 # via aiohttp zipp==3.20.2 # via importlib-metadata diff --git a/requirements/edx/coverage.txt b/requirements/edx/coverage.txt index a1faf5e74025..45f2429cb2d1 100644 --- a/requirements/edx/coverage.txt +++ b/requirements/edx/coverage.txt @@ -6,13 +6,13 @@ # chardet==5.2.0 # via diff-cover -coverage==7.6.1 +coverage==7.6.2 # via -r requirements/edx/coverage.in diff-cover==9.2.0 # via -r requirements/edx/coverage.in jinja2==3.1.4 # via diff-cover -markupsafe==2.1.5 +markupsafe==3.0.1 # via jinja2 pluggy==1.5.0 # via diff-cover diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 1bdd3736516b..13f3f6d5e637 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -12,16 +12,16 @@ accessible-pygments==0.0.5 # via # -r requirements/edx/doc.txt # pydata-sphinx-theme -acid-xblock==0.3.1 +acid-xblock==0.4.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -aiohappyeyeballs==2.4.0 +aiohappyeyeballs==2.4.3 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # aiohttp -aiohttp==3.10.6 +aiohttp==3.10.9 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -140,14 +140,14 @@ boto==2.49.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -boto3==1.35.27 +boto3==1.35.37 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # django-ses # fs-s3fs # ora2 -botocore==1.35.27 +botocore==1.35.37 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -157,7 +157,7 @@ bridgekeeper==0.9 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -build==1.2.2 +build==1.2.2.post1 # via # -r requirements/edx/../pip-tools.txt # pip-tools @@ -172,7 +172,7 @@ cachetools==5.5.0 # -r requirements/edx/testing.txt # google-auth # tox -camel-converter[pydantic]==3.1.2 +camel-converter[pydantic]==4.0.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -278,7 +278,7 @@ colorama==0.4.6 # via # -r requirements/edx/testing.txt # tox -coverage[toml]==7.6.1 +coverage[toml]==7.6.2 # via # -r requirements/edx/testing.txt # pytest-cov @@ -325,11 +325,11 @@ defusedxml==0.7.1 # social-auth-core diff-cover==9.2.0 # via -r requirements/edx/testing.txt -dill==0.3.8 +dill==0.3.9 # via # -r requirements/edx/testing.txt # pylint -distlib==0.3.8 +distlib==0.3.9 # via # -r requirements/edx/testing.txt # virtualenv @@ -544,7 +544,7 @@ django-sekizai==4.1.0 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # openedx-django-wiki -django-ses==4.1.1 +django-ses==4.2.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -627,7 +627,7 @@ djangorestframework-xml==2.0.0 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # edx-enterprise -dnspython==2.6.1 +dnspython==2.7.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -696,7 +696,7 @@ edx-codejail==3.4.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -edx-completion==4.7.1 +edx-completion==4.7.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -710,7 +710,7 @@ edx-django-sites-extensions==4.2.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -754,9 +754,8 @@ edx-event-bus-redis==0.5.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -edx-i18n-tools==1.5.0 +edx-i18n-tools==1.6.3 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # ora2 @@ -814,7 +813,7 @@ edx-sga==0.25.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -edx-submissions==3.8.0 +edx-submissions==3.8.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -879,7 +878,7 @@ execnet==2.1.1 # pytest-xdist factory-boy==3.3.1 # via -r requirements/edx/testing.txt -faker==30.0.0 +faker==30.3.0 # via # -r requirements/edx/testing.txt # factory-boy @@ -943,7 +942,7 @@ glob2==0.7 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -google-api-core[grpc]==2.20.0 +google-api-core[grpc]==2.21.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -952,7 +951,7 @@ google-api-core[grpc]==2.20.0 # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.147.0 +google-api-python-client==2.149.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1005,17 +1004,17 @@ googleapis-common-protos==1.65.0 # -r requirements/edx/testing.txt # google-api-core # grpcio-status -grimp==3.4.1 +grimp==3.5 # via # -r requirements/edx/testing.txt # import-linter -grpcio==1.66.1 +grpcio==1.66.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # google-api-core # grpcio-status -grpcio-status==1.66.1 +grpcio-status==1.66.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1045,7 +1044,7 @@ httplib2==0.22.0 # google-auth-httplib2 httpretty==1.1.4 # via -r requirements/edx/testing.txt -icalendar==5.0.13 +icalendar==6.0.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1062,7 +1061,7 @@ imagesize==1.4.1 # via # -r requirements/edx/doc.txt # sphinx -import-linter==2.0 +import-linter==2.1 # via -r requirements/edx/testing.txt importlib-metadata==8.5.0 # via @@ -1087,7 +1086,7 @@ ipaddress==1.0.23 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -isodate==0.6.1 +isodate==0.7.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1136,7 +1135,7 @@ jsonschema==4.23.0 # drf-spectacular # optimizely-sdk # sphinxcontrib-openapi -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1183,14 +1182,14 @@ lti-consumer-xblock==9.11.3 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -lxml==4.9.4 +lxml[html-clean]==5.3.0 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # edx-i18n-tools # edxval # lti-consumer-xblock + # lxml-html-clean # olxcleaner # openedx-calc # ora2 @@ -1198,6 +1197,11 @@ lxml==4.9.4 # python3-saml # xblock # xmlsec +lxml-html-clean==0.3.1 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # lxml mailsnake==1.6.4 # via # -r requirements/edx/doc.txt @@ -1218,7 +1222,7 @@ markdown==3.3.7 # openedx-django-wiki # staff-graded-xblock # xblock-poll -markupsafe==2.1.5 +markupsafe==3.0.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1290,7 +1294,7 @@ mysqlclient==2.2.4 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -newrelic==9.13.0 +newrelic==10.0.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1368,7 +1372,7 @@ openedx-events==9.14.1 # edx-name-affirmation # event-tracking # ora2 -openedx-filters==1.10.0 +openedx-filters==1.11.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1379,7 +1383,7 @@ openedx-learning==0.13.1 # -c requirements/edx/../constraints.txt # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -openedx-mongodbproxy==0.2.1 +openedx-mongodbproxy==0.2.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1407,7 +1411,7 @@ packaging==24.1 # snowflake-connector-python # sphinx # tox -pact-python==2.2.1 +pact-python==2.2.2 # via -r requirements/edx/testing.txt pansi==2020.7.3 # via @@ -1488,6 +1492,11 @@ prompt-toolkit==3.0.48 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # click-repl +propcache==0.2.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # yarl proto-plus==1.24.0 # via # -r requirements/edx/doc.txt @@ -1542,7 +1551,7 @@ pycparser==2.22 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # cffi -pycryptodomex==3.20.0 +pycryptodomex==3.21.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1666,7 +1675,7 @@ pyproject-api==1.8.0 # via # -r requirements/edx/testing.txt # tox -pyproject-hooks==1.1.0 +pyproject-hooks==1.2.0 # via # -r requirements/edx/../pip-tools.txt # build @@ -1767,7 +1776,6 @@ pytz==2024.2 # edx-tincan-py35 # event-tracking # fs - # icalendar # interchange # olxcleaner # ora2 @@ -1799,7 +1807,7 @@ recommender-xblock==2.2.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -redis==5.0.8 +redis==5.1.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1869,7 +1877,7 @@ rules==3.5 # edx-enterprise # edx-proctoring # openedx-learning -s3transfer==0.10.2 +s3transfer==0.10.3 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1926,7 +1934,6 @@ six==1.16.0 # fs-s3fs # html5lib # interchange - # isodate # libsass # optimizely-sdk # pact-python @@ -1986,7 +1993,7 @@ soupsieve==2.6 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # beautifulsoup4 -sphinx==8.0.2 +sphinx==8.1.0 # via # -r requirements/edx/doc.txt # pydata-sphinx-theme @@ -2087,7 +2094,7 @@ tinycss2==1.2.1 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # bleach -tomli==2.0.1 +tomli==2.0.2 # via django-stubs tomlkit==0.13.2 # via @@ -2095,7 +2102,7 @@ tomlkit==0.13.2 # -r requirements/edx/testing.txt # pylint # snowflake-connector-python -tox==4.20.0 +tox==4.21.2 # via -r requirements/edx/testing.txt tqdm==4.66.5 # via @@ -2103,7 +2110,7 @@ tqdm==4.66.5 # -r requirements/edx/testing.txt # nltk # openai -types-pytz==2024.2.0.20240913 +types-pytz==2024.2.0.20241003 # via django-stubs types-pyyaml==6.0.12.20240917 # via @@ -2122,6 +2129,7 @@ typing-extensions==4.12.2 # django-stubs-ext # djangorestframework-stubs # edx-opaque-keys + # faker # fastapi # grimp # import-linter @@ -2137,6 +2145,7 @@ tzdata==2024.2 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # celery + # icalendar # kombu unicodecsv==0.14.1 # via @@ -2165,7 +2174,7 @@ user-util==1.1.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -uvicorn==0.30.6 +uvicorn==0.31.1 # via # -r requirements/edx/testing.txt # pact-python @@ -2176,7 +2185,7 @@ vine==5.1.0 # amqp # celery # kombu -virtualenv==20.26.5 +virtualenv==20.26.6 # via # -r requirements/edx/testing.txt # tox @@ -2185,14 +2194,14 @@ voluptuous==0.15.2 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # ora2 -vulture==2.12 +vulture==2.13 # via -r requirements/edx/development.in walrus==0.9.4 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # edx-event-bus-redis -watchdog==5.0.2 +watchdog==5.0.3 # via # -r requirements/edx/development.in # -r requirements/edx/doc.txt @@ -2266,9 +2275,8 @@ xblock-utils==4.0.0 # -r requirements/edx/testing.txt # edx-sga # xblock-poll -xmlsec==1.3.13 +xmlsec==1.3.14 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # python3-saml @@ -2276,7 +2284,7 @@ xss-utils==0.6.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -yarl==1.12.1 +yarl==1.14.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 6f12d8046759..30736a21a35a 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -8,13 +8,13 @@ # via -r requirements/edx/base.txt accessible-pygments==0.0.5 # via pydata-sphinx-theme -acid-xblock==0.3.1 +acid-xblock==0.4.1 # via -r requirements/edx/base.txt -aiohappyeyeballs==2.4.0 +aiohappyeyeballs==2.4.3 # via # -r requirements/edx/base.txt # aiohttp -aiohttp==3.10.6 +aiohttp==3.10.9 # via # -r requirements/edx/base.txt # geoip2 @@ -102,13 +102,13 @@ bleach[css]==6.1.0 # xblock-poll boto==2.49.0 # via -r requirements/edx/base.txt -boto3==1.35.27 +boto3==1.35.37 # via # -r requirements/edx/base.txt # django-ses # fs-s3fs # ora2 -botocore==1.35.27 +botocore==1.35.37 # via # -r requirements/edx/base.txt # boto3 @@ -123,7 +123,7 @@ cachetools==5.5.0 # via # -r requirements/edx/base.txt # google-auth -camel-converter[pydantic]==3.1.2 +camel-converter[pydantic]==4.0.1 # via # -r requirements/edx/base.txt # meilisearch @@ -398,7 +398,7 @@ django-sekizai==4.1.0 # via # -r requirements/edx/base.txt # openedx-django-wiki -django-ses==4.1.1 +django-ses==4.2.0 # via -r requirements/edx/base.txt django-simple-history==3.4.0 # via @@ -459,7 +459,7 @@ djangorestframework-xml==2.0.0 # via # -r requirements/edx/base.txt # edx-enterprise -dnspython==2.6.1 +dnspython==2.7.0 # via # -r requirements/edx/base.txt # pymongo @@ -509,7 +509,7 @@ edx-celeryutils==1.3.0 # super-csv edx-codejail==3.4.1 # via -r requirements/edx/base.txt -edx-completion==4.7.1 +edx-completion==4.7.2 # via -r requirements/edx/base.txt edx-django-release-util==1.4.0 # via @@ -518,7 +518,7 @@ edx-django-release-util==1.4.0 # edxval edx-django-sites-extensions==4.2.0 # via -r requirements/edx/base.txt -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r requirements/edx/base.txt # django-config-models @@ -555,9 +555,8 @@ edx-event-bus-kafka==5.8.1 # via -r requirements/edx/base.txt edx-event-bus-redis==0.5.0 # via -r requirements/edx/base.txt -edx-i18n-tools==1.5.0 +edx-i18n-tools==1.6.3 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt # ora2 edx-milestones==0.6.0 @@ -598,7 +597,7 @@ edx-search==4.0.0 # via -r requirements/edx/base.txt edx-sga==0.25.0 # via -r requirements/edx/base.txt -edx-submissions==3.8.0 +edx-submissions==3.8.1 # via # -r requirements/edx/base.txt # ora2 @@ -683,7 +682,7 @@ gitpython==3.1.43 # via -r requirements/edx/doc.in glob2==0.7 # via -r requirements/edx/base.txt -google-api-core[grpc]==2.20.0 +google-api-core[grpc]==2.21.0 # via # -r requirements/edx/base.txt # firebase-admin @@ -691,7 +690,7 @@ google-api-core[grpc]==2.20.0 # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.147.0 +google-api-python-client==2.149.0 # via # -r requirements/edx/base.txt # firebase-admin @@ -735,12 +734,12 @@ googleapis-common-protos==1.65.0 # -r requirements/edx/base.txt # google-api-core # grpcio-status -grpcio==1.66.1 +grpcio==1.66.2 # via # -r requirements/edx/base.txt # google-api-core # grpcio-status -grpcio-status==1.66.1 +grpcio-status==1.66.2 # via # -r requirements/edx/base.txt # google-api-core @@ -757,7 +756,7 @@ httplib2==0.22.0 # -r requirements/edx/base.txt # google-api-python-client # google-auth-httplib2 -icalendar==5.0.13 +icalendar==6.0.0 # via -r requirements/edx/base.txt idna==3.10 # via @@ -781,7 +780,7 @@ interchange==2021.0.4 # py2neo ipaddress==1.0.23 # via -r requirements/edx/base.txt -isodate==0.6.1 +isodate==0.7.2 # via # -r requirements/edx/base.txt # python3-saml @@ -818,7 +817,7 @@ jsonschema==4.23.0 # drf-spectacular # optimizely-sdk # sphinxcontrib-openapi -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via # -r requirements/edx/base.txt # jsonschema @@ -850,19 +849,23 @@ loremipsum==1.0.5 # ora2 lti-consumer-xblock==9.11.3 # via -r requirements/edx/base.txt -lxml==4.9.4 +lxml[html-clean]==5.3.0 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt # edx-i18n-tools # edxval # lti-consumer-xblock + # lxml-html-clean # olxcleaner # openedx-calc # ora2 # python3-saml # xblock # xmlsec +lxml-html-clean==0.3.1 + # via + # -r requirements/edx/base.txt + # lxml mailsnake==1.6.4 # via -r requirements/edx/base.txt mako==1.3.5 @@ -879,7 +882,7 @@ markdown==3.3.7 # openedx-django-wiki # staff-graded-xblock # xblock-poll -markupsafe==2.1.5 +markupsafe==3.0.1 # via # -r requirements/edx/base.txt # chem @@ -923,7 +926,7 @@ multidict==6.1.0 # yarl mysqlclient==2.2.4 # via -r requirements/edx/base.txt -newrelic==9.13.0 +newrelic==10.0.0 # via # -r requirements/edx/base.txt # edx-django-utils @@ -979,7 +982,7 @@ openedx-events==9.14.1 # edx-name-affirmation # event-tracking # ora2 -openedx-filters==1.10.0 +openedx-filters==1.11.0 # via # -r requirements/edx/base.txt # lti-consumer-xblock @@ -988,7 +991,7 @@ openedx-learning==0.13.1 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt -openedx-mongodbproxy==0.2.1 +openedx-mongodbproxy==0.2.2 # via -r requirements/edx/base.txt optimizely-sdk==4.1.1 # via @@ -1057,6 +1060,10 @@ prompt-toolkit==3.0.48 # via # -r requirements/edx/base.txt # click-repl +propcache==0.2.0 + # via + # -r requirements/edx/base.txt + # yarl proto-plus==1.24.0 # via # -r requirements/edx/base.txt @@ -1094,7 +1101,7 @@ pycparser==2.22 # via # -r requirements/edx/base.txt # cffi -pycryptodomex==3.20.0 +pycryptodomex==3.21.0 # via # -r requirements/edx/base.txt # edx-proctoring @@ -1222,7 +1229,6 @@ pytz==2024.2 # edx-tincan-py35 # event-tracking # fs - # icalendar # interchange # olxcleaner # ora2 @@ -1245,7 +1251,7 @@ random2==1.0.2 # via -r requirements/edx/base.txt recommender-xblock==2.2.1 # via -r requirements/edx/base.txt -redis==5.0.8 +redis==5.1.1 # via # -r requirements/edx/base.txt # walrus @@ -1305,7 +1311,7 @@ rules==3.5 # edx-enterprise # edx-proctoring # openedx-learning -s3transfer==0.10.2 +s3transfer==0.10.3 # via # -r requirements/edx/base.txt # boto3 @@ -1350,7 +1356,6 @@ six==1.16.0 # fs-s3fs # html5lib # interchange - # isodate # libsass # optimizely-sdk # pansi @@ -1394,7 +1399,7 @@ soupsieve==2.6 # via # -r requirements/edx/base.txt # beautifulsoup4 -sphinx==8.0.2 +sphinx==8.1.0 # via # -r requirements/edx/doc.in # pydata-sphinx-theme @@ -1489,6 +1494,7 @@ tzdata==2024.2 # via # -r requirements/edx/base.txt # celery + # icalendar # kombu unicodecsv==0.14.1 # via @@ -1524,7 +1530,7 @@ walrus==0.9.4 # via # -r requirements/edx/base.txt # edx-event-bus-redis -watchdog==5.0.2 +watchdog==5.0.3 # via -r requirements/edx/base.txt wcwidth==0.2.13 # via @@ -1576,14 +1582,13 @@ xblock-utils==4.0.0 # -r requirements/edx/base.txt # edx-sga # xblock-poll -xmlsec==1.3.13 +xmlsec==1.3.14 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt # python3-saml xss-utils==0.6.0 # via -r requirements/edx/base.txt -yarl==1.12.1 +yarl==1.14.0 # via # -r requirements/edx/base.txt # aiohttp diff --git a/requirements/edx/paver.txt b/requirements/edx/paver.txt index a0b1896919d4..2d8f510e0307 100644 --- a/requirements/edx/paver.txt +++ b/requirements/edx/paver.txt @@ -10,7 +10,7 @@ charset-normalizer==2.0.12 # via # -c requirements/edx/../constraints.txt # requests -dnspython==2.6.1 +dnspython==2.7.0 # via pymongo edx-opaque-keys==2.11.0 # via -r requirements/edx/paver.in @@ -22,7 +22,7 @@ libsass==0.10.0 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/paver.in -markupsafe==2.1.5 +markupsafe==3.0.1 # via -r requirements/edx/paver.in mock==5.1.0 # via -r requirements/edx/paver.in @@ -61,7 +61,7 @@ urllib3==1.26.20 # via # -c requirements/edx/../constraints.txt # requests -watchdog==5.0.2 +watchdog==5.0.3 # via -r requirements/edx/paver.in wrapt==1.16.0 # via -r requirements/edx/paver.in diff --git a/requirements/edx/semgrep.txt b/requirements/edx/semgrep.txt index 102289def277..174fa87d081d 100644 --- a/requirements/edx/semgrep.txt +++ b/requirements/edx/semgrep.txt @@ -15,7 +15,7 @@ boltons==21.0.0 # face # glom # semgrep -bracex==2.5 +bracex==2.5.post1 # via wcmatch certifi==2024.8.30 # via requests @@ -42,7 +42,7 @@ idna==3.10 # via requests jsonschema==4.23.0 # via semgrep -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via jsonschema markdown-it-py==3.0.0 # via rich @@ -60,7 +60,7 @@ referencing==0.35.1 # jsonschema-specifications requests==2.32.3 # via semgrep -rich==13.8.1 +rich==13.9.2 # via semgrep rpds-py==0.20.0 # via @@ -72,7 +72,7 @@ ruamel-yaml-clib==0.2.8 # via ruamel-yaml semgrep==1.52.0 # via -r requirements/edx/semgrep.in -tomli==2.0.1 +tomli==2.0.2 # via semgrep typing-extensions==4.12.2 # via semgrep diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index d3b14a6f4373..473da125341f 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -6,13 +6,13 @@ # -e git+https://github.com/anupdhabarde/edx-proctoring-proctortrack.git@31c6c9923a51c903ae83760ecbbac191363aa2a2#egg=edx_proctoring_proctortrack # via -r requirements/edx/base.txt -acid-xblock==0.3.1 +acid-xblock==0.4.1 # via -r requirements/edx/base.txt -aiohappyeyeballs==2.4.0 +aiohappyeyeballs==2.4.3 # via # -r requirements/edx/base.txt # aiohttp -aiohttp==3.10.6 +aiohttp==3.10.9 # via # -r requirements/edx/base.txt # geoip2 @@ -102,13 +102,13 @@ bleach[css]==6.1.0 # xblock-poll boto==2.49.0 # via -r requirements/edx/base.txt -boto3==1.35.27 +boto3==1.35.37 # via # -r requirements/edx/base.txt # django-ses # fs-s3fs # ora2 -botocore==1.35.27 +botocore==1.35.37 # via # -r requirements/edx/base.txt # boto3 @@ -124,7 +124,7 @@ cachetools==5.5.0 # -r requirements/edx/base.txt # google-auth # tox -camel-converter[pydantic]==3.1.2 +camel-converter[pydantic]==4.0.1 # via # -r requirements/edx/base.txt # meilisearch @@ -209,7 +209,7 @@ codejail-includes==1.0.0 # via -r requirements/edx/base.txt colorama==0.4.6 # via tox -coverage[toml]==7.6.1 +coverage[toml]==7.6.2 # via # -r requirements/edx/coverage.txt # pytest-cov @@ -247,9 +247,9 @@ defusedxml==0.7.1 # social-auth-core diff-cover==9.2.0 # via -r requirements/edx/coverage.txt -dill==0.3.8 +dill==0.3.9 # via pylint -distlib==0.3.8 +distlib==0.3.9 # via virtualenv django==4.2.16 # via @@ -427,7 +427,7 @@ django-sekizai==4.1.0 # via # -r requirements/edx/base.txt # openedx-django-wiki -django-ses==4.1.1 +django-ses==4.2.0 # via -r requirements/edx/base.txt django-simple-history==3.4.0 # via @@ -488,7 +488,7 @@ djangorestframework-xml==2.0.0 # via # -r requirements/edx/base.txt # edx-enterprise -dnspython==2.6.1 +dnspython==2.7.0 # via # -r requirements/edx/base.txt # pymongo @@ -533,7 +533,7 @@ edx-celeryutils==1.3.0 # super-csv edx-codejail==3.4.1 # via -r requirements/edx/base.txt -edx-completion==4.7.1 +edx-completion==4.7.2 # via -r requirements/edx/base.txt edx-django-release-util==1.4.0 # via @@ -542,7 +542,7 @@ edx-django-release-util==1.4.0 # edxval edx-django-sites-extensions==4.2.0 # via -r requirements/edx/base.txt -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r requirements/edx/base.txt # django-config-models @@ -579,9 +579,8 @@ edx-event-bus-kafka==5.8.1 # via -r requirements/edx/base.txt edx-event-bus-redis==0.5.0 # via -r requirements/edx/base.txt -edx-i18n-tools==1.5.0 +edx-i18n-tools==1.6.3 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt # ora2 edx-lint==5.4.0 @@ -624,7 +623,7 @@ edx-search==4.0.0 # via -r requirements/edx/base.txt edx-sga==0.25.0 # via -r requirements/edx/base.txt -edx-submissions==3.8.0 +edx-submissions==3.8.1 # via # -r requirements/edx/base.txt # ora2 @@ -674,7 +673,7 @@ execnet==2.1.1 # via pytest-xdist factory-boy==3.3.1 # via -r requirements/edx/testing.in -faker==30.0.0 +faker==30.3.0 # via factory-boy fastapi==0.115.0 # via pact-python @@ -717,7 +716,7 @@ geoip2==4.8.0 # via -r requirements/edx/base.txt glob2==0.7 # via -r requirements/edx/base.txt -google-api-core[grpc]==2.20.0 +google-api-core[grpc]==2.21.0 # via # -r requirements/edx/base.txt # firebase-admin @@ -725,7 +724,7 @@ google-api-core[grpc]==2.20.0 # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.147.0 +google-api-python-client==2.149.0 # via # -r requirements/edx/base.txt # firebase-admin @@ -769,14 +768,14 @@ googleapis-common-protos==1.65.0 # -r requirements/edx/base.txt # google-api-core # grpcio-status -grimp==3.4.1 +grimp==3.5 # via import-linter -grpcio==1.66.1 +grpcio==1.66.2 # via # -r requirements/edx/base.txt # google-api-core # grpcio-status -grpcio-status==1.66.1 +grpcio-status==1.66.2 # via # -r requirements/edx/base.txt # google-api-core @@ -797,7 +796,7 @@ httplib2==0.22.0 # google-auth-httplib2 httpretty==1.1.4 # via -r requirements/edx/testing.in -icalendar==5.0.13 +icalendar==6.0.0 # via -r requirements/edx/base.txt idna==3.10 # via @@ -807,7 +806,7 @@ idna==3.10 # requests # snowflake-connector-python # yarl -import-linter==2.0 +import-linter==2.1 # via -r requirements/edx/testing.in importlib-metadata==8.5.0 # via -r requirements/edx/base.txt @@ -824,7 +823,7 @@ interchange==2021.0.4 # py2neo ipaddress==1.0.23 # via -r requirements/edx/base.txt -isodate==0.6.1 +isodate==0.7.2 # via # -r requirements/edx/base.txt # python3-saml @@ -865,7 +864,7 @@ jsonschema==4.23.0 # -r requirements/edx/base.txt # drf-spectacular # optimizely-sdk -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via # -r requirements/edx/base.txt # jsonschema @@ -899,13 +898,13 @@ loremipsum==1.0.5 # ora2 lti-consumer-xblock==9.11.3 # via -r requirements/edx/base.txt -lxml==4.9.4 +lxml[html-clean]==5.3.0 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt # edx-i18n-tools # edxval # lti-consumer-xblock + # lxml-html-clean # olxcleaner # openedx-calc # ora2 @@ -913,6 +912,10 @@ lxml==4.9.4 # python3-saml # xblock # xmlsec +lxml-html-clean==0.3.1 + # via + # -r requirements/edx/base.txt + # lxml mailsnake==1.6.4 # via -r requirements/edx/base.txt mako==1.3.5 @@ -929,7 +932,7 @@ markdown==3.3.7 # openedx-django-wiki # staff-graded-xblock # xblock-poll -markupsafe==2.1.5 +markupsafe==3.0.1 # via # -r requirements/edx/base.txt # -r requirements/edx/coverage.txt @@ -974,7 +977,7 @@ multidict==6.1.0 # yarl mysqlclient==2.2.4 # via -r requirements/edx/base.txt -newrelic==9.13.0 +newrelic==10.0.0 # via # -r requirements/edx/base.txt # edx-django-utils @@ -1030,7 +1033,7 @@ openedx-events==9.14.1 # edx-name-affirmation # event-tracking # ora2 -openedx-filters==1.10.0 +openedx-filters==1.11.0 # via # -r requirements/edx/base.txt # lti-consumer-xblock @@ -1039,7 +1042,7 @@ openedx-learning==0.13.1 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt -openedx-mongodbproxy==0.2.1 +openedx-mongodbproxy==0.2.2 # via -r requirements/edx/base.txt optimizely-sdk==4.1.1 # via @@ -1057,7 +1060,7 @@ packaging==24.1 # pytest # snowflake-connector-python # tox -pact-python==2.2.1 +pact-python==2.2.2 # via -r requirements/edx/testing.in pansi==2020.7.3 # via @@ -1119,6 +1122,10 @@ prompt-toolkit==3.0.48 # via # -r requirements/edx/base.txt # click-repl +propcache==0.2.0 + # via + # -r requirements/edx/base.txt + # yarl proto-plus==1.24.0 # via # -r requirements/edx/base.txt @@ -1164,7 +1171,7 @@ pycparser==2.22 # via # -r requirements/edx/base.txt # cffi -pycryptodomex==3.20.0 +pycryptodomex==3.21.0 # via # -r requirements/edx/base.txt # edx-proctoring @@ -1340,7 +1347,6 @@ pytz==2024.2 # edx-tincan-py35 # event-tracking # fs - # icalendar # interchange # olxcleaner # ora2 @@ -1362,7 +1368,7 @@ random2==1.0.2 # via -r requirements/edx/base.txt recommender-xblock==2.2.1 # via -r requirements/edx/base.txt -redis==5.0.8 +redis==5.1.1 # via # -r requirements/edx/base.txt # walrus @@ -1422,7 +1428,7 @@ rules==3.5 # edx-enterprise # edx-proctoring # openedx-learning -s3transfer==0.10.2 +s3transfer==0.10.3 # via # -r requirements/edx/base.txt # boto3 @@ -1470,7 +1476,6 @@ six==1.16.0 # fs-s3fs # html5lib # interchange - # isodate # libsass # optimizely-sdk # pact-python @@ -1554,7 +1559,7 @@ tomlkit==0.13.2 # -r requirements/edx/base.txt # pylint # snowflake-connector-python -tox==4.20.0 +tox==4.21.2 # via -r requirements/edx/testing.in tqdm==4.66.5 # via @@ -1566,6 +1571,7 @@ typing-extensions==4.12.2 # -r requirements/edx/base.txt # django-countries # edx-opaque-keys + # faker # fastapi # grimp # import-linter @@ -1578,6 +1584,7 @@ tzdata==2024.2 # via # -r requirements/edx/base.txt # celery + # icalendar # kombu unicodecsv==0.14.1 # via @@ -1601,7 +1608,7 @@ urllib3==1.26.20 # requests user-util==1.1.0 # via -r requirements/edx/base.txt -uvicorn==0.30.6 +uvicorn==0.31.1 # via pact-python vine==5.1.0 # via @@ -1609,7 +1616,7 @@ vine==5.1.0 # amqp # celery # kombu -virtualenv==20.26.5 +virtualenv==20.26.6 # via tox voluptuous==0.15.2 # via @@ -1619,7 +1626,7 @@ walrus==0.9.4 # via # -r requirements/edx/base.txt # edx-event-bus-redis -watchdog==5.0.2 +watchdog==5.0.3 # via -r requirements/edx/base.txt wcwidth==0.2.13 # via @@ -1673,14 +1680,13 @@ xblock-utils==4.0.0 # -r requirements/edx/base.txt # edx-sga # xblock-poll -xmlsec==1.3.13 +xmlsec==1.3.14 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt # python3-saml xss-utils==0.6.0 # via -r requirements/edx/base.txt -yarl==1.12.1 +yarl==1.14.0 # via # -r requirements/edx/base.txt # aiohttp diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt index 5bcb2aa55084..110663ff6ab3 100644 --- a/requirements/pip-tools.txt +++ b/requirements/pip-tools.txt @@ -4,7 +4,7 @@ # # make upgrade # -build==1.2.2 +build==1.2.2.post1 # via pip-tools click==8.1.6 # via @@ -14,7 +14,7 @@ packaging==24.1 # via build pip-tools==7.4.1 # via -r requirements/pip-tools.in -pyproject-hooks==1.1.0 +pyproject-hooks==1.2.0 # via # build # pip-tools diff --git a/scripts/structures_pruning/requirements/base.txt b/scripts/structures_pruning/requirements/base.txt index b80c660b8749..a3fcacad2f7e 100644 --- a/scripts/structures_pruning/requirements/base.txt +++ b/scripts/structures_pruning/requirements/base.txt @@ -11,7 +11,7 @@ click==8.1.6 # click-log click-log==0.4.0 # via -r scripts/structures_pruning/requirements/base.in -dnspython==2.6.1 +dnspython==2.7.0 # via pymongo edx-opaque-keys==2.11.0 # via -r scripts/structures_pruning/requirements/base.in diff --git a/scripts/structures_pruning/requirements/testing.txt b/scripts/structures_pruning/requirements/testing.txt index 8be2e15973d0..94c6ac6982f3 100644 --- a/scripts/structures_pruning/requirements/testing.txt +++ b/scripts/structures_pruning/requirements/testing.txt @@ -12,7 +12,7 @@ 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 +dnspython==2.7.0 # via # -r scripts/structures_pruning/requirements/base.txt # pymongo diff --git a/scripts/user_retirement/requirements/base.txt b/scripts/user_retirement/requirements/base.txt index 9f57da73d0c2..576fa342c385 100644 --- a/scripts/user_retirement/requirements/base.txt +++ b/scripts/user_retirement/requirements/base.txt @@ -10,9 +10,9 @@ attrs==24.2.0 # via zeep backoff==2.2.1 # via -r scripts/user_retirement/requirements/base.in -boto3==1.35.27 +boto3==1.35.37 # via -r scripts/user_retirement/requirements/base.in -botocore==1.35.27 +botocore==1.35.37 # via # boto3 # s3transfer @@ -46,13 +46,13 @@ django-crum==0.7.9 # via edx-django-utils django-waffle==4.1.0 # via edx-django-utils -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via edx-rest-api-client edx-rest-api-client==6.0.0 # via -r scripts/user_retirement/requirements/base.in -google-api-core==2.20.0 +google-api-core==2.21.0 # via google-api-python-client -google-api-python-client==2.147.0 +google-api-python-client==2.149.0 # via -r scripts/user_retirement/requirements/base.in google-auth==2.35.0 # via @@ -69,7 +69,7 @@ httplib2==0.22.0 # google-auth-httplib2 idna==3.10 # via requests -isodate==0.6.1 +isodate==0.7.2 # via zeep jenkinsapi==0.3.13 # via -r scripts/user_retirement/requirements/base.in @@ -77,13 +77,11 @@ jmespath==1.0.1 # via # boto3 # botocore -lxml==4.9.4 - # via - # -c scripts/user_retirement/requirements/../../../requirements/constraints.txt - # zeep +lxml==5.3.0 + # via zeep more-itertools==10.5.0 # via simple-salesforce -newrelic==9.13.0 +newrelic==10.0.0 # via edx-django-utils pbr==6.1.0 # via stevedore @@ -138,7 +136,7 @@ requests-toolbelt==1.0.0 # via zeep rsa==4.9 # via google-auth -s3transfer==0.10.2 +s3transfer==0.10.3 # via boto3 simple-salesforce==1.12.6 # via -r scripts/user_retirement/requirements/base.in @@ -146,7 +144,6 @@ simplejson==3.19.3 # via -r scripts/user_retirement/requirements/base.in six==1.16.0 # via - # isodate # jenkinsapi # python-dateutil sqlparse==0.5.1 diff --git a/scripts/user_retirement/requirements/testing.txt b/scripts/user_retirement/requirements/testing.txt index d5aac1cd062f..6a165d7356ca 100644 --- a/scripts/user_retirement/requirements/testing.txt +++ b/scripts/user_retirement/requirements/testing.txt @@ -14,11 +14,11 @@ attrs==24.2.0 # zeep backoff==2.2.1 # via -r scripts/user_retirement/requirements/base.txt -boto3==1.35.27 +boto3==1.35.37 # via # -r scripts/user_retirement/requirements/base.txt # moto -botocore==1.35.27 +botocore==1.35.37 # via # -r scripts/user_retirement/requirements/base.txt # boto3 @@ -66,17 +66,17 @@ django-waffle==4.1.0 # via # -r scripts/user_retirement/requirements/base.txt # edx-django-utils -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r scripts/user_retirement/requirements/base.txt # edx-rest-api-client edx-rest-api-client==6.0.0 # via -r scripts/user_retirement/requirements/base.txt -google-api-core==2.20.0 +google-api-core==2.21.0 # via # -r scripts/user_retirement/requirements/base.txt # google-api-python-client -google-api-python-client==2.147.0 +google-api-python-client==2.149.0 # via -r scripts/user_retirement/requirements/base.txt google-auth==2.35.0 # via @@ -103,7 +103,7 @@ idna==3.10 # requests iniconfig==2.0.0 # via pytest -isodate==0.6.1 +isodate==0.7.2 # via # -r scripts/user_retirement/requirements/base.txt # zeep @@ -116,11 +116,11 @@ jmespath==1.0.1 # -r scripts/user_retirement/requirements/base.txt # boto3 # botocore -lxml==4.9.4 +lxml==5.3.0 # via # -r scripts/user_retirement/requirements/base.txt # zeep -markupsafe==2.1.5 +markupsafe==3.0.1 # via # jinja2 # werkzeug @@ -132,7 +132,7 @@ more-itertools==10.5.0 # simple-salesforce moto==4.2.14 # via -r scripts/user_retirement/requirements/testing.in -newrelic==9.13.0 +newrelic==10.0.0 # via # -r scripts/user_retirement/requirements/base.txt # edx-django-utils @@ -235,7 +235,7 @@ rsa==4.9 # via # -r scripts/user_retirement/requirements/base.txt # google-auth -s3transfer==0.10.2 +s3transfer==0.10.3 # via # -r scripts/user_retirement/requirements/base.txt # boto3 @@ -246,7 +246,6 @@ simplejson==3.19.3 six==1.16.0 # via # -r scripts/user_retirement/requirements/base.txt - # isodate # jenkinsapi # python-dateutil sqlparse==0.5.1 @@ -275,7 +274,7 @@ urllib3==1.26.20 # responses werkzeug==3.0.4 # via moto -xmltodict==0.13.0 +xmltodict==0.14.1 # via moto zeep==4.2.1 # via From 6076f075a89202417718d8d776209128cfca1e79 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Thu, 3 Oct 2024 20:50:08 +0530 Subject: [PATCH 03/17] feat: add & remove collections to component --- .../core/djangoapps/content_libraries/api.py | 52 +++++++++++++++++++ .../content_libraries/serializers.py | 8 +++ .../content_libraries/signal_handlers.py | 9 ++-- .../core/djangoapps/content_libraries/urls.py | 2 + .../djangoapps/content_libraries/views.py | 43 +++++++++++++++ 5 files changed, 110 insertions(+), 4 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index b9f3779af539..61afdbe09cd2 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -1235,6 +1235,58 @@ def update_library_collection_components( return collection +def update_library_component_collections( + library_key: LibraryLocatorV2, + component: Component, + *, + collection_keys: list[str], + created_by: int | None = None, + remove=False, + # As an optimization, callers may pass in a pre-fetched ContentLibrary instance + content_library: ContentLibrary | None = None, +) -> Collection: + """ + This api has opposite then functionality from `update_library_collection_components`. + It Associates the component with collections for the given collection keys. + + By default the Collections are added to the Component. + If remove=True, the Collections are removed from the Component. + + If you've already fetched the ContentLibrary, pass it in to avoid refetching. + + Raises: + * ContentLibraryCollectionNotFound if any of the given collection_keys don't match Collections in the given library. + + Returns the updated Component. + """ + if not content_library: + content_library = ContentLibrary.objects.get_by_key(library_key) # type: ignore[attr-defined] + assert content_library + assert content_library.learning_package_id + assert content_library.library_key == library_key + + # Note: Component.key matches its PublishableEntity.key + collection_qs = authoring_api.get_collections(content_library.learning_package_id).filter( + key__in=collection_keys + ) + + if remove: + component = authoring_api.remove_collections( + content_library.learning_package_id, + component, + collection_qs, + ) + else: + component = authoring_api.add_collections( + content_library.learning_package_id, + component, + collection_qs, + created_by=created_by, + ) + + return component + + def get_library_collection_usage_key( library_key: LibraryLocatorV2, collection_key: str, diff --git a/openedx/core/djangoapps/content_libraries/serializers.py b/openedx/core/djangoapps/content_libraries/serializers.py index 51ba55cd6b48..f9563ff3603c 100644 --- a/openedx/core/djangoapps/content_libraries/serializers.py +++ b/openedx/core/djangoapps/content_libraries/serializers.py @@ -305,3 +305,11 @@ class ContentLibraryCollectionComponentsUpdateSerializer(serializers.Serializer) """ usage_keys = serializers.ListField(child=UsageKeyV2Serializer(), allow_empty=False) + + +class ContentLibraryComponentCollectionsUpdateSerializer(serializers.Serializer): + """ + Serializer for adding/removing Collections to/from a Component. + """ + + collection_keys = serializers.ListField(child=serializers.CharField(), allow_empty=False) diff --git a/openedx/core/djangoapps/content_libraries/signal_handlers.py b/openedx/core/djangoapps/content_libraries/signal_handlers.py index fedee045a9f6..18e102bf686d 100644 --- a/openedx/core/djangoapps/content_libraries/signal_handlers.py +++ b/openedx/core/djangoapps/content_libraries/signal_handlers.py @@ -21,7 +21,7 @@ LIBRARY_COLLECTION_UPDATED, ) from openedx_learning.api.authoring import get_collection_components, get_component, get_components -from openedx_learning.api.authoring_models import Collection, CollectionPublishableEntity, Component +from openedx_learning.api.authoring_models import Collection, CollectionPublishableEntity, Component, PublishableEntity from lms.djangoapps.grades.api import signals as grades_signals @@ -177,9 +177,6 @@ def library_collection_entities_changed(sender, instance, action, pk_set, **kwar """ Sends a CONTENT_OBJECT_ASSOCIATIONS_CHANGED event for components added/removed/cleared from a collection. """ - if not isinstance(instance, Collection): - return - if action not in ["post_add", "post_remove", "post_clear"]: return @@ -191,6 +188,10 @@ def library_collection_entities_changed(sender, instance, action, pk_set, **kwar log.error("{instance} is not associated with a content library.") return + if isinstance(instance, PublishableEntity): + _library_collection_component_changed(instance.component, library.library_key) + return + if pk_set: components = get_collection_components( instance.learning_package_id, diff --git a/openedx/core/djangoapps/content_libraries/urls.py b/openedx/core/djangoapps/content_libraries/urls.py index 9455f0de5e61..e77c1b34d277 100644 --- a/openedx/core/djangoapps/content_libraries/urls.py +++ b/openedx/core/djangoapps/content_libraries/urls.py @@ -57,6 +57,8 @@ path('blocks//', include([ # Get metadata about a specific XBlock in this library, or delete the block: path('', views.LibraryBlockView.as_view()), + # Update collections for a given component + path('collections/', views.LibraryBlockCollectionsView.as_view(), name='update-collections'), # Get the LTI URL of a specific XBlock path('lti/', views.LibraryBlockLtiUrlView.as_view(), name='lti-url'), # Get the OLX source code of the specified block: diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py index 3712af6e597f..abf00d4ae93b 100644 --- a/openedx/core/djangoapps/content_libraries/views.py +++ b/openedx/core/djangoapps/content_libraries/views.py @@ -90,6 +90,7 @@ from organizations.exceptions import InvalidOrganizationException from organizations.models import Organization from rest_framework import status +from rest_framework.decorators import action from rest_framework.exceptions import NotFound, PermissionDenied, ValidationError from rest_framework.generics import GenericAPIView from rest_framework.parsers import MultiPartParser @@ -106,6 +107,7 @@ ContentLibraryPermissionLevelSerializer, ContentLibraryPermissionSerializer, ContentLibraryUpdateSerializer, + ContentLibraryComponentCollectionsUpdateSerializer, LibraryXBlockCreationSerializer, LibraryXBlockMetadataSerializer, LibraryXBlockTypeSerializer, @@ -640,6 +642,47 @@ def delete(self, request, usage_key_str): # pylint: disable=unused-argument return Response({}) +@method_decorator(non_atomic_requests, name="dispatch") +@view_auth_classes() +class LibraryBlockCollectionsView(APIView): + def _handle_request(self, request, usage_key_str) -> Response: + key = LibraryUsageLocatorV2.from_string(usage_key_str) + content_library = api.require_permission_for_library_key(key.lib_key, request.user, + permissions.CAN_EDIT_THIS_CONTENT_LIBRARY) + component = api.get_component_from_usage_key(key) + serializer = ContentLibraryComponentCollectionsUpdateSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + + collection_keys = serializer.validated_data['collection_keys'] + api.update_library_component_collections( + library_key=key.lib_key, + component=component, + collection_keys=collection_keys, + created_by=self.request.user.id, + remove=(request.method == "DELETE"), + content_library=content_library, + ) + + return Response({'count': len(collection_keys)}) + + @convert_exceptions + def patch(self, request, usage_key_str) -> Response: + """ + Adds Collections to a Component. + + Collection and Components must all be part of the given library/learning package. + """ + return self._handle_request(request, usage_key_str) + + @convert_exceptions + def delete(self, request, usage_key_str) -> Response: + """ + Removes Collections from a Component. + + Collection and Components must all be part of the given library/learning package. + """ + return self._handle_request(request, usage_key_str) + @method_decorator(non_atomic_requests, name="dispatch") @view_auth_classes() class LibraryBlockLtiUrlView(APIView): From f38fa8b32b328dd2aeaac6f0ec7592bbebf0c235 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Fri, 4 Oct 2024 11:43:52 +0530 Subject: [PATCH 04/17] refactor: set collections in a component --- .../core/djangoapps/content_libraries/api.py | 25 ++++++------------ .../djangoapps/content_libraries/views.py | 26 +++++-------------- 2 files changed, 15 insertions(+), 36 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index 61afdbe09cd2..8992f0fc7844 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -1241,16 +1241,14 @@ def update_library_component_collections( *, collection_keys: list[str], created_by: int | None = None, - remove=False, # As an optimization, callers may pass in a pre-fetched ContentLibrary instance content_library: ContentLibrary | None = None, ) -> Collection: """ - This api has opposite then functionality from `update_library_collection_components`. It Associates the component with collections for the given collection keys. - By default the Collections are added to the Component. - If remove=True, the Collections are removed from the Component. + Only collections in queryset are associated with component, all previous component-collections + associations are removed. If you've already fetched the ContentLibrary, pass it in to avoid refetching. @@ -1270,19 +1268,12 @@ def update_library_component_collections( key__in=collection_keys ) - if remove: - component = authoring_api.remove_collections( - content_library.learning_package_id, - component, - collection_qs, - ) - else: - component = authoring_api.add_collections( - content_library.learning_package_id, - component, - collection_qs, - created_by=created_by, - ) + component = authoring_api.set_collections( + content_library.learning_package_id, + component, + collection_qs, + created_by=created_by, + ) return component diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py index abf00d4ae93b..8ebd8fb2507a 100644 --- a/openedx/core/djangoapps/content_libraries/views.py +++ b/openedx/core/djangoapps/content_libraries/views.py @@ -645,7 +645,13 @@ def delete(self, request, usage_key_str): # pylint: disable=unused-argument @method_decorator(non_atomic_requests, name="dispatch") @view_auth_classes() class LibraryBlockCollectionsView(APIView): - def _handle_request(self, request, usage_key_str) -> Response: + @convert_exceptions + def patch(self, request, usage_key_str) -> Response: + """ + Adds Collections to a Component. + + Collection and Components must all be part of the given library/learning package. + """ key = LibraryUsageLocatorV2.from_string(usage_key_str) content_library = api.require_permission_for_library_key(key.lib_key, request.user, permissions.CAN_EDIT_THIS_CONTENT_LIBRARY) @@ -659,29 +665,11 @@ def _handle_request(self, request, usage_key_str) -> Response: component=component, collection_keys=collection_keys, created_by=self.request.user.id, - remove=(request.method == "DELETE"), content_library=content_library, ) return Response({'count': len(collection_keys)}) - @convert_exceptions - def patch(self, request, usage_key_str) -> Response: - """ - Adds Collections to a Component. - - Collection and Components must all be part of the given library/learning package. - """ - return self._handle_request(request, usage_key_str) - - @convert_exceptions - def delete(self, request, usage_key_str) -> Response: - """ - Removes Collections from a Component. - - Collection and Components must all be part of the given library/learning package. - """ - return self._handle_request(request, usage_key_str) @method_decorator(non_atomic_requests, name="dispatch") @view_auth_classes() From b84a54c280c363b25715f3a1123533edfa3c2da6 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Fri, 4 Oct 2024 20:11:22 +0530 Subject: [PATCH 05/17] refactor: async collections indexing --- openedx/core/djangoapps/content_libraries/api.py | 6 +++++- openedx/core/djangoapps/content_libraries/serializers.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index 8992f0fc7844..3ff26003f80d 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -1268,13 +1268,17 @@ def update_library_component_collections( key__in=collection_keys ) - component = authoring_api.set_collections( + affected_collections = authoring_api.set_collections( content_library.learning_package_id, component, collection_qs, created_by=created_by, ) + from ..content.search.tasks import update_library_collection_index_doc + for collection in affected_collections: + update_library_collection_index_doc.delay(str(library_key), collection.key) + return component diff --git a/openedx/core/djangoapps/content_libraries/serializers.py b/openedx/core/djangoapps/content_libraries/serializers.py index f9563ff3603c..6765656e69d5 100644 --- a/openedx/core/djangoapps/content_libraries/serializers.py +++ b/openedx/core/djangoapps/content_libraries/serializers.py @@ -312,4 +312,4 @@ class ContentLibraryComponentCollectionsUpdateSerializer(serializers.Serializer) Serializer for adding/removing Collections to/from a Component. """ - collection_keys = serializers.ListField(child=serializers.CharField(), allow_empty=False) + collection_keys = serializers.ListField(child=serializers.CharField(), allow_empty=True) From e6dbb8bc8a945d7dfede54e80d342db70c53c68e Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Fri, 4 Oct 2024 20:13:06 +0530 Subject: [PATCH 06/17] fix: lint issues --- openedx/core/djangoapps/content_libraries/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py index 8ebd8fb2507a..f909b682c038 100644 --- a/openedx/core/djangoapps/content_libraries/views.py +++ b/openedx/core/djangoapps/content_libraries/views.py @@ -90,7 +90,6 @@ from organizations.exceptions import InvalidOrganizationException from organizations.models import Organization from rest_framework import status -from rest_framework.decorators import action from rest_framework.exceptions import NotFound, PermissionDenied, ValidationError from rest_framework.generics import GenericAPIView from rest_framework.parsers import MultiPartParser @@ -645,6 +644,9 @@ def delete(self, request, usage_key_str): # pylint: disable=unused-argument @method_decorator(non_atomic_requests, name="dispatch") @view_auth_classes() class LibraryBlockCollectionsView(APIView): + """ + View to set collections for a component. + """ @convert_exceptions def patch(self, request, usage_key_str) -> Response: """ From 150487c106d6b154a45fb74806e3a8bae83ad61b Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Mon, 7 Oct 2024 11:32:01 +0530 Subject: [PATCH 07/17] test: test set collections for component --- .../core/djangoapps/content_libraries/api.py | 2 +- .../content_libraries/tests/test_api.py | 46 +++++++++++++++++++ .../djangoapps/content_libraries/views.py | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index 3ff26003f80d..8494e0cad336 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -1235,7 +1235,7 @@ def update_library_collection_components( return collection -def update_library_component_collections( +def set_library_component_collections( library_key: LibraryLocatorV2, component: Component, *, diff --git a/openedx/core/djangoapps/content_libraries/tests/test_api.py b/openedx/core/djangoapps/content_libraries/tests/test_api.py index 8041c508dc31..9ab60a2c9d26 100644 --- a/openedx/core/djangoapps/content_libraries/tests/test_api.py +++ b/openedx/core/djangoapps/content_libraries/tests/test_api.py @@ -308,6 +308,13 @@ def setUp(self): description="Description for Collection 2", created_by=self.user.id, ) + self.col3 = api.create_library_collection( + self.lib2.library_key, + collection_key="COL3", + title="Collection 3", + description="Description for Collection 3", + created_by=self.user.id, + ) # Create some library blocks in lib1 self.lib1_problem_block = self._add_block_to_library( @@ -316,6 +323,10 @@ def setUp(self): self.lib1_html_block = self._add_block_to_library( self.lib1.library_key, "html", "html1", ) + # Create some library blocks in lib2 + self.lib2_problem_block = self._add_block_to_library( + self.lib2.library_key, "problem", "problem2", + ) def test_create_library_collection(self): event_receiver = mock.Mock() @@ -498,3 +509,38 @@ def test_update_collection_components_from_wrong_library(self): ], ) assert self.lib1_problem_block["id"] in str(exc.exception) + + @mock.patch('openedx.core.djangoapps.content.search.api.upsert_library_collection_index_doc') + def test_set_library_component_collections(self, mock_update_collection_index_doc): + event_receiver = mock.Mock() + CONTENT_OBJECT_ASSOCIATIONS_CHANGED.connect(event_receiver) + assert not list(self.col2.entities.all()) + component = api.get_component_from_usage_key(UsageKey.from_string(self.lib2_problem_block["id"])) + + api.set_library_component_collections( + self.lib2.library_key, + component, + collection_keys=[self.col2.key, self.col3.key], + ) + + assert len(authoring_api.get_collection(self.lib2.learning_package_id, self.col2.key).entities.all()) == 1 + assert len(authoring_api.get_collection(self.lib2.learning_package_id, self.col3.key).entities.all()) == 1 + self.assertDictContainsSubset( + { + "signal": CONTENT_OBJECT_ASSOCIATIONS_CHANGED, + "sender": None, + "content_object": ContentObjectChangedData( + object_id=self.lib2_problem_block["id"], + changes=["collections"], + ), + }, + event_receiver.call_args_list[0].kwargs, + ) + self.assertListEqual( + list(mock_update_collection_index_doc.call_args_list[0][0]), + [self.lib2.library_key, self.col2.key] + ) + self.assertListEqual( + list(mock_update_collection_index_doc.call_args_list[1][0]), + [self.lib2.library_key, self.col3.key] + ) diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py index f909b682c038..a3aa2407f331 100644 --- a/openedx/core/djangoapps/content_libraries/views.py +++ b/openedx/core/djangoapps/content_libraries/views.py @@ -662,7 +662,7 @@ def patch(self, request, usage_key_str) -> Response: serializer.is_valid(raise_exception=True) collection_keys = serializer.validated_data['collection_keys'] - api.update_library_component_collections( + api.set_library_component_collections( library_key=key.lib_key, component=component, collection_keys=collection_keys, From 7a3841224dd4454eba0800f70c93f2c51cf05590 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Mon, 7 Oct 2024 11:47:00 +0530 Subject: [PATCH 08/17] chore: fix docs --- openedx/core/djangoapps/content_libraries/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py index a3aa2407f331..4d0dfe17fda1 100644 --- a/openedx/core/djangoapps/content_libraries/views.py +++ b/openedx/core/djangoapps/content_libraries/views.py @@ -650,7 +650,7 @@ class LibraryBlockCollectionsView(APIView): @convert_exceptions def patch(self, request, usage_key_str) -> Response: """ - Adds Collections to a Component. + Sets Collections for a Component. Collection and Components must all be part of the given library/learning package. """ From 08773d76aa5c76a270f6858649a182223721e7b8 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Mon, 7 Oct 2024 11:58:21 +0530 Subject: [PATCH 09/17] chore: temporarily update openedx-learning package --- requirements/constraints.txt | 2 +- requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 2 +- requirements/edx/doc.txt | 2 +- requirements/edx/testing.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 2fc1a1e745f3..26e0f9774b0b 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -126,7 +126,7 @@ optimizely-sdk<5.0 # Date: 2023-09-18 # pinning this version to avoid updates while the library is being developed # Issue for unpinning: https://github.com/openedx/edx-platform/issues/35269 -openedx-learning==0.13.1 +openedx-learning @ git+https://github.com/open-craft/openedx-learning@navin/component-collection-api # Date: 2023-11-29 # Open AI version 1.0.0 dropped support for openai.ChatCompletion which is currently in use in enterprise. diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index c7f7828f4115..fd3fc5124291 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -826,7 +826,7 @@ openedx-filters==1.11.0 # -r requirements/edx/kernel.in # lti-consumer-xblock # ora2 -openedx-learning==0.13.1 +openedx-learning @ git+https://github.com/open-craft/openedx-learning@navin/component-collection-api # via # -c requirements/edx/../constraints.txt # -r requirements/edx/kernel.in diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 13f3f6d5e637..c453da84a504 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -1378,7 +1378,7 @@ openedx-filters==1.11.0 # -r requirements/edx/testing.txt # lti-consumer-xblock # ora2 -openedx-learning==0.13.1 +openedx-learning @ git+https://github.com/open-craft/openedx-learning@navin/component-collection-api # via # -c requirements/edx/../constraints.txt # -r requirements/edx/doc.txt diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 30736a21a35a..3f3fcae9e85f 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -987,7 +987,7 @@ openedx-filters==1.11.0 # -r requirements/edx/base.txt # lti-consumer-xblock # ora2 -openedx-learning==0.13.1 +openedx-learning @ git+https://github.com/open-craft/openedx-learning@navin/component-collection-api # via # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 473da125341f..db72359da6f6 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -1038,7 +1038,7 @@ openedx-filters==1.11.0 # -r requirements/edx/base.txt # lti-consumer-xblock # ora2 -openedx-learning==0.13.1 +openedx-learning @ git+https://github.com/open-craft/openedx-learning@navin/component-collection-api # via # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt From 0ecb7c8185a2f2fa28badaa950e6b881127ba213 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Mon, 7 Oct 2024 12:02:47 +0530 Subject: [PATCH 10/17] fix: lint issues --- openedx/core/djangoapps/content_libraries/api.py | 2 +- openedx/core/djangoapps/content_libraries/views.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index 8494e0cad336..11b720bbb970 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -1243,7 +1243,7 @@ def set_library_component_collections( created_by: int | None = None, # As an optimization, callers may pass in a pre-fetched ContentLibrary instance content_library: ContentLibrary | None = None, -) -> Collection: +) -> Component: """ It Associates the component with collections for the given collection keys. diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py index 4d0dfe17fda1..c9051d155208 100644 --- a/openedx/core/djangoapps/content_libraries/views.py +++ b/openedx/core/djangoapps/content_libraries/views.py @@ -655,8 +655,11 @@ def patch(self, request, usage_key_str) -> Response: Collection and Components must all be part of the given library/learning package. """ key = LibraryUsageLocatorV2.from_string(usage_key_str) - content_library = api.require_permission_for_library_key(key.lib_key, request.user, - permissions.CAN_EDIT_THIS_CONTENT_LIBRARY) + content_library = api.require_permission_for_library_key( + key.lib_key, + request.user, + permissions.CAN_EDIT_THIS_CONTENT_LIBRARY + ) component = api.get_component_from_usage_key(key) serializer = ContentLibraryComponentCollectionsUpdateSerializer(data=request.data) serializer.is_valid(raise_exception=True) From 3a577a4397cf3e22f474ec591f1307faa03e94d6 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Tue, 8 Oct 2024 20:31:32 +0530 Subject: [PATCH 11/17] chore: add usage_key to filterable attribute --- openedx/core/djangoapps/content/search/api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openedx/core/djangoapps/content/search/api.py b/openedx/core/djangoapps/content/search/api.py index b5ed1bde78e1..17338f20ab83 100644 --- a/openedx/core/djangoapps/content/search/api.py +++ b/openedx/core/djangoapps/content/search/api.py @@ -320,6 +320,7 @@ def rebuild_index(status_cb: Callable[[str], None] | None = None) -> None: Fields.block_id, Fields.block_type, Fields.context_key, + Fields.usage_key, Fields.org, Fields.tags, Fields.tags + "." + Fields.tags_taxonomy, From 5ac6f568aa198f1c3991c6d8148af794966e237d Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Wed, 9 Oct 2024 16:18:48 +0530 Subject: [PATCH 12/17] feat: add collections to component api --- .../core/djangoapps/content_libraries/api.py | 22 +++++++++++++++++-- .../content_libraries/serializers.py | 10 +++++++++ .../djangoapps/content_libraries/views.py | 2 +- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index 11b720bbb970..e5f43375866e 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -204,6 +204,15 @@ class ContentLibraryPermissionEntry: access_level = attr.ib(AccessLevel.NO_ACCESS) +@attr.s +class CollectionMetadata: + """ + Class to represent collection metadata in a content library. + """ + key = attr.ib(type=str) + title = attr.ib(type=str) + + @attr.s class LibraryXBlockMetadata: """ @@ -219,9 +228,10 @@ class LibraryXBlockMetadata: published_by = attr.ib("") has_unpublished_changes = attr.ib(False) created = attr.ib(default=None, type=datetime) + collections = attr.ib(type=list[CollectionMetadata], factory=list) @classmethod - def from_component(cls, library_key, component): + def from_component(cls, library_key, component, collections=None): """ Construct a LibraryXBlockMetadata from a Component object. """ @@ -248,6 +258,7 @@ def from_component(cls, library_key, component): last_draft_created=last_draft_created, last_draft_created_by=last_draft_created_by, has_unpublished_changes=component.versioning.has_unpublished_changes, + collections=collections or [], ) @@ -690,7 +701,7 @@ def get_library_components(library_key, text_search=None, block_types=None) -> Q return components -def get_library_block(usage_key) -> LibraryXBlockMetadata: +def get_library_block(usage_key, include_collections=False) -> LibraryXBlockMetadata: """ Get metadata about (the draft version of) one specific XBlock in a library. @@ -713,9 +724,16 @@ def get_library_block(usage_key) -> LibraryXBlockMetadata: if not draft_version: raise ContentLibraryBlockNotFound(usage_key) + collections = [] + if include_collections: + collections = authoring_api.get_entity_collections( + component.learning_package_id, + component.key, + ).values('key', 'title') xblock_metadata = LibraryXBlockMetadata.from_component( library_key=usage_key.context_key, component=component, + collections=collections, ) return xblock_metadata diff --git a/openedx/core/djangoapps/content_libraries/serializers.py b/openedx/core/djangoapps/content_libraries/serializers.py index 6765656e69d5..8e9e5fc2a749 100644 --- a/openedx/core/djangoapps/content_libraries/serializers.py +++ b/openedx/core/djangoapps/content_libraries/serializers.py @@ -134,6 +134,14 @@ class ContentLibraryFilterSerializer(BaseFilterSerializer): type = serializers.ChoiceField(choices=LIBRARY_TYPES, default=None, required=False) +class CollectionMetadataSerializer(serializers.Serializer): + """ + Serializer for CollectionMetadata + """ + key = serializers.CharField() + title = serializers.CharField() + + class LibraryXBlockMetadataSerializer(serializers.Serializer): """ Serializer for LibraryXBlockMetadata @@ -161,6 +169,8 @@ class LibraryXBlockMetadataSerializer(serializers.Serializer): slug = serializers.CharField(write_only=True) tags_count = serializers.IntegerField(read_only=True) + collections = CollectionMetadataSerializer(many=True, required=False) + class LibraryXBlockTypeSerializer(serializers.Serializer): """ diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py index c9051d155208..6e50559f38f6 100644 --- a/openedx/core/djangoapps/content_libraries/views.py +++ b/openedx/core/djangoapps/content_libraries/views.py @@ -618,7 +618,7 @@ def get(self, request, usage_key_str): """ key = LibraryUsageLocatorV2.from_string(usage_key_str) api.require_permission_for_library_key(key.lib_key, request.user, permissions.CAN_VIEW_THIS_CONTENT_LIBRARY) - result = api.get_library_block(key) + result = api.get_library_block(key, include_collections=True) return Response(LibraryXBlockMetadataSerializer(result).data) From 70865865a2574d76f5cdbb589596ec7aa797d39a Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Wed, 9 Oct 2024 16:29:29 +0530 Subject: [PATCH 13/17] fix: lint issues --- openedx/core/djangoapps/content_libraries/api.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index e5f43375866e..07d07222234f 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -231,7 +231,7 @@ class LibraryXBlockMetadata: collections = attr.ib(type=list[CollectionMetadata], factory=list) @classmethod - def from_component(cls, library_key, component, collections=None): + def from_component(cls, library_key, component, associated_collections=None): """ Construct a LibraryXBlockMetadata from a Component object. """ @@ -258,7 +258,7 @@ def from_component(cls, library_key, component, collections=None): last_draft_created=last_draft_created, last_draft_created_by=last_draft_created_by, has_unpublished_changes=component.versioning.has_unpublished_changes, - collections=collections or [], + collections=associated_collections or [], ) @@ -724,16 +724,17 @@ def get_library_block(usage_key, include_collections=False) -> LibraryXBlockMeta if not draft_version: raise ContentLibraryBlockNotFound(usage_key) - collections = [] if include_collections: - collections = authoring_api.get_entity_collections( + associated_collections = authoring_api.get_entity_collections( component.learning_package_id, component.key, ).values('key', 'title') + else: + associated_collections = None xblock_metadata = LibraryXBlockMetadata.from_component( library_key=usage_key.context_key, component=component, - collections=collections, + associated_collections=associated_collections, ) return xblock_metadata From 6e887a9133d41dfb9ddbf4fab631e6899522523a Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Thu, 10 Oct 2024 11:50:26 +0530 Subject: [PATCH 14/17] fix: remove collection-entity through model post_delete signal handler The indexing update is already handled by m2m_changed handler. --- .../djangoapps/content_libraries/signal_handlers.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/signal_handlers.py b/openedx/core/djangoapps/content_libraries/signal_handlers.py index 18e102bf686d..1d723bea8b23 100644 --- a/openedx/core/djangoapps/content_libraries/signal_handlers.py +++ b/openedx/core/djangoapps/content_libraries/signal_handlers.py @@ -162,16 +162,6 @@ def library_collection_entity_saved(sender, instance, created, **kwargs): _library_collection_component_changed(component) -@receiver(post_delete, sender=CollectionPublishableEntity, dispatch_uid="library_collection_entity_deleted") -def library_collection_entity_deleted(sender, instance, **kwargs): - """ - Sends a CONTENT_OBJECT_ASSOCIATIONS_CHANGED event for components removed from a collection. - """ - # Component.pk matches its entity.pk - component = get_component(instance.entity_id) - _library_collection_component_changed(component) - - @receiver(m2m_changed, sender=CollectionPublishableEntity, dispatch_uid="library_collection_entities_changed") def library_collection_entities_changed(sender, instance, action, pk_set, **kwargs): """ From d23a5fdec2d73366daaacc03595ee1c38f218c11 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Thu, 10 Oct 2024 12:53:27 +0530 Subject: [PATCH 15/17] fix: use lazy field to control collection update task --- .../djangoapps/content/search/handlers.py | 20 +++++++---- .../core/djangoapps/content_libraries/api.py | 13 ++++++-- .../content_libraries/tests/test_api.py | 33 ++++++++++++++----- 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/openedx/core/djangoapps/content/search/handlers.py b/openedx/core/djangoapps/content/search/handlers.py index 085387d336b1..46b015367a0d 100644 --- a/openedx/core/djangoapps/content/search/handlers.py +++ b/openedx/core/djangoapps/content/search/handlers.py @@ -179,13 +179,19 @@ def library_collection_updated_handler(**kwargs) -> None: log.error("Received null or incorrect data for event") return - # Update collection index synchronously to make sure that search index is updated before - # the frontend invalidates/refetches index. - # See content_library_updated_handler for more details. - update_library_collection_index_doc.apply(args=[ - str(library_collection.library_key), - library_collection.collection_key, - ]) + if library_collection.lazy: + update_library_collection_index_doc.delay( + str(library_collection.library_key), + library_collection.collection_key, + ) + else: + # Update collection index synchronously to make sure that search index is updated before + # the frontend invalidates/refetches index. + # See content_library_updated_handler for more details. + update_library_collection_index_doc.apply(args=[ + str(library_collection.library_key), + library_collection.collection_key, + ]) @receiver(CONTENT_OBJECT_ASSOCIATIONS_CHANGED) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index 07d07222234f..1ba00ac7122c 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -80,6 +80,7 @@ from openedx_events.content_authoring.data import ( ContentLibraryData, LibraryBlockData, + LibraryCollectionData, ) from openedx_events.content_authoring.signals import ( CONTENT_LIBRARY_CREATED, @@ -88,6 +89,7 @@ LIBRARY_BLOCK_CREATED, LIBRARY_BLOCK_DELETED, LIBRARY_BLOCK_UPDATED, + LIBRARY_COLLECTION_UPDATED, ) from openedx_learning.api import authoring as authoring_api from openedx_learning.api.authoring_models import Collection, Component, MediaType, LearningPackage, PublishableEntity @@ -1294,9 +1296,16 @@ def set_library_component_collections( created_by=created_by, ) - from ..content.search.tasks import update_library_collection_index_doc + # For each collection, trigger LIBRARY_COLLECTION_UPDATED signal and set lazy=True to trigger + # collection indexing asynchronously. for collection in affected_collections: - update_library_collection_index_doc.delay(str(library_key), collection.key) + LIBRARY_COLLECTION_UPDATED.send_event( + library_collection=LibraryCollectionData( + library_key=library_key, + collection_key=collection.key, + lazy=True, + ) + ) return component diff --git a/openedx/core/djangoapps/content_libraries/tests/test_api.py b/openedx/core/djangoapps/content_libraries/tests/test_api.py index 9ab60a2c9d26..4e49bff8c9f1 100644 --- a/openedx/core/djangoapps/content_libraries/tests/test_api.py +++ b/openedx/core/djangoapps/content_libraries/tests/test_api.py @@ -510,10 +510,11 @@ def test_update_collection_components_from_wrong_library(self): ) assert self.lib1_problem_block["id"] in str(exc.exception) - @mock.patch('openedx.core.djangoapps.content.search.api.upsert_library_collection_index_doc') - def test_set_library_component_collections(self, mock_update_collection_index_doc): + def test_set_library_component_collections(self): event_receiver = mock.Mock() CONTENT_OBJECT_ASSOCIATIONS_CHANGED.connect(event_receiver) + collection_update_event_receiver = mock.Mock() + LIBRARY_COLLECTION_UPDATED.connect(collection_update_event_receiver) assert not list(self.col2.entities.all()) component = api.get_component_from_usage_key(UsageKey.from_string(self.lib2_problem_block["id"])) @@ -536,11 +537,27 @@ def test_set_library_component_collections(self, mock_update_collection_index_do }, event_receiver.call_args_list[0].kwargs, ) - self.assertListEqual( - list(mock_update_collection_index_doc.call_args_list[0][0]), - [self.lib2.library_key, self.col2.key] + self.assertDictContainsSubset( + { + "signal": LIBRARY_COLLECTION_UPDATED, + "sender": None, + "library_collection": LibraryCollectionData( + self.lib2.library_key, + collection_key=self.col2.key, + lazy=True, + ), + }, + collection_update_event_receiver.call_args_list[0].kwargs, ) - self.assertListEqual( - list(mock_update_collection_index_doc.call_args_list[1][0]), - [self.lib2.library_key, self.col3.key] + self.assertDictContainsSubset( + { + "signal": LIBRARY_COLLECTION_UPDATED, + "sender": None, + "library_collection": LibraryCollectionData( + self.lib2.library_key, + collection_key=self.col3.key, + lazy=True, + ), + }, + collection_update_event_receiver.call_args_list[1].kwargs, ) From 0613ebf9013dc3bab77ff6a4c68382962163114f Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Thu, 10 Oct 2024 12:53:44 +0530 Subject: [PATCH 16/17] chore: temporarily point openedx-events to dev branch --- requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 2 +- requirements/edx/doc.txt | 2 +- requirements/edx/kernel.in | 3 ++- requirements/edx/testing.txt | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index fd3fc5124291..682a7c875d3c 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -812,7 +812,7 @@ openedx-django-require==2.1.0 # via -r requirements/edx/kernel.in openedx-django-wiki==2.1.0 # via -r requirements/edx/kernel.in -openedx-events==9.14.1 +openedx-events @ git+https://github.com/open-craft/openedx-events@navin/update-library-collection-data # via # -r requirements/edx/kernel.in # edx-enterprise diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index c453da84a504..d7072458f9bb 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -1362,7 +1362,7 @@ openedx-django-wiki==2.1.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -openedx-events==9.14.1 +openedx-events @ git+https://github.com/open-craft/openedx-events@navin/update-library-collection-data # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 3f3fcae9e85f..ea2dd78977ed 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -973,7 +973,7 @@ openedx-django-require==2.1.0 # via -r requirements/edx/base.txt openedx-django-wiki==2.1.0 # via -r requirements/edx/base.txt -openedx-events==9.14.1 +openedx-events @ git+https://github.com/open-craft/openedx-events@navin/update-library-collection-data # via # -r requirements/edx/base.txt # edx-enterprise diff --git a/requirements/edx/kernel.in b/requirements/edx/kernel.in index a5b510742ac7..d399f938cfdb 100644 --- a/requirements/edx/kernel.in +++ b/requirements/edx/kernel.in @@ -117,7 +117,8 @@ olxcleaner openedx-atlas # CLI tool to manage translations openedx-calc # Library supporting mathematical calculations for Open edX openedx-django-require -openedx-events # Open edX Events from Hooks Extension Framework (OEP-50) +# openedx-events # Open edX Events from Hooks Extension Framework (OEP-50) +openedx-events @ git+https://github.com/open-craft/openedx-events@navin/update-library-collection-data openedx-filters # Open edX Filters from Hooks Extension Framework (OEP-50) openedx-learning # Open edX Learning core (experimental) openedx-mongodbproxy diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index db72359da6f6..4c76d4770302 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -1024,7 +1024,7 @@ openedx-django-require==2.1.0 # via -r requirements/edx/base.txt openedx-django-wiki==2.1.0 # via -r requirements/edx/base.txt -openedx-events==9.14.1 +openedx-events @ git+https://github.com/open-craft/openedx-events@navin/update-library-collection-data # via # -r requirements/edx/base.txt # edx-enterprise From bdee940b1cb55302b982cf4a160a24a01262db53 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Thu, 10 Oct 2024 16:15:03 +0530 Subject: [PATCH 17/17] fix: use get_components in m2m_changed signal handler Using `get_collection_components` does not work in case of post_remove as the component is already removed from collection and we don't really need additional filtering as we already have pk_set from the signal. --- .../content_libraries/signal_handlers.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/signal_handlers.py b/openedx/core/djangoapps/content_libraries/signal_handlers.py index 1d723bea8b23..49d40b27d689 100644 --- a/openedx/core/djangoapps/content_libraries/signal_handlers.py +++ b/openedx/core/djangoapps/content_libraries/signal_handlers.py @@ -20,7 +20,7 @@ LIBRARY_COLLECTION_DELETED, LIBRARY_COLLECTION_UPDATED, ) -from openedx_learning.api.authoring import get_collection_components, get_component, get_components +from openedx_learning.api.authoring import get_component, get_components from openedx_learning.api.authoring_models import Collection, CollectionPublishableEntity, Component, PublishableEntity from lms.djangoapps.grades.api import signals as grades_signals @@ -182,18 +182,12 @@ def library_collection_entities_changed(sender, instance, action, pk_set, **kwar _library_collection_component_changed(instance.component, library.library_key) return + # When action=="post_clear", pk_set==None + # Since the collection instance now has an empty entities set, + # we don't know which ones were removed, so we need to update associations for all library components. + components = get_components(instance.learning_package_id) if pk_set: - components = get_collection_components( - instance.learning_package_id, - instance.key, - ).filter(pk__in=pk_set) - else: - # When action=="post_clear", pk_set==None - # Since the collection instance now has an empty entities set, - # we don't know which ones were removed, so we need to update associations for all library components. - components = get_components( - instance.learning_package_id, - ) + components = components.filter(pk__in=pk_set) for component in components.all(): _library_collection_component_changed(component, library.library_key)