diff --git a/cms/djangoapps/contentstore/models.py b/cms/djangoapps/contentstore/models.py index f5ee218f3e..a4f2ce3c61 100644 --- a/cms/djangoapps/contentstore/models.py +++ b/cms/djangoapps/contentstore/models.py @@ -7,12 +7,12 @@ from itertools import chain from config_models.models import ConfigurationModel from django.db import models -from django.db.models import QuerySet, OuterRef, Case, When, Exists, Value, ExpressionWrapper -from django.db.models.fields import IntegerField, TextField, BooleanField +from django.db.models import Case, Exists, ExpressionWrapper, OuterRef, Q, QuerySet, Value, When +from django.db.models.fields import BooleanField, IntegerField, TextField from django.db.models.functions import Coalesce from django.db.models.lookups import GreaterThan from django.utils.translation import gettext_lazy as _ -from opaque_keys.edx.django.models import CourseKeyField, ContainerKeyField, UsageKeyField +from opaque_keys.edx.django.models import ContainerKeyField, CourseKeyField, UsageKeyField from opaque_keys.edx.keys import CourseKey, UsageKey from opaque_keys.edx.locator import LibraryContainerLocator from openedx_learning.api.authoring import get_published_version @@ -23,7 +23,6 @@ from openedx_learning.lib.fields import ( manual_date_time_field, ) - logger = logging.getLogger(__name__) @@ -391,7 +390,7 @@ class ContainerLink(EntityLinkBase): cls.objects.filter(**link_filter).select_related(*RELATED_FIELDS), ) if ready_to_sync is not None: - result = result.filter(ready_to_sync=ready_to_sync) + result = result.filter(Q(ready_to_sync=ready_to_sync) | Q(ready_to_sync_from_children=ready_to_sync)) # Handle top-level parents logic if use_top_level_parents: @@ -436,6 +435,11 @@ class ContainerLink(EntityLinkBase): ), then=1 ), + # If upstream block was deleted, set ready_to_sync = True + When( + Q(upstream_container__publishable_entity__published__version__version_num__isnull=True), + then=1 + ), default=0, output_field=models.IntegerField() ) @@ -457,6 +461,11 @@ class ContainerLink(EntityLinkBase): ), then=1 ), + # If upstream block was deleted, set ready_to_sync = True + When( + Q(upstream_block__publishable_entity__published__version__version_num__isnull=True), + then=1 + ), default=0, output_field=models.IntegerField() ) diff --git a/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_downstreams.py b/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_downstreams.py index ad10e373cf..b33d980732 100644 --- a/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_downstreams.py +++ b/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_downstreams.py @@ -23,7 +23,7 @@ from common.djangoapps.student.roles import CourseStaffRole from common.djangoapps.student.tests.factories import UserFactory from openedx.core.djangoapps.content_libraries import api as lib_api from xmodule.modulestore.django import modulestore -from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase, ImmediateOnCommitMixin +from xmodule.modulestore.tests.django_utils import ImmediateOnCommitMixin, SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import BlockFactory, CourseFactory from .. import downstreams as downstreams_views @@ -32,6 +32,7 @@ MOCK_UPSTREAM_ERROR = "your LibraryGPT subscription has expired" URL_PREFIX = '/api/libraries/v2/' URL_LIB_CREATE = URL_PREFIX URL_LIB_BLOCKS = URL_PREFIX + '{lib_key}/blocks/' +URL_LIB_BLOCK = URL_PREFIX + 'blocks/{block_key}/' URL_LIB_BLOCK_PUBLISH = URL_PREFIX + 'blocks/{block_key}/publish/' URL_LIB_BLOCK_OLX = URL_PREFIX + 'blocks/{block_key}/olx/' URL_LIB_CONTAINER = URL_PREFIX + 'containers/{container_key}/' # Get a container in this library @@ -277,6 +278,10 @@ class _BaseDownstreamViewTestMixin: data["slug"] = slug return self._api('post', URL_LIB_CONTAINERS.format(lib_key=lib_key), data, expect_response) + def _delete_component(self, block_key, expect_response=200): + """ Publish all changes in the specified container + children """ + return self._api('delete', URL_LIB_BLOCK.format(block_key=block_key), None, expect_response) + class SharedErrorTestCases(_BaseDownstreamViewTestMixin): """ @@ -1503,3 +1508,109 @@ class GetDownstreamSummaryViewTest( 'last_published_at': self.now.strftime('%Y-%m-%dT%H:%M:%S.%fZ'), }] self.assertListEqual(data, expected) + + +class GetDownstreamDeletedUpstream( + _BaseDownstreamViewTestMixin, + ImmediateOnCommitMixin, + SharedModuleStoreTestCase, +): + """ + Test that parent container is marked ready_to_sync when even when the only change is a deleted component under it + """ + def call_api( + self, + course_id: str | None = None, + ready_to_sync: bool | None = None, + upstream_key: str | None = None, + item_type: str | None = None, + use_top_level_parents: bool | None = None, + ): + data = {} + if course_id is not None: + data["course_id"] = str(course_id) + if ready_to_sync is not None: + data["ready_to_sync"] = str(ready_to_sync) + if upstream_key is not None: + data["upstream_key"] = str(upstream_key) + if item_type is not None: + data["item_type"] = str(item_type) + if use_top_level_parents is not None: + data["use_top_level_parents"] = str(use_top_level_parents) + return self.client.get("/api/contentstore/v2/downstreams/", data=data) + + def test_delete_component_should_be_ready_to_sync(self): + """ + Test deleting a component from library should mark the entire section container ready to sync + """ + # Create blocks + section_id = self._create_container(self.library_id, "section", "section-12", "Section 12")["id"] + subsection_id = self._create_container(self.library_id, "subsection", "subsection-12", "Subsection 12")["id"] + unit_id = self._create_container(self.library_id, "unit", "unit-12", "Unit 12")["id"] + video_id = self._add_block_to_library(self.library_id, "video", "video-bar-13")["id"] + section_key = ContainerKey.from_string(section_id) + subsection_key = ContainerKey.from_string(subsection_id) + unit_key = ContainerKey.from_string(unit_id) + video_key = LibraryUsageLocatorV2.from_string(video_id) + + # Set children + lib_api.update_container_children(section_key, [subsection_key], None) + lib_api.update_container_children(subsection_key, [unit_key], None) + lib_api.update_container_children(unit_key, [video_key], None) + self._publish_container(unit_id) + self._publish_container(subsection_id) + self._publish_container(section_id) + self._publish_library_block(video_id) + course = CourseFactory.create(display_name="Course New") + add_users(self.superuser, CourseStaffRole(course.id), self.course_user) + chapter = BlockFactory.create( + category='chapter', parent=course, upstream=section_id, upstream_version=2, + ) + sequential = BlockFactory.create( + category='sequential', + parent=chapter, + upstream=subsection_id, + upstream_version=2, + top_level_downstream_parent_key=get_block_key_string(chapter.usage_key), + ) + vertical = BlockFactory.create( + category='vertical', + parent=sequential, + upstream=unit_id, + upstream_version=2, + top_level_downstream_parent_key=get_block_key_string(chapter.usage_key), + ) + BlockFactory.create( + category='video', + parent=vertical, + upstream=video_id, + upstream_version=1, + top_level_downstream_parent_key=get_block_key_string(chapter.usage_key), + ) + self._delete_component(video_id) + self._publish_container(unit_id) + response = self.call_api(course_id=course.id, ready_to_sync=True, use_top_level_parents=True) + assert response.status_code == 200 + data = response.json()['results'] + assert len(data) == 1 + date_format = self.now.isoformat().split("+")[0] + 'Z' + expected_results = { + 'created': date_format, + 'downstream_context_key': str(course.id), + 'downstream_usage_key': str(chapter.usage_key), + 'downstream_customized': [], + 'id': 8, + 'ready_to_sync': False, + 'ready_to_sync_from_children': True, + 'top_level_parent_usage_key': None, + 'updated': date_format, + 'upstream_context_key': self.library_id, + 'upstream_context_title': self.library_title, + 'upstream_key': section_id, + 'upstream_type': 'container', + 'upstream_version': 2, + 'version_declined': None, + 'version_synced': 2, + } + + self.assertDictEqual(data[0], expected_results) diff --git a/cms/djangoapps/modulestore_migrator/rest_api/v1/serializers.py b/cms/djangoapps/modulestore_migrator/rest_api/v1/serializers.py index 7318079119..ac273f89ac 100644 --- a/cms/djangoapps/modulestore_migrator/rest_api/v1/serializers.py +++ b/cms/djangoapps/modulestore_migrator/rest_api/v1/serializers.py @@ -5,11 +5,13 @@ Serializers for the Course to Library Import API. from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import LearningContextKey from opaque_keys.edx.locator import LibraryLocatorV2 +from openedx_learning.api.authoring_models import Collection from rest_framework import serializers +from user_tasks.models import UserTaskStatus from user_tasks.serializers import StatusSerializer from cms.djangoapps.modulestore_migrator.data import CompositionLevel, RepeatHandlingStrategy -from cms.djangoapps.modulestore_migrator.models import ModulestoreMigration +from cms.djangoapps.modulestore_migrator.models import ModulestoreMigration, ModulestoreSource class ModulestoreMigrationSerializer(serializers.Serializer): @@ -173,3 +175,65 @@ class StatusWithModulestoreMigrationsSerializer(StatusSerializer): fields = super().get_fields() fields.pop('name', None) return fields + + +class LibraryMigrationCourseSourceSerializer(serializers.ModelSerializer): + """ + Serializer for the source course of a library migration. + """ + display_name = serializers.SerializerMethodField() + + class Meta: + model = ModulestoreSource + fields = ['key', 'display_name'] + + def get_display_name(self, obj): + """ + Return the display name of the source course + """ + return self.context["course_names"].get(str(obj.key), None) + + +class LibraryMigrationCollectionSerializer(serializers.ModelSerializer): + """ + Serializer for the target collection of a library migration. + """ + class Meta: + model = Collection + fields = ["key", "title"] + + +class LibraryMigrationCourseSerializer(serializers.ModelSerializer): + """ + Serializer for the course or legacylibrary migrations to V2 library. + """ + source = LibraryMigrationCourseSourceSerializer() # type: ignore[assignment] + target_collection = LibraryMigrationCollectionSerializer(required=False) + state = serializers.SerializerMethodField() + progress = serializers.SerializerMethodField() + + class Meta: + model = ModulestoreMigration + fields = [ + 'source', + 'target_collection', + 'state', + 'progress', + ] + + def get_state(self, obj: ModulestoreMigration): + """ + Return the state of the migration. + """ + if obj.is_failed or obj.task_status.state in [UserTaskStatus.FAILED, UserTaskStatus.CANCELED]: + return UserTaskStatus.FAILED + elif obj.task_status.state == UserTaskStatus.SUCCEEDED: + return UserTaskStatus.SUCCEEDED + + return UserTaskStatus.IN_PROGRESS + + def get_progress(self, obj: ModulestoreMigration): + """ + Return the progress of the migration. + """ + return obj.task_status.completed_steps / obj.task_status.total_steps diff --git a/cms/djangoapps/modulestore_migrator/rest_api/v1/urls.py b/cms/djangoapps/modulestore_migrator/rest_api/v1/urls.py index 7f66dc5f6d..596f519f53 100644 --- a/cms/djangoapps/modulestore_migrator/rest_api/v1/urls.py +++ b/cms/djangoapps/modulestore_migrator/rest_api/v1/urls.py @@ -3,10 +3,17 @@ Course to Library Import API v1 URLs. """ from rest_framework.routers import SimpleRouter -from .views import MigrationViewSet, BulkMigrationViewSet + +from .views import BulkMigrationViewSet, LibraryCourseMigrationViewSet, MigrationViewSet ROUTER = SimpleRouter() ROUTER.register(r'migrations', MigrationViewSet, basename='migrations') ROUTER.register(r'bulk_migration', BulkMigrationViewSet, basename='bulk-migration') +ROUTER.register( + r'library/(?P[^/.]+)/migrations/courses', + LibraryCourseMigrationViewSet, + basename='library-migrations', +) + urlpatterns = ROUTER.urls diff --git a/cms/djangoapps/modulestore_migrator/rest_api/v1/views.py b/cms/djangoapps/modulestore_migrator/rest_api/v1/views.py index f2b231c5c1..826312b138 100644 --- a/cms/djangoapps/modulestore_migrator/rest_api/v1/views.py +++ b/cms/djangoapps/modulestore_migrator/rest_api/v1/views.py @@ -6,22 +6,30 @@ import logging import edx_api_doc_tools as apidocs from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication from edx_rest_framework_extensions.auth.session.authentication import SessionAuthenticationAllowInactiveUser +from opaque_keys import InvalidKeyError +from opaque_keys.edx.locator import LibraryLocatorV2 +from rest_framework import status +from rest_framework.exceptions import ParseError +from rest_framework.mixins import ListModelMixin from rest_framework.permissions import IsAdminUser from rest_framework.response import Response -from rest_framework import status +from rest_framework.viewsets import GenericViewSet from user_tasks.models import UserTaskStatus from user_tasks.views import StatusViewSet -from cms.djangoapps.modulestore_migrator.api import start_migration_to_library, start_bulk_migration_to_library +from cms.djangoapps.modulestore_migrator.api import start_bulk_migration_to_library, start_migration_to_library +from openedx.core.djangoapps.content.course_overviews.models import CourseOverview +from openedx.core.djangoapps.content_libraries import api as lib_api from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser +from ...models import ModulestoreMigration from .serializers import ( - StatusWithModulestoreMigrationsSerializer, - ModulestoreMigrationSerializer, BulkModulestoreMigrationSerializer, + LibraryMigrationCourseSerializer, + ModulestoreMigrationSerializer, + StatusWithModulestoreMigrationsSerializer, ) - log = logging.getLogger(__name__) @@ -328,3 +336,55 @@ class BulkMigrationViewSet(StatusViewSet): We disable this endpoint to avoid confusion. """ raise NotImplementedError + + +@apidocs.schema_for( + "list", + "List all course migrations to a library.", + responses={ + 201: LibraryMigrationCourseSerializer, + 401: "The requester is not authenticated.", + 403: "The requester does not have permission to access the library.", + }, +) +class LibraryCourseMigrationViewSet(GenericViewSet, ListModelMixin): + """ + Show infomation about migrations related to a destination library. + """ + + serializer_class = LibraryMigrationCourseSerializer + pagination_class = None + queryset = ModulestoreMigration.objects.all().select_related('target_collection', 'target', 'task_status') + + def get_serializer_context(self): + """ + Add course name list to the serializer context. + + We need to display the course names in the migration view, and we get all of + them here to avoid futher queries. + """ + context = super().get_serializer_context() + queryset = self.get_queryset() + course_keys = queryset.values_list('source__key', flat=True) + courses = CourseOverview.get_all_courses(course_keys=course_keys) + context['course_names'] = dict((str(course.id), course.display_name) for course in courses) + return context + + def get_queryset(self): + """ + Override the default queryset to filter by the library key and check permissions. + """ + queryset = super().get_queryset() + lib_key_str = self.kwargs['lib_key_str'] + try: + library_key = LibraryLocatorV2.from_string(lib_key_str) + except InvalidKeyError as exc: + raise ParseError(detail=f"Malformed library key: {lib_key_str}") from exc + lib_api.require_permission_for_library_key( + library_key, + self.request.user, + lib_api.permissions.CAN_VIEW_THIS_CONTENT_LIBRARY + ) + queryset = queryset.filter(target__key=library_key, source__key__startswith='course-v1') + + return queryset diff --git a/cms/lib/xblock/upstream_sync.py b/cms/lib/xblock/upstream_sync.py index 8a089aeda7..b56e0d9568 100644 --- a/cms/lib/xblock/upstream_sync.py +++ b/cms/lib/xblock/upstream_sync.py @@ -87,6 +87,13 @@ class UpstreamLink: downstream_customized: list[str] | None # List of fields modified in downstream has_top_level_parent: bool # True if this Upstream link has a top-level parent + @property + def is_upstream_deleted(self) -> bool: + return bool( + self.upstream_ref and + self.version_available is None + ) + @property def is_ready_to_sync_individually(self) -> bool: return bool( @@ -94,7 +101,7 @@ class UpstreamLink: self.version_available and self.version_available > (self.version_synced or 0) and self.version_available > (self.version_declined or 0) - ) + ) or self.is_upstream_deleted def _check_children_ready_to_sync(self, xblock_downstream: XBlock, return_fast: bool) -> list[dict[str, str]]: """ diff --git a/common/static/data/geoip/GeoLite2-Country.mmdb b/common/static/data/geoip/GeoLite2-Country.mmdb index 5a7ccaaf87..a113c95c50 100644 Binary files a/common/static/data/geoip/GeoLite2-Country.mmdb and b/common/static/data/geoip/GeoLite2-Country.mmdb differ diff --git a/openedx/core/djangoapps/content_libraries/tests/test_containers.py b/openedx/core/djangoapps/content_libraries/tests/test_containers.py index 8b7b0c5273..7e6eac3bed 100644 --- a/openedx/core/djangoapps/content_libraries/tests/test_containers.py +++ b/openedx/core/djangoapps/content_libraries/tests/test_containers.py @@ -630,7 +630,7 @@ class ContainersTestCase(ContentLibrariesRestApiTest): ] def test_subsection_hierarchy(self): - with self.assertNumQueries(93): + with self.assertNumQueries(95): hierarchy = self._get_container_hierarchy(self.subsection_with_units["id"]) assert hierarchy["object_key"] == self.subsection_with_units["id"] assert hierarchy["components"] == [ @@ -653,7 +653,7 @@ class ContainersTestCase(ContentLibrariesRestApiTest): ] def test_units_hierarchy(self): - with self.assertNumQueries(56): + with self.assertNumQueries(60): hierarchy = self._get_container_hierarchy(self.unit_with_components["id"]) assert hierarchy["object_key"] == self.unit_with_components["id"] assert hierarchy["components"] == [ @@ -679,7 +679,7 @@ class ContainersTestCase(ContentLibrariesRestApiTest): ) def test_block_hierarchy(self): - with self.assertNumQueries(21): + with self.assertNumQueries(27): hierarchy = self._get_block_hierarchy(self.problem_block["id"]) assert hierarchy["object_key"] == self.problem_block["id"] assert hierarchy["components"] == [ diff --git a/openedx/core/djangoapps/user_api/tests/test_constants.py b/openedx/core/djangoapps/user_api/tests/test_constants.py index 96db68bba9..ffa7903a94 100644 --- a/openedx/core/djangoapps/user_api/tests/test_constants.py +++ b/openedx/core/djangoapps/user_api/tests/test_constants.py @@ -16,7 +16,7 @@ SORTED_COUNTRIES = [ ("AU", "Australia"), ("AT", "Austria"), ("AZ", "Azerbaijan"), - ("BS", "Bahamas"), + ("BS", "Bahamas (The)"), ("BH", "Bahrain"), ("BD", "Bangladesh"), ("BB", "Barbados"), @@ -51,7 +51,6 @@ SORTED_COUNTRIES = [ ("CO", "Colombia"), ("KM", "Comoros"), ("CG", "Congo"), - ("CD", "Congo (the Democratic Republic of the)"), ("CK", "Cook Islands"), ("CR", "Costa Rica"), ("CI", "C\xf4te d'Ivoire"), @@ -60,6 +59,7 @@ SORTED_COUNTRIES = [ ("CW", "Cura\xe7ao"), ("CY", "Cyprus"), ("CZ", "Czechia"), + ("CD", "Democratic Republic of the Congo"), ("DK", "Denmark"), ("DJ", "Djibouti"), ("DM", "Dominica"), @@ -98,7 +98,6 @@ SORTED_COUNTRIES = [ ("GY", "Guyana"), ("HT", "Haiti"), ("HM", "Heard Island and McDonald Islands"), - ("VA", "Holy See"), ("HN", "Honduras"), ("HK", "Hong Kong"), ("HU", "Hungary"), @@ -170,7 +169,7 @@ SORTED_COUNTRIES = [ ("OM", "Oman"), ("PK", "Pakistan"), ("PW", "Palau"), - ("PS", "Palestine, State of"), + ("PS", "Palestine"), ("PA", "Panama"), ("PG", "Papua New Guinea"), ("PY", "Paraguay"), @@ -186,7 +185,7 @@ SORTED_COUNTRIES = [ ("RU", "Russia"), ("RW", "Rwanda"), ("BL", "Saint Barth\xe9lemy"), - ("SH", "Saint Helena, Ascension and Tristan da Cunha"), + ("SH", "Saint Helena"), ("KN", "Saint Kitts and Nevis"), ("LC", "Saint Lucia"), ("MF", "Saint Martin (French part)"), @@ -207,7 +206,7 @@ SORTED_COUNTRIES = [ ("SB", "Solomon Islands"), ("SO", "Somalia"), ("ZA", "South Africa"), - ("GS", "South Georgia and the South Sandwich Islands"), + ("GS", "South Georgia"), ("KR", "South Korea"), ("SS", "South Sudan"), ("ES", "Spain"), @@ -241,6 +240,7 @@ SORTED_COUNTRIES = [ ("UY", "Uruguay"), ("UZ", "Uzbekistan"), ("VU", "Vanuatu"), + ("VA", "Vatican City"), ("VE", "Venezuela"), ("VN", "Vietnam"), ("VG", "Virgin Islands (British)"), diff --git a/requirements/common_constraints.txt b/requirements/common_constraints.txt index 28ebe29f5c..1f3e81f503 100644 --- a/requirements/common_constraints.txt +++ b/requirements/common_constraints.txt @@ -16,14 +16,14 @@ # this file from Github directly. It does not require packaging in edx-lint. # using LTS django version - +Django<6.0 # elasticsearch>=7.14.0 includes breaking changes in it which caused issues in discovery upgrade process. # elastic search changelog: https://www.elastic.co/guide/en/enterprise-search/master/release-notes-7.14.0.html # See https://github.com/openedx/edx-platform/issues/35126 for more info elasticsearch<7.14.0 -# pip 25.3 is incompatible with pip-tools hence causing failures during the build process +# pip 25.3 is incompatible with pip-tools hence causing failures during the build process # Make upgrade command and all requirements upgrade jobs are broken due to this. # See issue https://github.com/openedx/public-engineering/issues/440 for details regarding the ongoing fix. # The constraint can be removed once a release (pip-tools > 7.5.1) is available with support for pip 25.3 diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 96ee4cbcbf..c96838f937 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -61,7 +61,7 @@ numpy<2.0.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.29.1 +openedx-learning==0.30.0 # 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-sandbox/README.rst b/requirements/edx-sandbox/README.rst index 4d628f3e2a..d4b1ab8199 100644 --- a/requirements/edx-sandbox/README.rst +++ b/requirements/edx-sandbox/README.rst @@ -74,3 +74,21 @@ releases/sumac.txt .. _Python changelog: https://docs.python.org/3.11/whatsnew/changelog.html .. _SciPy changelog: https://docs.scipy.org/doc/scipy/release.html .. _NumPy changelog: https://numpy.org/doc/stable/release.html + +releases/teak.txt +------------------ + +* Frozen at the time of the Teak release +* Supports Python 3.11 and Python 3.12 +* SciPy is upgraded from 1.14.1 to 1.15.2 + +.. _SciPy changelog: https://docs.scipy.org/doc/scipy/release.html + +releases/ulmo.txt +------------------ + +* Frozen at the time of the Ulmo release +* Supports Python 3.11 and Python 3.12 +* SciPy is upgraded from 1.15.2 to 1.16.3 + +.. _SciPy changelog: https://docs.scipy.org/doc/scipy/release.html diff --git a/requirements/edx-sandbox/base.txt b/requirements/edx-sandbox/base.txt index 887f5cc1be..daf49eeb70 100644 --- a/requirements/edx-sandbox/base.txt +++ b/requirements/edx-sandbox/base.txt @@ -74,7 +74,7 @@ python-dateutil==2.9.0.post0 # via matplotlib random2==1.0.2 # via -r requirements/edx-sandbox/base.in -regex==2025.10.23 +regex==2025.11.3 # via nltk scipy==1.16.3 # via diff --git a/requirements/edx-sandbox/releases/ulmo.txt b/requirements/edx-sandbox/releases/ulmo.txt new file mode 100644 index 0000000000..887f5cc1be --- /dev/null +++ b/requirements/edx-sandbox/releases/ulmo.txt @@ -0,0 +1,90 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# make upgrade +# +cffi==2.0.0 + # via cryptography +chem==2.0.0 + # via -r requirements/edx-sandbox/base.in +click==8.3.0 + # via nltk +codejail-includes==2.0.0 + # via -r requirements/edx-sandbox/base.in +contourpy==1.3.3 + # via matplotlib +cryptography==45.0.7 + # via + # -c requirements/constraints.txt + # -r requirements/edx-sandbox/base.in +cycler==0.12.1 + # via matplotlib +fonttools==4.60.1 + # via matplotlib +joblib==1.5.2 + # via nltk +kiwisolver==1.4.9 + # via matplotlib +lxml[html-clean]==5.3.2 + # via + # -c requirements/constraints.txt + # -r requirements/edx-sandbox/base.in + # lxml-html-clean + # openedx-calc +lxml-html-clean==0.4.3 + # via lxml +markupsafe==3.0.3 + # via + # chem + # openedx-calc +matplotlib==3.10.7 + # via -r requirements/edx-sandbox/base.in +mpmath==1.3.0 + # via sympy +networkx==3.5 + # via -r requirements/edx-sandbox/base.in +nltk==3.9.2 + # via + # -r requirements/edx-sandbox/base.in + # chem +numpy==1.26.4 + # via + # -c requirements/constraints.txt + # chem + # contourpy + # matplotlib + # openedx-calc + # scipy +openedx-calc==4.0.2 + # via -r requirements/edx-sandbox/base.in +packaging==25.0 + # via matplotlib +pillow==12.0.0 + # via matplotlib +pycparser==2.23 + # via cffi +pyparsing==3.2.5 + # via + # -r requirements/edx-sandbox/base.in + # chem + # matplotlib + # openedx-calc +python-dateutil==2.9.0.post0 + # via matplotlib +random2==1.0.2 + # via -r requirements/edx-sandbox/base.in +regex==2025.10.23 + # via nltk +scipy==1.16.3 + # via + # -r requirements/edx-sandbox/base.in + # chem +six==1.17.0 + # via python-dateutil +sympy==1.14.0 + # via + # -r requirements/edx-sandbox/base.in + # openedx-calc +tqdm==4.67.1 + # via nltk diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 1f6eb49a2a..137d1deaf9 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -69,14 +69,14 @@ bleach[css]==6.3.0 # xblock-poll boto==2.49.0 # via -r requirements/edx/kernel.in -boto3==1.40.62 +boto3==1.40.66 # via # -r requirements/edx/kernel.in # django-ses # fs-s3fs # ora2 # snowflake-connector-python -botocore==1.40.62 +botocore==1.40.66 # via # -r requirements/edx/kernel.in # boto3 @@ -170,8 +170,9 @@ defusedxml==0.7.1 # ora2 # python3-openid # social-auth-core -django==5.2.7 +django==5.2.8 # via + # -c requirements/common_constraints.txt # -c requirements/constraints.txt # -r requirements/edx/kernel.in # casbin-django-orm-adapter @@ -265,7 +266,7 @@ django-config-models==2.9.0 # lti-consumer-xblock django-cors-headers==4.9.0 # via -r requirements/edx/kernel.in -django-countries==7.6.1 +django-countries==8.0.0 # via # -r requirements/edx/kernel.in # edx-enterprise @@ -375,7 +376,7 @@ django-waffle==5.0.0 # edx-enterprise # edx-proctoring # edx-toggles -django-webpack-loader==3.2.1 +django-webpack-loader==3.2.2 # via # -r requirements/edx/kernel.in # edx-proctoring @@ -408,7 +409,7 @@ done-xblock==2.5.0 # via -r requirements/edx/bundled.in drf-jwt==1.19.2 # via edx-drf-extensions -drf-spectacular==0.28.0 +drf-spectacular==0.29.0 # via -r requirements/edx/kernel.in drf-yasg==1.21.11 # via @@ -612,7 +613,7 @@ google-api-core[grpc]==2.28.1 # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-auth==2.42.0 +google-auth==2.42.1 # via # google-api-core # google-cloud-core @@ -624,7 +625,7 @@ google-cloud-core==2.5.0 # google-cloud-storage google-cloud-firestore==2.21.0 # via firebase-admin -google-cloud-storage==3.4.1 +google-cloud-storage==3.5.0 # via firebase-admin google-crc32c==1.7.1 # via @@ -662,7 +663,7 @@ httpx[http2]==0.28.1 # via firebase-admin hyperframe==6.1.0 # via h2 -icalendar==6.3.1 +icalendar==6.3.2 # via -r requirements/edx/kernel.in idna==3.11 # via @@ -753,7 +754,7 @@ mako==1.3.10 # lti-consumer-xblock # xblock # xblock-utils -markdown==3.9 +markdown==3.10 # via # -r requirements/edx/kernel.in # openedx-django-wiki @@ -790,7 +791,7 @@ mysqlclient==2.2.7 # via # -r requirements/edx/kernel.in # openedx-forum -nh3==0.3.1 +nh3==0.3.2 # via # -r requirements/edx/kernel.in # xblocks-contrib @@ -825,7 +826,7 @@ openedx-atlas==0.7.0 # enterprise-integrated-channels # openedx-authz # openedx-forum -openedx-authz==0.11.2 +openedx-authz==0.13.0 # via -r requirements/edx/kernel.in openedx-calc==4.0.2 # via -r requirements/edx/kernel.in @@ -854,7 +855,7 @@ openedx-filters==2.1.0 # ora2 openedx-forum==0.3.8 # via -r requirements/edx/kernel.in -openedx-learning==0.29.1 +openedx-learning==0.30.0 # via # -c requirements/constraints.txt # -r requirements/edx/kernel.in @@ -912,7 +913,7 @@ protobuf==6.33.0 # googleapis-common-protos # grpcio-status # proto-plus -psutil==7.1.2 +psutil==7.1.3 # via # -r requirements/edx/kernel.in # edx-django-utils @@ -936,9 +937,9 @@ pycryptodomex==3.23.0 # -r requirements/edx/kernel.in # edx-proctoring # lti-consumer-xblock -pydantic==2.12.3 +pydantic==2.12.4 # via camel-converter -pydantic-core==2.41.4 +pydantic-core==2.41.5 # via pydantic pyjwt[crypto]==2.10.1 # via @@ -1049,7 +1050,7 @@ referencing==0.37.0 # via # jsonschema # jsonschema-specifications -regex==2025.10.23 +regex==2025.11.3 # via nltk requests==2.32.5 # via diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index b3fc160729..8b711055c9 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -141,7 +141,7 @@ boto==2.49.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -boto3==1.40.62 +boto3==1.40.66 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -149,7 +149,7 @@ boto3==1.40.62 # fs-s3fs # ora2 # snowflake-connector-python -botocore==1.40.62 +botocore==1.40.66 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -343,8 +343,9 @@ distlib==0.4.0 # via # -r requirements/edx/testing.txt # virtualenv -django==5.2.7 +django==5.2.8 # via + # -c requirements/common_constraints.txt # -c requirements/constraints.txt # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -458,7 +459,7 @@ django-cors-headers==4.9.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -django-countries==7.6.1 +django-countries==8.0.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -616,7 +617,7 @@ django-waffle==5.0.0 # edx-enterprise # edx-proctoring # edx-toggles -django-webpack-loader==3.2.1 +django-webpack-loader==3.2.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -670,7 +671,7 @@ drf-jwt==1.19.2 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # edx-drf-extensions -drf-spectacular==0.28.0 +drf-spectacular==0.29.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -915,7 +916,7 @@ faker==37.12.0 # via # -r requirements/edx/testing.txt # factory-boy -fastapi==0.120.2 +fastapi==0.121.0 # via # -r requirements/edx/testing.txt # pact-python @@ -978,7 +979,7 @@ google-api-core[grpc]==2.28.1 # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-auth==2.42.0 +google-auth==2.42.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -997,7 +998,7 @@ google-cloud-firestore==2.21.0 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # firebase-admin -google-cloud-storage==3.4.1 +google-cloud-storage==3.5.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1080,7 +1081,7 @@ hyperframe==6.1.0 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # h2 -icalendar==6.3.1 +icalendar==6.3.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1248,7 +1249,7 @@ mako==1.3.10 # lti-consumer-xblock # xblock # xblock-utils -markdown==3.9 +markdown==3.10 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1325,7 +1326,7 @@ mysqlclient==2.2.7 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # openedx-forum -nh3==0.3.1 +nh3==0.3.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1375,7 +1376,7 @@ openedx-atlas==0.7.0 # enterprise-integrated-channels # openedx-authz # openedx-forum -openedx-authz==0.11.2 +openedx-authz==0.13.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1418,7 +1419,7 @@ openedx-forum==0.3.8 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -openedx-learning==0.29.1 +openedx-learning==0.30.0 # via # -c requirements/constraints.txt # -r requirements/edx/doc.txt @@ -1539,7 +1540,7 @@ protobuf==6.33.0 # googleapis-common-protos # grpcio-status # proto-plus -psutil==7.1.2 +psutil==7.1.3 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1585,13 +1586,13 @@ pycryptodomex==3.23.0 # -r requirements/edx/testing.txt # edx-proctoring # lti-consumer-xblock -pydantic==2.12.3 +pydantic==2.12.4 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # camel-converter # fastapi -pydantic-core==2.41.4 +pydantic-core==2.41.5 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1830,7 +1831,7 @@ referencing==0.37.0 # -r requirements/edx/testing.txt # jsonschema # jsonschema-specifications -regex==2025.10.23 +regex==2025.11.3 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -2073,7 +2074,7 @@ staff-graded-xblock==3.1.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -starlette==0.49.1 +starlette==0.49.3 # via # -r requirements/edx/testing.txt # fastapi diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index ac81bd89e8..9ea6b1a4fa 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -104,14 +104,14 @@ bleach[css]==6.3.0 # xblock-poll boto==2.49.0 # via -r requirements/edx/base.txt -boto3==1.40.62 +boto3==1.40.66 # via # -r requirements/edx/base.txt # django-ses # fs-s3fs # ora2 # snowflake-connector-python -botocore==1.40.62 +botocore==1.40.66 # via # -r requirements/edx/base.txt # boto3 @@ -232,8 +232,9 @@ defusedxml==0.7.1 # ora2 # python3-openid # social-auth-core -django==5.2.7 +django==5.2.8 # via + # -c requirements/common_constraints.txt # -c requirements/constraints.txt # -r requirements/edx/base.txt # casbin-django-orm-adapter @@ -333,7 +334,7 @@ django-config-models==2.9.0 # lti-consumer-xblock django-cors-headers==4.9.0 # via -r requirements/edx/base.txt -django-countries==7.6.1 +django-countries==8.0.0 # via # -r requirements/edx/base.txt # edx-enterprise @@ -451,7 +452,7 @@ django-waffle==5.0.0 # edx-enterprise # edx-proctoring # edx-toggles -django-webpack-loader==3.2.1 +django-webpack-loader==3.2.2 # via # -r requirements/edx/base.txt # edx-proctoring @@ -495,7 +496,7 @@ drf-jwt==1.19.2 # via # -r requirements/edx/base.txt # edx-drf-extensions -drf-spectacular==0.28.0 +drf-spectacular==0.29.0 # via -r requirements/edx/base.txt drf-yasg==1.21.11 # via @@ -717,7 +718,7 @@ google-api-core[grpc]==2.28.1 # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-auth==2.42.0 +google-auth==2.42.1 # via # -r requirements/edx/base.txt # google-api-core @@ -733,7 +734,7 @@ google-cloud-firestore==2.21.0 # via # -r requirements/edx/base.txt # firebase-admin -google-cloud-storage==3.4.1 +google-cloud-storage==3.5.0 # via # -r requirements/edx/base.txt # firebase-admin @@ -792,7 +793,7 @@ hyperframe==6.1.0 # via # -r requirements/edx/base.txt # h2 -icalendar==6.3.1 +icalendar==6.3.2 # via -r requirements/edx/base.txt idna==3.11 # via @@ -912,7 +913,7 @@ mako==1.3.10 # lti-consumer-xblock # xblock # xblock-utils -markdown==3.9 +markdown==3.10 # via # -r requirements/edx/base.txt # openedx-django-wiki @@ -963,7 +964,7 @@ mysqlclient==2.2.7 # via # -r requirements/edx/base.txt # openedx-forum -nh3==0.3.1 +nh3==0.3.2 # via # -r requirements/edx/base.txt # xblocks-contrib @@ -1002,7 +1003,7 @@ openedx-atlas==0.7.0 # enterprise-integrated-channels # openedx-authz # openedx-forum -openedx-authz==0.11.2 +openedx-authz==0.13.0 # via -r requirements/edx/base.txt openedx-calc==4.0.2 # via -r requirements/edx/base.txt @@ -1032,7 +1033,7 @@ openedx-filters==2.1.0 # ora2 openedx-forum==0.3.8 # via -r requirements/edx/base.txt -openedx-learning==0.29.1 +openedx-learning==0.30.0 # via # -c requirements/constraints.txt # -r requirements/edx/base.txt @@ -1109,7 +1110,7 @@ protobuf==6.33.0 # googleapis-common-protos # grpcio-status # proto-plus -psutil==7.1.2 +psutil==7.1.3 # via # -r requirements/edx/base.txt # edx-django-utils @@ -1139,11 +1140,11 @@ pycryptodomex==3.23.0 # -r requirements/edx/base.txt # edx-proctoring # lti-consumer-xblock -pydantic==2.12.3 +pydantic==2.12.4 # via # -r requirements/edx/base.txt # camel-converter -pydantic-core==2.41.4 +pydantic-core==2.41.5 # via # -r requirements/edx/base.txt # pydantic @@ -1281,7 +1282,7 @@ referencing==0.37.0 # -r requirements/edx/base.txt # jsonschema # jsonschema-specifications -regex==2025.10.23 +regex==2025.11.3 # via # -r requirements/edx/base.txt # nltk diff --git a/requirements/edx/semgrep.txt b/requirements/edx/semgrep.txt index 2a779f3cfa..6166b4675c 100644 --- a/requirements/edx/semgrep.txt +++ b/requirements/edx/semgrep.txt @@ -113,17 +113,17 @@ packaging==25.0 # via # opentelemetry-instrumentation # semgrep -peewee==3.18.2 +peewee==3.18.3 # via semgrep protobuf==6.33.0 # via # googleapis-common-protos # opentelemetry-proto -pydantic==2.12.3 +pydantic==2.12.4 # via # mcp # pydantic-settings -pydantic-core==2.41.4 +pydantic-core==2.41.5 # via pydantic pydantic-settings==2.11.0 # via mcp @@ -153,13 +153,13 @@ ruamel-yaml-clib==0.2.14 # via # ruamel-yaml # semgrep -semgrep==1.141.1 +semgrep==1.142.0 # via -r requirements/edx/semgrep.in sniffio==1.3.1 # via anyio -sse-starlette==3.0.2 +sse-starlette==3.0.3 # via mcp -starlette==0.49.1 +starlette==0.50.0 # via mcp tomli==2.0.2 # via semgrep diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 5cfe412a7f..66856ecd12 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -103,14 +103,14 @@ bleach[css]==6.3.0 # xblock-poll boto==2.49.0 # via -r requirements/edx/base.txt -boto3==1.40.62 +boto3==1.40.66 # via # -r requirements/edx/base.txt # django-ses # fs-s3fs # ora2 # snowflake-connector-python -botocore==1.40.62 +botocore==1.40.66 # via # -r requirements/edx/base.txt # boto3 @@ -259,8 +259,9 @@ dill==0.4.0 # via pylint distlib==0.4.0 # via virtualenv -django==5.2.7 +django==5.2.8 # via + # -c requirements/common_constraints.txt # -c requirements/constraints.txt # -r requirements/edx/base.txt # casbin-django-orm-adapter @@ -360,7 +361,7 @@ django-config-models==2.9.0 # lti-consumer-xblock django-cors-headers==4.9.0 # via -r requirements/edx/base.txt -django-countries==7.6.1 +django-countries==8.0.0 # via # -r requirements/edx/base.txt # edx-enterprise @@ -478,7 +479,7 @@ django-waffle==5.0.0 # edx-enterprise # edx-proctoring # edx-toggles -django-webpack-loader==3.2.1 +django-webpack-loader==3.2.2 # via # -r requirements/edx/base.txt # edx-proctoring @@ -517,7 +518,7 @@ drf-jwt==1.19.2 # via # -r requirements/edx/base.txt # edx-drf-extensions -drf-spectacular==0.28.0 +drf-spectacular==0.29.0 # via -r requirements/edx/base.txt drf-yasg==1.21.11 # via @@ -705,7 +706,7 @@ factory-boy==3.3.3 # via -r requirements/edx/testing.in faker==37.12.0 # via factory-boy -fastapi==0.120.2 +fastapi==0.121.0 # via pact-python fastavro==1.12.1 # via @@ -749,7 +750,7 @@ google-api-core[grpc]==2.28.1 # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-auth==2.42.0 +google-auth==2.42.1 # via # -r requirements/edx/base.txt # google-api-core @@ -765,7 +766,7 @@ google-cloud-firestore==2.21.0 # via # -r requirements/edx/base.txt # firebase-admin -google-cloud-storage==3.4.1 +google-cloud-storage==3.5.0 # via # -r requirements/edx/base.txt # firebase-admin @@ -829,7 +830,7 @@ hyperframe==6.1.0 # via # -r requirements/edx/base.txt # h2 -icalendar==6.3.1 +icalendar==6.3.2 # via -r requirements/edx/base.txt idna==3.11 # via @@ -955,7 +956,7 @@ mako==1.3.10 # lti-consumer-xblock # xblock # xblock-utils -markdown==3.9 +markdown==3.10 # via # -r requirements/edx/base.txt # openedx-django-wiki @@ -1009,7 +1010,7 @@ mysqlclient==2.2.7 # via # -r requirements/edx/base.txt # openedx-forum -nh3==0.3.1 +nh3==0.3.2 # via # -r requirements/edx/base.txt # xblocks-contrib @@ -1048,7 +1049,7 @@ openedx-atlas==0.7.0 # enterprise-integrated-channels # openedx-authz # openedx-forum -openedx-authz==0.11.2 +openedx-authz==0.13.0 # via -r requirements/edx/base.txt openedx-calc==4.0.2 # via -r requirements/edx/base.txt @@ -1078,7 +1079,7 @@ openedx-filters==2.1.0 # ora2 openedx-forum==0.3.8 # via -r requirements/edx/base.txt -openedx-learning==0.29.1 +openedx-learning==0.30.0 # via # -c requirements/constraints.txt # -r requirements/edx/base.txt @@ -1169,7 +1170,7 @@ protobuf==6.33.0 # googleapis-common-protos # grpcio-status # proto-plus -psutil==7.1.2 +psutil==7.1.3 # via # -r requirements/edx/base.txt # edx-django-utils @@ -1207,12 +1208,12 @@ pycryptodomex==3.23.0 # -r requirements/edx/base.txt # edx-proctoring # lti-consumer-xblock -pydantic==2.12.3 +pydantic==2.12.4 # via # -r requirements/edx/base.txt # camel-converter # fastapi -pydantic-core==2.41.4 +pydantic-core==2.41.5 # via # -r requirements/edx/base.txt # pydantic @@ -1393,7 +1394,7 @@ referencing==0.37.0 # -r requirements/edx/base.txt # jsonschema # jsonschema-specifications -regex==2025.10.23 +regex==2025.11.3 # via # -r requirements/edx/base.txt # nltk @@ -1536,7 +1537,7 @@ sqlparse==0.5.3 # django staff-graded-xblock==3.1.0 # via -r requirements/edx/base.txt -starlette==0.49.1 +starlette==0.49.3 # via fastapi stevedore==5.5.0 # via diff --git a/scripts/user_retirement/requirements/base.txt b/scripts/user_retirement/requirements/base.txt index a14836ff5e..ef96d8bbf0 100644 --- a/scripts/user_retirement/requirements/base.txt +++ b/scripts/user_retirement/requirements/base.txt @@ -10,9 +10,9 @@ attrs==25.4.0 # via zeep backoff==2.2.1 # via -r scripts/user_retirement/requirements/base.in -boto3==1.40.62 +boto3==1.40.66 # via -r scripts/user_retirement/requirements/base.in -botocore==1.40.62 +botocore==1.40.66 # via # boto3 # s3transfer @@ -34,8 +34,9 @@ cryptography==45.0.7 # via # -c requirements/constraints.txt # pyjwt -django==5.2.7 +django==5.2.8 # via + # -c requirements/common_constraints.txt # -c requirements/constraints.txt # django-crum # django-waffle @@ -50,14 +51,14 @@ edx-rest-api-client==6.2.0 # via -r scripts/user_retirement/requirements/base.in google-api-core==2.28.1 # via google-api-python-client -google-api-python-client==2.185.0 +google-api-python-client==2.186.0 # via -r scripts/user_retirement/requirements/base.in -google-auth==2.42.0 +google-auth==2.42.1 # via # google-api-core # google-api-python-client # google-auth-httplib2 -google-auth-httplib2==0.2.0 +google-auth-httplib2==0.2.1 # via google-api-python-client googleapis-common-protos==1.71.0 # via google-api-core @@ -69,7 +70,7 @@ idna==3.11 # via requests isodate==0.7.2 # via zeep -jenkinsapi==0.3.16 +jenkinsapi==0.3.17 # via -r scripts/user_retirement/requirements/base.in jmespath==1.0.1 # via @@ -90,7 +91,7 @@ protobuf==6.33.0 # google-api-core # googleapis-common-protos # proto-plus -psutil==7.1.2 +psutil==7.1.3 # via edx-django-utils pyasn1==0.6.1 # via diff --git a/scripts/user_retirement/requirements/testing.txt b/scripts/user_retirement/requirements/testing.txt index 3299e4f8fd..f7559dc971 100644 --- a/scripts/user_retirement/requirements/testing.txt +++ b/scripts/user_retirement/requirements/testing.txt @@ -14,11 +14,11 @@ attrs==25.4.0 # zeep backoff==2.2.1 # via -r scripts/user_retirement/requirements/base.txt -boto3==1.40.62 +boto3==1.40.66 # via # -r scripts/user_retirement/requirements/base.txt # moto -botocore==1.40.62 +botocore==1.40.66 # via # -r scripts/user_retirement/requirements/base.txt # boto3 @@ -52,7 +52,7 @@ cryptography==45.0.7 # pyjwt ddt==1.7.2 # via -r scripts/user_retirement/requirements/testing.in -django==5.2.7 +django==5.2.8 # via # -r scripts/user_retirement/requirements/base.txt # django-crum @@ -76,15 +76,15 @@ google-api-core==2.28.1 # via # -r scripts/user_retirement/requirements/base.txt # google-api-python-client -google-api-python-client==2.185.0 +google-api-python-client==2.186.0 # via -r scripts/user_retirement/requirements/base.txt -google-auth==2.42.0 +google-auth==2.42.1 # via # -r scripts/user_retirement/requirements/base.txt # google-api-core # google-api-python-client # google-auth-httplib2 -google-auth-httplib2==0.2.0 +google-auth-httplib2==0.2.1 # via # -r scripts/user_retirement/requirements/base.txt # google-api-python-client @@ -107,7 +107,7 @@ isodate==0.7.2 # via # -r scripts/user_retirement/requirements/base.txt # zeep -jenkinsapi==0.3.16 +jenkinsapi==0.3.17 # via -r scripts/user_retirement/requirements/base.txt jinja2==3.1.6 # via moto @@ -130,7 +130,7 @@ more-itertools==10.8.0 # via # -r scripts/user_retirement/requirements/base.txt # simple-salesforce -moto==5.1.15 +moto==5.1.16 # via -r scripts/user_retirement/requirements/testing.in packaging==25.0 # via pytest @@ -150,7 +150,7 @@ protobuf==6.33.0 # google-api-core # googleapis-common-protos # proto-plus -psutil==7.1.2 +psutil==7.1.3 # via # -r scripts/user_retirement/requirements/base.txt # edx-django-utils