diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 704742d1e0..d4df216f8f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -16,15 +16,25 @@ Change Log Unreleased ---------- -[4.10.13] +[4.11.4] --------- +* feat: update blackboard client to store API calls in DB -feat: update blackboard client to store API calls in DB +[4.11.3] +--------- +* feat: update cornerstone client to store API calls in DB + +[4.11.2] +--------- +* feat: added caching for fetching degreed course id -[4.10.12] +[4.11.1] --------- +* Added management command to fix `LearnerDataTransmissionAudit` table records. -feat: update cornerstone client to store API calls in DB +[4.11.0] +--------- +* Added the ability for enterprise customers to enable/disable academies. [4.10.11] --------- diff --git a/enterprise/__init__.py b/enterprise/__init__.py index d907380c2c..8e72b8f9c9 100644 --- a/enterprise/__init__.py +++ b/enterprise/__init__.py @@ -2,4 +2,4 @@ Your project description goes here. """ -__version__ = "4.10.13" +__version__ = "4.11.4" diff --git a/enterprise/admin/__init__.py b/enterprise/admin/__init__.py index df241caaf4..2d88a33dd1 100644 --- a/enterprise/admin/__init__.py +++ b/enterprise/admin/__init__.py @@ -214,7 +214,7 @@ class EnterpriseCustomerAdmin(DjangoObjectActions, SimpleHistoryAdmin): 'enable_executive_education_2U_fulfillment', 'enable_career_engagement_network_on_learner_portal', 'career_engagement_network_message', 'enable_pathways', 'enable_programs', - 'enable_demo_data_for_analytics_and_lpr'), + 'enable_demo_data_for_analytics_and_lpr', 'enable_academies'), 'description': ('The following default settings should be the same for ' 'the majority of enterprise customers, ' 'and are either rarely used, unlikely to be sold, ' diff --git a/enterprise/api/v1/serializers.py b/enterprise/api/v1/serializers.py index d991cc445b..0c171d32a3 100644 --- a/enterprise/api/v1/serializers.py +++ b/enterprise/api/v1/serializers.py @@ -222,7 +222,7 @@ class Meta: 'enterprise_customer_catalogs', 'reply_to', 'enterprise_notification_banner', 'hide_labor_market_data', 'modified', 'enable_universal_link', 'enable_browse_and_request', 'admin_users', 'enable_career_engagement_network_on_learner_portal', 'career_engagement_network_message', - 'enable_pathways', 'enable_programs', 'enable_demo_data_for_analytics_and_lpr', + 'enable_pathways', 'enable_programs', 'enable_demo_data_for_analytics_and_lpr', 'enable_academies', ) identity_providers = EnterpriseCustomerIdentityProviderSerializer(many=True, read_only=True) diff --git a/enterprise/migrations/0199_auto_20240130_0628.py b/enterprise/migrations/0199_auto_20240130_0628.py new file mode 100644 index 0000000000..7247fbdda3 --- /dev/null +++ b/enterprise/migrations/0199_auto_20240130_0628.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.23 on 2024-01-30 06:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('enterprise', '0198_alter_enterprisecourseenrollment_options'), + ] + + operations = [ + migrations.AddField( + model_name='enterprisecustomer', + name='enable_academies', + field=models.BooleanField(default=False, help_text='If checked, the learners will be able to see the academies on the learner portal dashboard.', verbose_name='Display academies screen'), + ), + migrations.AddField( + model_name='historicalenterprisecustomer', + name='enable_academies', + field=models.BooleanField(default=False, help_text='If checked, the learners will be able to see the academies on the learner portal dashboard.', verbose_name='Display academies screen'), + ), + ] diff --git a/enterprise/models.py b/enterprise/models.py index 6c2bfec1ca..543283976d 100644 --- a/enterprise/models.py +++ b/enterprise/models.py @@ -396,6 +396,14 @@ class Meta: ) ) + enable_academies = models.BooleanField( + verbose_name="Display academies screen", + default=False, + help_text=_( + "If checked, the learners will be able to see the academies on the learner portal dashboard." + ) + ) + enable_analytics_screen = models.BooleanField( verbose_name="Display analytics page", default=True, diff --git a/integrated_channels/blackboard/client.py b/integrated_channels/blackboard/client.py index 743a6f6202..40a1cf760c 100644 --- a/integrated_channels/blackboard/client.py +++ b/integrated_channels/blackboard/client.py @@ -17,10 +17,7 @@ from integrated_channels.blackboard.exporters.content_metadata import BLACKBOARD_COURSE_CONTENT_NAME from integrated_channels.exceptions import ClientError from integrated_channels.integrated_channel.client import IntegratedChannelApiClient -from integrated_channels.utils import ( - generate_formatted_log, - refresh_session_if_expired, -) +from integrated_channels.utils import generate_formatted_log, refresh_session_if_expired LOGGER = logging.getLogger(__name__) @@ -58,9 +55,6 @@ def __init__(self, enterprise_configuration): 'blackboard', 'BlackboardGlobalConfiguration' ) - self.IntegratedChannelAPIRequestLogs = apps.get_model( - "integrated_channel", "IntegratedChannelAPIRequestLogs" - ) self.global_blackboard_config = BlackboardGlobalConfiguration.current() self.config = apps.get_app_config('blackboard') self.session = None @@ -604,6 +598,10 @@ def generate_course_content_delete_url(self, course_id, content_id): def stringify_and_store_api_record( self, url, data, time_taken, status_code, response_body ): + """ + Helper method to stringify `data` arg and create new record in + `IntegratedChannelAPIRequestLogs` model + """ if data is not None: # Convert data to string if it's not already a string if not isinstance(data, str): @@ -614,11 +612,23 @@ def stringify_and_store_api_record( else: # If it's another type, simply convert to string data = str(data) - except Exception as e: + except Exception as e: # pylint: disable=broad-except + LOGGER.error( + generate_formatted_log( + self.enterprise_configuration.channel_code(), + self.enterprise_configuration.enterprise_customer.uuid, + None, + None, + f"stringify_and_store_api_record: Unable to stringify data: {e}", + ) + ) pass # Store stringified data in the database try: - self.IntegratedChannelAPIRequestLogs.store_api_call( + IntegratedChannelAPIRequestLogs = apps.get_model( + "integrated_channel", "IntegratedChannelAPIRequestLogs" + ) + IntegratedChannelAPIRequestLogs.store_api_call( enterprise_customer=self.enterprise_configuration.enterprise_customer, enterprise_customer_configuration_id=self.enterprise_configuration.id, endpoint=url, @@ -627,8 +637,16 @@ def stringify_and_store_api_record( status_code=status_code, response_body=response_body, ) - except Exception as e: - print(f"Failed to store data in the database: {e}") + except Exception as e: # pylint: disable=broad-except + LOGGER.error( + generate_formatted_log( + self.enterprise_configuration.channel_code(), + self.enterprise_configuration.enterprise_customer.uuid, + None, + None, + f"stringify_and_store_api_record: Failed to store data in the database: {e}", + ) + ) def _get(self, url, data=None): """ diff --git a/integrated_channels/cornerstone/client.py b/integrated_channels/cornerstone/client.py index 40e33bd863..6f4a74244e 100644 --- a/integrated_channels/cornerstone/client.py +++ b/integrated_channels/cornerstone/client.py @@ -13,7 +13,7 @@ from integrated_channels.cornerstone.utils import get_or_create_key_pair from integrated_channels.integrated_channel.client import IntegratedChannelApiClient -from integrated_channels.utils import generate_formatted_log, store_api_call +from integrated_channels.utils import generate_formatted_log LOGGER = logging.getLogger(__name__) @@ -88,6 +88,9 @@ def create_course_completion(self, user_id, payload): Raises: HTTPError: if we received a failure response code from Cornerstone """ + IntegratedChannelAPIRequestLogs = apps.get_model( + "integrated_channel", "IntegratedChannelAPIRequestLogs" + ) json_payload = json.loads(payload) callback_url = json_payload['data'].pop('callbackUrl') session_token = self.enterprise_configuration.session_token @@ -115,7 +118,7 @@ def create_course_completion(self, user_id, payload): } ) duration_seconds = time.time() - start_time - store_api_call( + IntegratedChannelAPIRequestLogs.store_api_call( enterprise_customer=self.enterprise_configuration.enterprise_customer, enterprise_customer_configuration_id=self.enterprise_configuration.id, endpoint=url, diff --git a/integrated_channels/cornerstone/views.py b/integrated_channels/cornerstone/views.py index 363e2ab2a4..47308b86ff 100644 --- a/integrated_channels/cornerstone/views.py +++ b/integrated_channels/cornerstone/views.py @@ -13,13 +13,13 @@ from rest_framework.authentication import SessionAuthentication from rest_framework.response import Response +from django.apps import apps from django.utils.http import parse_http_date_safe from enterprise.api.throttles import ServiceUserThrottle from enterprise.utils import get_enterprise_customer, get_enterprise_worker_user, get_oauth2authentication_class from integrated_channels.cornerstone.models import CornerstoneEnterpriseCustomerConfiguration from integrated_channels.integrated_channel.constants import ISO_8601_DATE_FORMAT -from integrated_channels.utils import store_api_call logger = getLogger(__name__) @@ -103,6 +103,9 @@ class CornerstoneCoursesListView(BaseViewSet): def get(self, request, *args, **kwargs): start_time = time.time() enterprise_customer_uuid = request.GET.get('ciid') + IntegratedChannelAPIRequestLogs = apps.get_model( + "integrated_channel", "IntegratedChannelAPIRequestLogs" + ) if not enterprise_customer_uuid: return Response( status=status.HTTP_400_BAD_REQUEST, @@ -163,7 +166,7 @@ def get(self, request, *args, **kwargs): duration_seconds = time.time() - start_time headers_dict = dict(request.headers) headers_json = json.dumps(headers_dict) - store_api_call( + IntegratedChannelAPIRequestLogs.store_api_call( enterprise_customer=enterprise_customer, enterprise_customer_configuration_id=enterprise_config.id, endpoint=request.get_full_path(), diff --git a/integrated_channels/degreed2/client.py b/integrated_channels/degreed2/client.py index bee591fed7..1424d692ef 100644 --- a/integrated_channels/degreed2/client.py +++ b/integrated_channels/degreed2/client.py @@ -9,6 +9,7 @@ from http import HTTPStatus import requests +from edx_django_utils.cache import TieredCache, get_cache_key from six.moves.urllib.parse import urljoin from django.apps import apps @@ -182,9 +183,17 @@ def delete_course_completion(self, user_id, payload): def fetch_degreed_course_id(self, external_id): """ - Fetch the 'id' of a course from Degreed2, given the external-id as a search param - 'external-id' is the edX course key + Fetch the 'id' of a course from cache first and if not found then send a request to Degreed2, + given the external-id as a search param 'external-id' is the edX course key. """ + cache_key = get_cache_key( + resource='degreed2_course_id', + resource_id=external_id, + ) + cached_course_id = TieredCache.get_cached_response(cache_key) + if cached_course_id.is_found: + LOGGER.info(self.make_log_msg(external_id, f'Found cached course id: {cached_course_id.value}')) + return cached_course_id.value # QueryDict converts + to space params = QueryDict(f"filter[external_id]={external_id.replace('+','%2B')}") course_search_url = f'{self.get_courses_url()}?{params.urlencode(safe="[]")}' @@ -201,7 +210,11 @@ def fetch_degreed_course_id(self, external_id): ) response_json = json.loads(response_body) if response_json['data']: - return response_json['data'][0]['id'] + # cache the course id with a 1 day expiration + response_course_id = response_json['data'][0]['id'] + expires_in = 60 * 60 * 24 # 1 day + TieredCache.set_all_tiers(cache_key, response_course_id, expires_in) + return response_course_id raise ClientError( f'Degreed2: Attempted to find degreed course id but failed, external id was {external_id}' f', Response from Degreed was {response_body}') diff --git a/integrated_channels/integrated_channel/admin/__init__.py b/integrated_channels/integrated_channel/admin/__init__.py index 960b49c182..27dd98e384 100644 --- a/integrated_channels/integrated_channel/admin/__init__.py +++ b/integrated_channels/integrated_channel/admin/__init__.py @@ -89,13 +89,3 @@ class ApiResponseRecordAdmin(admin.ModelAdmin): ) list_per_page = 1000 - - -@admin.register(IntegratedChannelAPIRequestLogs) -class CornerstoneAPIRequestLogAdmin(admin.ModelAdmin): - """ - Django admin model for IntegratedChannelAPIRequestLogs. - """ - - class Meta: - model = IntegratedChannelAPIRequestLogs diff --git a/integrated_channels/integrated_channel/management/commands/remove_duplicate_learner_transmission_audit_records.py b/integrated_channels/integrated_channel/management/commands/remove_duplicate_learner_transmission_audit_records.py new file mode 100644 index 0000000000..b7edf86f91 --- /dev/null +++ b/integrated_channels/integrated_channel/management/commands/remove_duplicate_learner_transmission_audit_records.py @@ -0,0 +1,67 @@ +""" +Transmits consenting enterprise learner data to the integrated channels. +""" +from logging import getLogger + +from django.apps import apps +from django.contrib import auth +from django.core.management.base import BaseCommand +from django.db import transaction +from django.db.models import Max +from django.utils.translation import gettext as _ + +User = auth.get_user_model() +LOGGER = getLogger(__name__) + + +class Command(BaseCommand): + """ + Management command which removes the duplicated transmission audit records for integration channels + """ + help = _(''' + Transmit Enterprise learner course completion data for the given EnterpriseCustomer. + ''') + + def handle(self, *args, **options): + """ + Remove the duplicated transmission audit records for integration channels. + """ + # Multiple transmission records were being saved against single enterprise_course_enrollment_id in case + # transmission fails against course and course run id. Job of this management command is to keep the latest + # record for enterprise_course_enrollment_id that doesn't start with "course-v1: and delete all other records." + channel_learner_audit_models = [ + ('moodle', 'MoodleLearnerDataTransmissionAudit'), + ('blackboard', 'BlackboardLearnerDataTransmissionAudit'), + ('cornerstone', 'CornerstoneLearnerDataTransmissionAudit'), + ('canvas', 'CanvasLearnerAssessmentDataTransmissionAudit'), + ('degreed2', 'Degreed2LearnerDataTransmissionAudit'), + ('sap_success_factors', 'SapSuccessFactorsLearnerDataTransmissionAudit'), + ] + for app_label, model_name in channel_learner_audit_models: + model_class = apps.get_model(app_label=app_label, model_name=model_name) + + latest_records_without_prefix = ( + model_class.objects.exclude(course_id__startswith='course-v1:') + .values('enterprise_course_enrollment_id').annotate(most_recent_transmission_id=Max('id')) + ) + + LOGGER.info( + f'{app_label} channel has {latest_records_without_prefix.count()} records without prefix' + ) + + # Delete all duplicate records for each enterprise_course_enrollment_id + with transaction.atomic(): + for entry in latest_records_without_prefix: + enterprise_course_enrollment_id = entry['enterprise_course_enrollment_id'] + most_recent_transmission_id = entry['most_recent_transmission_id'] + + # Delete all records except the latest one without "course-v1:" + duplicate_records_to_delete = ( + model_class.objects + .filter(enterprise_course_enrollment_id=enterprise_course_enrollment_id) + .exclude(id=most_recent_transmission_id) + ) + LOGGER.info( + f'{app_label} channel - {duplicate_records_to_delete.count()} duplicate records are deleted' + ) + duplicate_records_to_delete.delete() diff --git a/integrated_channels/integrated_channel/migrations/0031_alter_integratedchannelapirequestlogs_options.py b/integrated_channels/integrated_channel/migrations/0031_alter_integratedchannelapirequestlogs_options.py index 5b11a9f695..7f04148866 100644 --- a/integrated_channels/integrated_channel/migrations/0031_alter_integratedchannelapirequestlogs_options.py +++ b/integrated_channels/integrated_channel/migrations/0031_alter_integratedchannelapirequestlogs_options.py @@ -1,6 +1,6 @@ # Generated by Django 3.2.22 on 2024-01-25 09:25 -from django.db import migrations +from django.db import migrations, models class Migration(migrations.Migration): @@ -14,4 +14,23 @@ class Migration(migrations.Migration): name='integratedchannelapirequestlogs', options={'verbose_name_plural': 'Integrated channels API request logs'}, ), + migrations.RemoveField( + model_name='integratedchannelapirequestlogs', + name='api_record', + ), + migrations.AddField( + model_name='integratedchannelapirequestlogs', + name='response_body', + field=models.TextField(blank=True, help_text='API call response body', null=True), + ), + migrations.AddField( + model_name='integratedchannelapirequestlogs', + name='status_code', + field=models.PositiveIntegerField(blank=True, help_text='API call response HTTP status code', null=True), + ), + migrations.AlterField( + model_name='integratedchannelapirequestlogs', + name='time_taken', + field=models.FloatField(), + ), ] diff --git a/integrated_channels/integrated_channel/migrations/0032_alter_integratedchannelapirequestlogs_endpoint.py b/integrated_channels/integrated_channel/migrations/0032_alter_integratedchannelapirequestlogs_endpoint.py new file mode 100644 index 0000000000..ccd5d2b95c --- /dev/null +++ b/integrated_channels/integrated_channel/migrations/0032_alter_integratedchannelapirequestlogs_endpoint.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.22 on 2024-01-29 13:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('integrated_channel', '0031_alter_integratedchannelapirequestlogs_options'), + ] + + operations = [ + migrations.AlterField( + model_name='integratedchannelapirequestlogs', + name='endpoint', + field=models.URLField(max_length=255), + ), + ] diff --git a/integrated_channels/integrated_channel/migrations/0032_auto_20240125_0936.py b/integrated_channels/integrated_channel/migrations/0032_auto_20240125_0936.py deleted file mode 100644 index 077a1af02d..0000000000 --- a/integrated_channels/integrated_channel/migrations/0032_auto_20240125_0936.py +++ /dev/null @@ -1,32 +0,0 @@ -# Generated by Django 3.2.22 on 2024-01-25 09:36 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('integrated_channel', '0031_alter_integratedchannelapirequestlogs_options'), - ] - - operations = [ - migrations.RemoveField( - model_name='integratedchannelapirequestlogs', - name='api_record', - ), - migrations.AddField( - model_name='integratedchannelapirequestlogs', - name='response_body', - field=models.TextField(blank=True, help_text='API call response body', null=True), - ), - migrations.AddField( - model_name='integratedchannelapirequestlogs', - name='status_code', - field=models.PositiveIntegerField(blank=True, help_text='API call response HTTP status code', null=True), - ), - migrations.AlterField( - model_name='integratedchannelapirequestlogs', - name='time_taken', - field=models.FloatField(), - ), - ] diff --git a/integrated_channels/integrated_channel/models.py b/integrated_channels/integrated_channel/models.py index c5700eb446..44ab495e35 100644 --- a/integrated_channels/integrated_channel/models.py +++ b/integrated_channels/integrated_channel/models.py @@ -881,7 +881,7 @@ class Meta: resolved = models.BooleanField(default=False) -class BaseIntegratedChannelAPIRequestLogs(TimeStampedModel): +class IntegratedChannelAPIRequestLogs(TimeStampedModel): """ A model to track basic information about every API call we make from the integrated channels. """ @@ -894,8 +894,9 @@ class BaseIntegratedChannelAPIRequestLogs(TimeStampedModel): null=False, help_text="ID from the EnterpriseCustomerConfiguration model", ) - endpoint = models.TextField( + endpoint = models.URLField( blank=False, + max_length=255, null=False, ) payload = models.TextField(blank=False, null=False) @@ -907,16 +908,6 @@ class BaseIntegratedChannelAPIRequestLogs(TimeStampedModel): help_text="API call response body", blank=True, null=True ) - class Meta: - app_label = "integrated_channel" - abstract = True - - -class IntegratedChannelAPIRequestLogs(BaseIntegratedChannelAPIRequestLogs): - """ - A model to track basic information about every API call we make from the integrated channels. - """ - class Meta: app_label = "integrated_channel" verbose_name_plural = "Integrated channels API request logs" @@ -940,3 +931,40 @@ def __repr__(self): Return uniquely identifying string representation. """ return self.__str__() + + @classmethod + def store_api_call( + cls, + enterprise_customer, + enterprise_customer_configuration_id, + endpoint, + payload, + time_taken, + status_code, + response_body, + ): + """ + Creates new record in IntegratedChannelAPIRequestLogs table. + """ + try: + record = cls( + enterprise_customer=enterprise_customer, + enterprise_customer_configuration_id=enterprise_customer_configuration_id, + endpoint=endpoint, + payload=payload, + time_taken=time_taken, + status_code=status_code, + response_body=response_body, + ) + record.save() + except Exception as e: # pylint: disable=broad-except + LOGGER.error( + f"store_api_call raised error while storing API call: {e}" + f"enterprise_customer={enterprise_customer}" + f"enterprise_customer_configuration_id={enterprise_customer_configuration_id}," + f"endpoint={endpoint}" + f"payload={payload}" + f"time_taken={time_taken}" + f"status_code={status_code}" + f"response_body={response_body}" + ) diff --git a/integrated_channels/utils.py b/integrated_channels/utils.py index bf728c94a9..62ba54fa71 100644 --- a/integrated_channels/utils.py +++ b/integrated_channels/utils.py @@ -477,13 +477,6 @@ def get_enterprise_customer_model(): return apps.get_model('enterprise', 'EnterpriseCustomer') -def integrated_channel_request_log_model(): - """ - Returns the ``IntegratedChannelAPIRequestLogs`` class. - """ - return apps.get_model("integrated_channel", "IntegratedChannelAPIRequestLogs") - - def get_enterprise_customer_from_enterprise_enrollment(enrollment_id): """ Returns the Django ORM enterprise customer object that is associated with an enterprise enrollment ID @@ -508,38 +501,3 @@ def get_enterprise_client_by_channel_code(channel_code): 'canvas': CanvasAPIClient, } return _enterprise_client_model_by_channel_code[channel_code] - - -def store_api_call( - enterprise_customer, - enterprise_customer_configuration_id, - endpoint, - payload, - time_taken, - status_code, - response_body, -): - """ - Creates new record in CornerstoneAPIRequestLogs table. - """ - try: - integrated_channel_request_log_model().objects.create( - enterprise_customer=enterprise_customer, - enterprise_customer_configuration_id=enterprise_customer_configuration_id, - endpoint=endpoint, - payload=payload, - time_taken=time_taken, - status_code=status_code, - response_body=response_body, - ) - except Exception as e: # pylint: disable=broad-except - LOGGER.error( - f"store_api_call raised error while storing API call: {e}" - f"enterprise_customer={enterprise_customer}" - f"enterprise_customer_configuration_id={enterprise_customer_configuration_id}," - f"endpoint={endpoint}" - f"payload={payload}" - f"time_taken={time_taken}" - f"status_code={status_code}" - f"response_body={response_body}" - ) diff --git a/requirements/celery53.txt b/requirements/celery53.txt index f5e6e328aa..71b29858a8 100644 --- a/requirements/celery53.txt +++ b/requirements/celery53.txt @@ -1,9 +1,9 @@ amqp==5.2.0 billiard==4.2.0 -celery==5.3.4 +celery==5.3.6 click==8.1.7 click-didyoumean==0.3.0 click-repl==0.3.0 -kombu==5.3.3 -prompt-toolkit==3.0.39 +kombu==5.3.5 +prompt-toolkit==3.0.43 vine==5.1.0 diff --git a/requirements/ci.txt b/requirements/ci.txt index a055e8ef41..a7bca04d76 100644 --- a/requirements/ci.txt +++ b/requirements/ci.txt @@ -4,7 +4,7 @@ # # make upgrade # -distlib==0.3.7 +distlib==0.3.8 # via virtualenv filelock==3.13.1 # via @@ -12,7 +12,7 @@ filelock==3.13.1 # virtualenv packaging==23.2 # via tox -platformdirs==3.11.0 +platformdirs==4.1.0 # via virtualenv pluggy==1.3.0 # via tox @@ -24,8 +24,7 @@ tomli==2.0.1 # via tox tox==3.28.0 # via - # -c requirements/common_constraints.txt # -c requirements/constraints.txt # -r requirements/ci.in -virtualenv==20.24.6 +virtualenv==20.25.0 # via tox diff --git a/requirements/common_constraints.txt b/requirements/common_constraints.txt index 08e94f34dd..be61b7e0ed 100644 --- a/requirements/common_constraints.txt +++ b/requirements/common_constraints.txt @@ -21,7 +21,3 @@ Django<4.0 elasticsearch<7.14.0 # django-simple-history>3.0.0 adds indexing and causes a lot of migrations to be affected - -# tox>4.0.0 isn't yet compatible with many tox plugins, causing CI failures in almost all repos. -# Details can be found in this discussion: https://github.com/tox-dev/tox/discussions/1810 -tox<4.0.0 diff --git a/requirements/dev.txt b/requirements/dev.txt index fbe87b0ec8..30852d5719 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -8,7 +8,7 @@ accessible-pygments==0.0.4 # via # -r requirements/doc.txt # pydata-sphinx-theme -aiohttp==3.8.6 +aiohttp==3.9.1 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -48,9 +48,8 @@ asn1crypto==1.5.1 # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt - # oscrypto # snowflake-connector-python -astroid==3.0.1 +astroid==3.0.2 # via # pylint # pylint-celery @@ -67,7 +66,7 @@ attrs==23.1.0 # -r requirements/test.txt # aiohttp # pytest -babel==2.13.1 +babel==2.14.0 # via # -r requirements/doc.txt # pydata-sphinx-theme @@ -77,9 +76,10 @@ backports-zoneinfo[tzdata]==0.2.1 # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt + # backports-zoneinfo # celery # kombu -beautifulsoup4==4.12.2 +beautifulsoup4==4.12.3 # via # -r requirements/doc.txt # pydata-sphinx-theme @@ -96,13 +96,13 @@ bleach==6.1.0 # -r requirements/test.txt build==1.0.3 # via pip-tools -celery==5.3.4 +celery==5.3.6 # via # -c requirements/constraints.txt # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt -certifi==2023.7.22 +certifi==2023.11.17 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -126,7 +126,6 @@ charset-normalizer==2.0.12 # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt - # aiohttp # requests # snowflake-connector-python click==8.1.7 @@ -183,9 +182,10 @@ coreschema==0.0.4 # -r requirements/test.txt # coreapi # drf-yasg -coverage[toml]==7.3.2 +coverage[toml]==7.4.0 # via # -r requirements/test.txt + # coverage # pytest-cov cryptography==38.0.4 # via @@ -212,13 +212,13 @@ deprecated==1.2.14 # -r requirements/test-master.txt # -r requirements/test.txt # jwcrypto -diff-cover==8.0.0 +diff-cover==8.0.3 # via -r requirements/test.txt dill==0.3.7 # via pylint -distlib==0.3.7 +distlib==0.3.8 # via virtualenv -django==3.2.22 +django==3.2.23 # via # -c requirements/common_constraints.txt # -r requirements/doc.txt @@ -270,12 +270,12 @@ django-fernet-fields-v2==0.9 # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt -django-filter==23.3 +django-filter==23.5 # via # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt -django-ipware==5.0.1 +django-ipware==6.0.2 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -307,7 +307,7 @@ django-simple-history==3.1.1 # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt -django-waffle==4.0.0 +django-waffle==4.1.0 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -362,7 +362,7 @@ edx-braze-client==0.1.8 # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt -edx-django-utils==5.7.0 +edx-django-utils==5.9.0 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -371,7 +371,7 @@ edx-django-utils==5.7.0 # edx-drf-extensions # edx-rest-api-client # edx-toggles -edx-drf-extensions==8.12.0 +edx-drf-extensions==9.1.2 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -387,12 +387,13 @@ edx-opaque-keys[django]==2.5.1 # -r requirements/test-master.txt # -r requirements/test.txt # edx-drf-extensions + # edx-opaque-keys edx-rbac==1.8.0 # via # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt -edx-rest-api-client==5.6.0 +edx-rest-api-client==5.6.1 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -412,12 +413,12 @@ factory-boy==3.3.0 # -c requirements/constraints.txt # -r requirements/doc.txt # -r requirements/test.txt -faker==19.13.0 +faker==22.5.0 # via # -r requirements/doc.txt # -r requirements/test.txt # factory-boy -filelock==3.12.4 +filelock==3.13.1 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -436,7 +437,7 @@ frozenlist==1.4.0 # -r requirements/test.txt # aiohttp # aiosignal -idna==3.4 +idna==3.6 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -448,7 +449,7 @@ imagesize==1.4.1 # via # -r requirements/doc.txt # sphinx -importlib-metadata==6.8.0 +importlib-metadata==7.0.1 # via # -r requirements/doc.txt # build @@ -464,7 +465,7 @@ iniconfig==2.0.0 # -r requirements/doc.txt # -r requirements/test.txt # pytest -isort==5.12.0 +isort==5.13.2 # via # -r requirements/dev.in # pylint @@ -499,13 +500,13 @@ jwcrypto==1.5.0 # -r requirements/test-master.txt # -r requirements/test.txt # django-oauth-toolkit -kombu==5.3.3 +kombu==5.3.5 # via # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt # celery -lxml==4.9.3 +lxml==5.1.0 # via edx-i18n-tools markupsafe==2.1.3 # via @@ -526,13 +527,13 @@ multidict==6.0.4 # -r requirements/test.txt # aiohttp # yarl -newrelic==9.1.0 +newrelic==9.3.0 # via # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt # edx-django-utils -nh3==0.2.14 +nh3==0.2.15 # via # -r requirements/doc.txt # readme-renderer @@ -547,12 +548,6 @@ openai==0.28.1 # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt -oscrypto==1.3.0 - # via - # -r requirements/doc.txt - # -r requirements/test-master.txt - # -r requirements/test.txt - # snowflake-connector-python packaging==23.2 # via # -r requirements/doc.txt @@ -565,7 +560,7 @@ packaging==23.2 # snowflake-connector-python # sphinx # tox -path==16.7.1 +path==16.9.0 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -577,7 +572,7 @@ path-py==12.5.0 # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt -pbr==5.11.1 +pbr==6.0.0 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -588,7 +583,7 @@ pgpy==0.6.0 # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt -pillow==9.5.0 +pillow==10.1.0 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -614,13 +609,13 @@ pluggy==1.3.0 # tox polib==1.2.0 # via edx-i18n-tools -prompt-toolkit==3.0.39 +prompt-toolkit==3.0.43 # via # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt # click-repl -psutil==5.9.5 +psutil==5.9.6 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -632,7 +627,7 @@ py==1.11.0 # -r requirements/test.txt # pytest # tox -pyasn1==0.5.0 +pyasn1==0.5.1 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -646,19 +641,13 @@ pycparser==2.21 # -r requirements/test-master.txt # -r requirements/test.txt # cffi -pycryptodomex==3.19.0 - # via - # -r requirements/doc.txt - # -r requirements/test-master.txt - # -r requirements/test.txt - # snowflake-connector-python -pydata-sphinx-theme==0.14.3 +pydata-sphinx-theme==0.14.4 # via # -r requirements/doc.txt # sphinx-book-theme pydocstyle==6.3.0 # via -r requirements/dev.in -pygments==2.16.1 +pygments==2.17.2 # via # -r requirements/doc.txt # -r requirements/test.txt @@ -676,8 +665,9 @@ pyjwt[crypto]==2.8.0 # drf-jwt # edx-drf-extensions # edx-rest-api-client + # pyjwt # snowflake-connector-python -pylint==3.0.2 +pylint==3.0.3 # via # edx-lint # pylint-celery @@ -730,13 +720,19 @@ python-dateutil==2.8.2 # celery # faker # freezegun +python-ipware==2.0.0 + # via + # -r requirements/doc.txt + # -r requirements/test-master.txt + # -r requirements/test.txt + # django-ipware python-slugify==8.0.1 # via # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt # code-annotations -pytz==2022.7.1 +pytz==2023.3.post1 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -782,7 +778,7 @@ restructuredtext-lint==1.4.0 # via # -r requirements/doc.txt # doc8 -ruamel-yaml==0.17.35 +ruamel-yaml==0.18.5 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -829,7 +825,7 @@ snowballstemmer==2.2.0 # -r requirements/doc.txt # pydocstyle # sphinx -snowflake-connector-python==3.2.1 +snowflake-connector-python==3.6.0 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -890,7 +886,7 @@ stevedore==5.1.0 # doc8 # edx-django-utils # edx-opaque-keys -testfixtures==7.2.0 +testfixtures==7.2.2 # via # -r requirements/dev.in # -r requirements/doc.txt @@ -918,7 +914,7 @@ tomli==2.0.1 # pylint # pyproject-hooks # tox -tomlkit==0.12.1 +tomlkit==0.12.3 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -927,7 +923,6 @@ tomlkit==0.12.1 # snowflake-connector-python tox==3.28.0 # via - # -c requirements/common_constraints.txt # -c requirements/constraints.txt # -r requirements/dev.in tqdm==4.66.1 @@ -939,7 +934,7 @@ tqdm==4.66.1 # twine twine==1.11.0 # via -r requirements/dev.in -typing-extensions==4.8.0 +typing-extensions==4.9.0 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -972,7 +967,7 @@ uritemplate==4.1.1 # -r requirements/test.txt # coreapi # drf-yasg -urllib3==1.26.17 +urllib3==1.26.18 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -987,9 +982,9 @@ vine==5.1.0 # amqp # celery # kombu -virtualenv==20.24.6 +virtualenv==20.25.0 # via tox -wcwidth==0.2.8 +wcwidth==0.2.12 # via # -r requirements/doc.txt # -r requirements/test-master.txt @@ -1001,17 +996,17 @@ webencodings==0.5.1 # -r requirements/test-master.txt # -r requirements/test.txt # bleach -wheel==0.41.3 +wheel==0.42.0 # via # -r requirements/dev.in # pip-tools -wrapt==1.15.0 +wrapt==1.16.0 # via # -r requirements/doc.txt # -r requirements/test-master.txt # -r requirements/test.txt # deprecated -yarl==1.9.2 +yarl==1.9.4 # via # -r requirements/doc.txt # -r requirements/test-master.txt diff --git a/requirements/django.txt b/requirements/django.txt index 5a28da341d..d296127a53 100644 --- a/requirements/django.txt +++ b/requirements/django.txt @@ -1 +1 @@ -django==3.2.22 +django==3.2.23 diff --git a/requirements/doc.txt b/requirements/doc.txt index 62eae90148..fce593f30e 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -6,7 +6,7 @@ # accessible-pygments==0.0.4 # via pydata-sphinx-theme -aiohttp==3.8.6 +aiohttp==3.9.1 # via # -r requirements/test-master.txt # openai @@ -32,7 +32,6 @@ asgiref==3.7.2 asn1crypto==1.5.1 # via # -r requirements/test-master.txt - # oscrypto # snowflake-connector-python async-timeout==4.0.3 # via @@ -43,16 +42,17 @@ attrs==23.1.0 # -r requirements/test-master.txt # aiohttp # pytest -babel==2.13.1 +babel==2.14.0 # via # pydata-sphinx-theme # sphinx backports-zoneinfo[tzdata]==0.2.1 # via # -r requirements/test-master.txt + # backports-zoneinfo # celery # kombu -beautifulsoup4==4.12.2 +beautifulsoup4==4.12.3 # via pydata-sphinx-theme billiard==4.2.0 # via @@ -60,11 +60,11 @@ billiard==4.2.0 # celery bleach==6.1.0 # via -r requirements/test-master.txt -celery==5.3.4 +celery==5.3.6 # via # -c requirements/constraints.txt # -r requirements/test-master.txt -certifi==2023.7.22 +certifi==2023.11.17 # via # -r requirements/test-master.txt # requests @@ -78,7 +78,6 @@ cffi==1.16.0 charset-normalizer==2.0.12 # via # -r requirements/test-master.txt - # aiohttp # requests # snowflake-connector-python click==8.1.7 @@ -132,7 +131,7 @@ deprecated==1.2.14 # via # -r requirements/test-master.txt # jwcrypto -django==3.2.22 +django==3.2.23 # via # -c requirements/common_constraints.txt # -r requirements/test-master.txt @@ -167,9 +166,9 @@ django-crum==0.7.9 # edx-toggles django-fernet-fields-v2==0.9 # via -r requirements/test-master.txt -django-filter==23.3 +django-filter==23.5 # via -r requirements/test-master.txt -django-ipware==5.0.1 +django-ipware==6.0.2 # via -r requirements/test-master.txt django-model-utils==4.3.1 # via @@ -185,7 +184,7 @@ django-simple-history==3.1.1 # via # -c requirements/constraints.txt # -r requirements/test-master.txt -django-waffle==4.0.0 +django-waffle==4.1.0 # via # -r requirements/test-master.txt # edx-django-utils @@ -223,14 +222,14 @@ edx-api-doc-tools==1.7.0 # via -r requirements/test-master.txt edx-braze-client==0.1.8 # via -r requirements/test-master.txt -edx-django-utils==5.7.0 +edx-django-utils==5.9.0 # via # -r requirements/test-master.txt # django-config-models # edx-drf-extensions # edx-rest-api-client # edx-toggles -edx-drf-extensions==8.12.0 +edx-drf-extensions==9.1.2 # via # -r requirements/test-master.txt # edx-rbac @@ -238,9 +237,10 @@ edx-opaque-keys[django]==2.5.1 # via # -r requirements/test-master.txt # edx-drf-extensions + # edx-opaque-keys edx-rbac==1.8.0 # via -r requirements/test-master.txt -edx-rest-api-client==5.6.0 +edx-rest-api-client==5.6.1 # via -r requirements/test-master.txt edx-tincan-py35==1.0.0 # via -r requirements/test-master.txt @@ -250,9 +250,9 @@ factory-boy==3.3.0 # via # -c requirements/constraints.txt # -r requirements/doc.in -faker==19.13.0 +faker==22.5.0 # via factory-boy -filelock==3.12.4 +filelock==3.13.1 # via # -r requirements/test-master.txt # snowflake-connector-python @@ -261,7 +261,7 @@ frozenlist==1.4.0 # -r requirements/test-master.txt # aiohttp # aiosignal -idna==3.4 +idna==3.6 # via # -r requirements/test-master.txt # requests @@ -269,7 +269,7 @@ idna==3.4 # yarl imagesize==1.4.1 # via sphinx -importlib-metadata==6.8.0 +importlib-metadata==7.0.1 # via sphinx inflection==0.5.1 # via @@ -295,7 +295,7 @@ jwcrypto==1.5.0 # via # -r requirements/test-master.txt # django-oauth-toolkit -kombu==5.3.3 +kombu==5.3.5 # via # -r requirements/test-master.txt # celery @@ -308,11 +308,11 @@ multidict==6.0.4 # -r requirements/test-master.txt # aiohttp # yarl -newrelic==9.1.0 +newrelic==9.3.0 # via # -r requirements/test-master.txt # edx-django-utils -nh3==0.2.14 +nh3==0.2.15 # via readme-renderer oauthlib==3.2.2 # via @@ -320,10 +320,6 @@ oauthlib==3.2.2 # django-oauth-toolkit openai==0.28.1 # via -r requirements/test-master.txt -oscrypto==1.3.0 - # via - # -r requirements/test-master.txt - # snowflake-connector-python packaging==23.2 # via # -r requirements/test-master.txt @@ -332,19 +328,19 @@ packaging==23.2 # pytest # snowflake-connector-python # sphinx -path==16.7.1 +path==16.9.0 # via # -r requirements/test-master.txt # path-py path-py==12.5.0 # via -r requirements/test-master.txt -pbr==5.11.1 +pbr==6.0.0 # via # -r requirements/test-master.txt # stevedore pgpy==0.6.0 # via -r requirements/test-master.txt -pillow==9.5.0 +pillow==10.1.0 # via -r requirements/test-master.txt platformdirs==3.11.0 # via @@ -352,17 +348,17 @@ platformdirs==3.11.0 # snowflake-connector-python pluggy==1.3.0 # via pytest -prompt-toolkit==3.0.39 +prompt-toolkit==3.0.43 # via # -r requirements/test-master.txt # click-repl -psutil==5.9.5 +psutil==5.9.6 # via # -r requirements/test-master.txt # edx-django-utils py==1.11.0 # via pytest -pyasn1==0.5.0 +pyasn1==0.5.1 # via # -r requirements/test-master.txt # pgpy @@ -370,13 +366,9 @@ pycparser==2.21 # via # -r requirements/test-master.txt # cffi -pycryptodomex==3.19.0 - # via - # -r requirements/test-master.txt - # snowflake-connector-python -pydata-sphinx-theme==0.14.3 +pydata-sphinx-theme==0.14.4 # via sphinx-book-theme -pygments==2.16.1 +pygments==2.17.2 # via # accessible-pygments # doc8 @@ -389,6 +381,7 @@ pyjwt[crypto]==2.8.0 # drf-jwt # edx-drf-extensions # edx-rest-api-client + # pyjwt # snowflake-connector-python pymongo==3.13.0 # via @@ -411,11 +404,15 @@ python-dateutil==2.8.2 # -r requirements/test-master.txt # celery # faker +python-ipware==2.0.0 + # via + # -r requirements/test-master.txt + # django-ipware python-slugify==8.0.1 # via # -r requirements/test-master.txt # code-annotations -pytz==2022.7.1 +pytz==2023.3.post1 # via # -r requirements/test-master.txt # babel @@ -443,7 +440,7 @@ requests==2.31.0 # sphinx restructuredtext-lint==1.4.0 # via doc8 -ruamel-yaml==0.17.35 +ruamel-yaml==0.18.5 # via # -r requirements/test-master.txt # drf-yasg @@ -469,7 +466,7 @@ slumber==0.7.1 # edx-rest-api-client snowballstemmer==2.2.0 # via sphinx -snowflake-connector-python==3.2.1 +snowflake-connector-python==3.6.0 # via -r requirements/test-master.txt sortedcontainers==2.4.0 # via @@ -507,7 +504,7 @@ stevedore==5.1.0 # doc8 # edx-django-utils # edx-opaque-keys -testfixtures==7.2.0 +testfixtures==7.2.2 # via -r requirements/test-master.txt text-unidecode==1.3 # via @@ -517,7 +514,7 @@ toml==0.10.2 # via pytest tomli==2.0.1 # via doc8 -tomlkit==0.12.1 +tomlkit==0.12.3 # via # -r requirements/test-master.txt # snowflake-connector-python @@ -525,7 +522,7 @@ tqdm==4.66.1 # via # -r requirements/test-master.txt # openai -typing-extensions==4.8.0 +typing-extensions==4.9.0 # via # -r requirements/test-master.txt # asgiref @@ -547,7 +544,7 @@ uritemplate==4.1.1 # -r requirements/test-master.txt # coreapi # drf-yasg -urllib3==1.26.17 +urllib3==1.26.18 # via # -r requirements/test-master.txt # requests @@ -558,7 +555,7 @@ vine==5.1.0 # amqp # celery # kombu -wcwidth==0.2.8 +wcwidth==0.2.12 # via # -r requirements/test-master.txt # prompt-toolkit @@ -566,11 +563,11 @@ webencodings==0.5.1 # via # -r requirements/test-master.txt # bleach -wrapt==1.15.0 +wrapt==1.16.0 # via # -r requirements/test-master.txt # deprecated -yarl==1.9.2 +yarl==1.9.4 # via # -r requirements/test-master.txt # aiohttp diff --git a/requirements/edx-platform-constraints.txt b/requirements/edx-platform-constraints.txt index 4fe802bf37..9663e6f7c5 100644 --- a/requirements/edx-platform-constraints.txt +++ b/requirements/edx-platform-constraints.txt @@ -8,16 +8,14 @@ # via -r requirements/edx/github.in acid-xblock==0.2.1 # via -r requirements/edx/kernel.in -aiohttp==3.8.6 +aiohttp==3.9.1 # via # geoip2 # openai aiosignal==1.3.1 # via aiohttp -algoliasearch==2.6.3 - # via - # -c requirements/edx/../constraints.txt - # -r requirements/edx/bundled.in +algoliasearch==3.0.0 + # via -r requirements/edx/bundled.in # via kombu analytics-python==1.4.post1 # via -r requirements/edx/kernel.in @@ -28,11 +26,10 @@ appdirs==1.4.4 asgiref==3.7.2 # via # django + # django-cors-headers # django-countries asn1crypto==1.5.1 - # via - # oscrypto - # snowflake-connector-python + # via snowflake-connector-python async-timeout==4.0.3 # via # aiohttp @@ -48,9 +45,8 @@ attrs==23.1.0 # openedx-events # openedx-learning # referencing -babel==2.11.0 +babel==2.14.0 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/kernel.in # enmerkar # enmerkar-underscore @@ -73,17 +69,15 @@ bleach[css]==6.1.0 # ora2 # xblock-drag-and-drop-v2 # xblock-poll -boto==2.39.0 - # via - # -c requirements/edx/../constraints.txt - # -r requirements/edx/kernel.in -boto3==1.28.62 +boto==2.49.0 + # via -r requirements/edx/kernel.in +boto3==1.33.12 # via # -r requirements/edx/kernel.in # django-ses # fs-s3fs # ora2 -botocore==1.31.62 +botocore==1.33.12 # via # -r requirements/edx/kernel.in # boto3 @@ -99,7 +93,7 @@ bridgekeeper==0.9 # edx-enterprise # event-tracking # openedx-learning -certifi==2023.7.22 +certifi==2023.11.17 # via # -r requirements/edx/paver.txt # elasticsearch @@ -117,7 +111,6 @@ charset-normalizer==2.0.12 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/paver.txt - # aiohttp # requests # snowflake-connector-python chem==1.2.0 @@ -163,7 +156,7 @@ cryptography==38.0.4 # pyopenssl # snowflake-connector-python # social-auth-core -cssutils==2.7.1 +cssutils==2.9.0 # via pynliner defusedxml==0.7.1 # via @@ -174,7 +167,7 @@ defusedxml==0.7.1 # social-auth-core deprecated==1.2.14 # via jwcrypto -django==3.2.22 +django==3.2.23 # via # -c requirements/edx/../common_constraints.txt # -r requirements/edx/kernel.in @@ -245,7 +238,7 @@ django==3.2.22 # ora2 # super-csv # xss-utils -django-appconf==1.0.5 +django-appconf==1.0.6 # via django-statici18n django-cache-memoize==0.2.0 django-celery-results==2.5.1 @@ -258,7 +251,7 @@ django-config-models==2.5.1 # edx-enterprise # edx-name-affirmation # lti-consumer-xblock -django-cors-headers==4.2.0 +django-cors-headers==4.3.1 # via -r requirements/edx/kernel.in django-countries==7.5.1 # via @@ -276,13 +269,13 @@ django-crum==0.7.9 django-environ==0.11.2 # via openedx-blockstore django-fernet-fields-v2==0.9 -django-filter==23.3 +django-filter==23.5 # via # -r requirements/edx/kernel.in # edx-enterprise # lti-consumer-xblock # openedx-blockstore -django-ipware==5.0.1 +django-ipware==6.0.2 # via # -r requirements/edx/kernel.in # edx-enterprise @@ -314,7 +307,7 @@ django-mptt==0.14.0 # -r requirements/edx/kernel.in # openedx-django-wiki django-multi-email-field==0.7.0 -django-mysql==4.11.0 +django-mysql==4.12.0 # via -r requirements/edx/kernel.in django-oauth-toolkit==1.7.1 # via @@ -330,7 +323,7 @@ django-sekizai==4.1.0 # via # -r requirements/edx/kernel.in # openedx-django-wiki -django-ses==3.5.0 +django-ses==3.5.2 # via -r requirements/edx/bundled.in # via # -r requirements/edx/kernel.in @@ -346,14 +339,13 @@ django-statici18n==2.4.0 # -r requirements/edx/kernel.in # lti-consumer-xblock # xblock-drag-and-drop-v2 -django-storages==1.14 +django-storages==1.14.2 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/kernel.in # edxval django-user-tasks==3.1.0 # via -r requirements/edx/kernel.in -django-waffle==4.0.0 +django-waffle==4.1.0 # via # -r requirements/edx/kernel.in # edx-django-utils @@ -390,13 +382,13 @@ djangorestframework==3.14.0 # ora2 # super-csv djangorestframework-xml==2.0.0 -done-xblock==2.1.0 +done-xblock==2.2.0 # via -r requirements/edx/bundled.in drf-jwt==1.19.2 # via edx-drf-extensions drf-nested-routers==0.93.4 # via openedx-blockstore -drf-spectacular==0.26.5 +drf-spectacular==0.27.0 # via -r requirements/edx/kernel.in drf-yasg==1.21.5 # via @@ -433,16 +425,16 @@ edx-celeryutils==1.2.3 # super-csv edx-codejail==3.3.3 # via -r requirements/edx/kernel.in -edx-completion==4.3.0 +edx-completion==4.4.0 # via -r requirements/edx/kernel.in edx-django-release-util==1.3.0 # via # -r requirements/edx/kernel.in # edxval # openedx-blockstore -edx-django-sites-extensions==4.0.1 +edx-django-sites-extensions==4.0.2 # via -r requirements/edx/kernel.in -edx-django-utils==5.7.0 +edx-django-utils==5.9.0 # via # -r requirements/edx/kernel.in # django-config-models @@ -458,7 +450,7 @@ edx-django-utils==5.7.0 # openedx-blockstore # ora2 # super-csv -edx-drf-extensions==8.12.0 +edx-drf-extensions==9.1.2 # via # -r requirements/edx/kernel.in # edx-completion @@ -470,7 +462,7 @@ edx-drf-extensions==8.12.0 # edx-when # edxval # openedx-learning -edx-enterprise==4.6.12 +edx-enterprise==4.10.6 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/kernel.in @@ -507,12 +499,12 @@ edx-proctoring==4.16.1 # -r requirements/edx/kernel.in # edx-proctoring-proctortrack edx-rbac==1.8.0 -edx-rest-api-client==5.6.0 +edx-rest-api-client==5.6.1 # via # -r requirements/edx/kernel.in # edx-enterprise # edx-proctoring -edx-search==3.6.0 +edx-search==3.8.2 # via -r requirements/edx/kernel.in edx-sga==0.23.0 # via -r requirements/edx/bundled.in @@ -551,11 +543,12 @@ enmerkar-underscore==2.2.0 event-tracking==2.2.0 # via # -r requirements/edx/kernel.in + # edx-completion # edx-proctoring # edx-search -fastavro==1.8.4 +fastavro==1.9.1 # via openedx-events -filelock==3.12.4 +filelock==3.13.1 # via snowflake-connector-python frozenlist==1.4.0 # via @@ -573,7 +566,7 @@ fs-s3fs==0.1.8 # openedx-django-pyfs future==0.18.3 # via pyjwkest -geoip2==4.7.0 +geoip2==4.8.0 # via -r requirements/edx/kernel.in glob2==0.7 # via -r requirements/edx/kernel.in @@ -585,21 +578,22 @@ html5lib==1.1 # via # -r requirements/edx/kernel.in # ora2 -icalendar==5.0.10 +icalendar==5.0.11 # via -r requirements/edx/kernel.in -idna==3.4 +idna==3.6 # via # -r requirements/edx/paver.txt # optimizely-sdk # requests # snowflake-connector-python # yarl -importlib-metadata==6.8.0 +importlib-metadata==7.0.0 # via markdown -importlib-resources==6.1.0 +importlib-resources==5.13.0 # via # jsonschema # jsonschema-specifications + # pycountry inflection==0.5.1 # via # drf-spectacular @@ -632,11 +626,11 @@ jsonfield==3.1.0 # edx-submissions # lti-consumer-xblock # ora2 -jsonschema==4.19.1 +jsonschema==4.20.0 # via # drf-spectacular # optimizely-sdk -jsonschema-specifications==2023.7.1 +jsonschema-specifications==2023.11.2 # via jsonschema jwcrypto==1.5.0 # via @@ -658,10 +652,8 @@ libsass==0.10.0 # -r requirements/edx/paver.txt loremipsum==1.0.5 # via ora2 -lti-consumer-xblock==9.6.1 - # via - # -c requirements/edx/../constraints.txt - # -r requirements/edx/kernel.in +lti-consumer-xblock==9.8.1 + # via -r requirements/edx/kernel.in lxml==4.9.3 # via # -r requirements/edx/kernel.in @@ -676,7 +668,7 @@ lxml==4.9.3 # xmlsec mailsnake==1.6.4 # via -r requirements/edx/bundled.in -mako==1.2.4 +mako==1.3.0 # via # -r requirements/edx/kernel.in # acid-xblock @@ -701,7 +693,7 @@ markupsafe==2.1.3 # mako # openedx-calc # xblock -maxminddb==2.4.0 +maxminddb==2.5.1 # via geoip2 mock==5.1.0 # via -r requirements/edx/paver.txt @@ -721,7 +713,7 @@ mysqlclient==2.2.0 # via # -r requirements/edx/kernel.in # openedx-blockstore -newrelic==9.1.0 +newrelic==9.3.0 # via # -r requirements/edx/bundled.in # edx-django-utils @@ -745,6 +737,9 @@ oauthlib==3.2.2 olxcleaner==0.2.1 # via -r requirements/edx/kernel.in openai==0.28.1 + # via + # -c requirements/edx/../constraints.txt + # edx-enterprise openedx-atlas==0.5.0 # via -r requirements/edx/kernel.in openedx-blockstore==1.4.0 @@ -759,7 +754,7 @@ openedx-django-require==2.1.0 # via -r requirements/edx/kernel.in openedx-django-wiki==2.0.3 # via -r requirements/edx/kernel.in -openedx-events==9.0.1 +openedx-events==9.2.0 # via # -r requirements/edx/kernel.in # edx-event-bus-kafka @@ -768,7 +763,7 @@ openedx-filters==1.6.0 # via # -r requirements/edx/kernel.in # lti-consumer-xblock -openedx-learning==0.3.2 +openedx-learning==0.4.2 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/kernel.in @@ -776,10 +771,8 @@ openedx-mongodbproxy==0.2.0 # via -r requirements/edx/kernel.in optimizely-sdk==4.1.1 # via -r requirements/edx/bundled.in -ora2==6.0.0 +ora2==6.0.28 # via -r requirements/edx/bundled.in -oscrypto==1.3.0 - # via snowflake-connector-python packaging==23.2 # via # drf-yasg @@ -788,7 +781,7 @@ packaging==23.2 # snowflake-connector-python pansi==2020.7.3 # via py2neo -path==16.7.1 +path==16.9.0 # via # -r requirements/edx/kernel.in # -r requirements/edx/paver.txt @@ -801,16 +794,15 @@ path-py==12.5.0 # staff-graded-xblock paver==1.3.4 # via -r requirements/edx/paver.txt -pbr==5.11.1 +pbr==6.0.0 # via # -r requirements/edx/paver.txt # stevedore pgpy==0.6.0 piexif==1.1.3 # via -r requirements/edx/kernel.in -pillow==9.5.0 +pillow==10.1.0 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/kernel.in # edx-enterprise # edx-organizations @@ -822,7 +814,7 @@ platformdirs==3.11.0 polib==1.2.0 # via edx-i18n-tools # via click-repl -psutil==5.9.5 +psutil==5.9.6 # via # -r requirements/edx/paver.txt # edx-django-utils @@ -830,9 +822,9 @@ py2neo @ https://github.com/overhangio/py2neo/releases/download/2021.2.3/py2neo- # via # -c requirements/edx/../constraints.txt # -r requirements/edx/bundled.in -pyasn1==0.5.0 +pyasn1==0.5.1 # via pgpy -pycountry==22.3.5 +pycountry==23.12.11 # via -r requirements/edx/kernel.in pycparser==2.21 # via cffi @@ -842,8 +834,7 @@ pycryptodomex==3.19.0 # edx-proctoring # lti-consumer-xblock # pyjwkest - # snowflake-connector-python -pygments==2.16.1 +pygments==2.17.2 # via # -r requirements/edx/bundled.in # py2neo @@ -891,7 +882,7 @@ pyparsing==3.1.1 # via # chem # openedx-calc -pyrsistent==0.19.3 +pyrsistent==0.20.0 # via optimizely-sdk pysrt==1.1.2 # via @@ -910,6 +901,8 @@ python-dateutil==2.8.2 # olxcleaner # ora2 # xblock +python-ipware==2.0.0 + # via django-ipware python-memcached==1.59 # via -r requirements/edx/paver.txt python-slugify==8.0.1 @@ -922,9 +915,8 @@ python3-openid==3.2.0 ; python_version >= "3" # social-auth-core python3-saml==1.16.0 # via -r requirements/edx/kernel.in -pytz==2022.7.1 +pytz==2023.3.post1 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/kernel.in # babel # django @@ -963,7 +955,7 @@ redis==5.0.1 # via # -r requirements/edx/kernel.in # walrus -referencing==0.30.2 +referencing==0.32.0 # via # jsonschema # jsonschema-specifications @@ -996,11 +988,11 @@ requests-oauthlib==1.3.1 # via # -r requirements/edx/kernel.in # social-auth-core -rpds-py==0.10.4 +rpds-py==0.13.2 # via # jsonschema # referencing -ruamel-yaml==0.17.35 +ruamel-yaml==0.18.5 # via drf-yasg ruamel-yaml-clib==0.2.8 # via ruamel-yaml @@ -1010,7 +1002,7 @@ rules==3.3 # edx-enterprise # edx-proctoring # openedx-learning -s3transfer==0.7.0 +s3transfer==0.8.2 # via boto3 sailthru-client==2.2.3 # via edx-ace @@ -1021,7 +1013,7 @@ scipy==1.7.3 # openedx-calc semantic-version==2.10.0 # via edx-drf-extensions -shapely==2.0.1 +shapely==2.0.2 # via -r requirements/edx/kernel.in simplejson==3.19.2 # via @@ -1062,10 +1054,11 @@ six==1.16.0 # python-memcached slumber==0.7.1 # via + # -r requirements/edx/kernel.in # edx-bulk-grades # edx-enterprise # edx-rest-api-client -snowflake-connector-python==3.2.1 +snowflake-connector-python==3.6.0 social-auth-app-django==5.0.0 # via # -c requirements/edx/../constraints.txt @@ -1092,7 +1085,7 @@ sqlparse==0.4.4 # -r requirements/edx/kernel.in # django # openedx-blockstore -staff-graded-xblock==2.1.1 +staff-graded-xblock==2.2.0 # via -r requirements/edx/bundled.in stevedore==5.1.0 # via @@ -1107,22 +1100,23 @@ super-csv==3.1.0 # via edx-bulk-grades sympy==1.12 # via openedx-calc -testfixtures==7.2.0 +testfixtures==7.2.2 text-unidecode==1.3 # via python-slugify tinycss2==1.2.1 # via bleach -tomlkit==0.12.1 +tomlkit==0.12.3 # via snowflake-connector-python tqdm==4.66.1 # via # nltk # openai -typing-extensions==4.8.0 +typing-extensions==4.9.0 # via # -r requirements/edx/paver.txt # asgiref # django-countries + # drf-spectacular # edx-opaque-keys # kombu # pylti1p3 @@ -1140,7 +1134,7 @@ uritemplate==4.1.1 # coreapi # drf-spectacular # drf-yasg -urllib3==1.26.17 +urllib3==1.26.18 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/paver.txt @@ -1155,13 +1149,13 @@ user-util==1.0.0 # amqp # celery # kombu -voluptuous==0.13.1 +voluptuous==0.14.1 # via ora2 walrus==0.9.3 # via edx-event-bus-redis watchdog==3.0.0 # via -r requirements/edx/paver.txt -wcwidth==0.2.8 +wcwidth==0.2.12 # via prompt-toolkit web-fragments==2.1.0 # via @@ -1180,11 +1174,11 @@ webob==1.8.7 # via # -r requirements/edx/kernel.in # xblock -wrapt==1.15.0 +wrapt==1.16.0 # via # -r requirements/edx/paver.txt # deprecated -xblock[django]==1.8.1 +xblock[django]==1.9.0 # via # -r requirements/edx/kernel.in # acid-xblock @@ -1196,28 +1190,25 @@ xblock[django]==1.8.1 # lti-consumer-xblock # ora2 # staff-graded-xblock + # xblock-drag-and-drop-v2 # xblock-google-drive # xblock-poll # xblock-utils -xblock-drag-and-drop-v2==3.2.0 +xblock-drag-and-drop-v2==3.3.0 # via -r requirements/edx/bundled.in -xblock-google-drive==0.4.0 +xblock-google-drive==0.5.0 # via -r requirements/edx/bundled.in xblock-poll==1.13.0 # via -r requirements/edx/bundled.in xblock-utils==4.0.0 # via - # done-xblock # edx-sga - # lti-consumer-xblock - # staff-graded-xblock - # xblock-drag-and-drop-v2 # xblock-google-drive xmlsec==1.3.13 # via python3-saml xss-utils==0.5.0 # via -r requirements/edx/kernel.in -yarl==1.9.2 +yarl==1.9.4 # via aiohttp zipp==3.17.0 # via diff --git a/requirements/js_test.txt b/requirements/js_test.txt index 49ff64e80f..025c512c6b 100644 --- a/requirements/js_test.txt +++ b/requirements/js_test.txt @@ -6,19 +6,19 @@ # annotated-types==0.6.0 # via pydantic -attrs==23.1.0 +attrs==23.2.0 # via # outcome # trio autocommand==2.2.2 # via jaraco-text -certifi==2023.7.22 +certifi==2023.11.17 # via selenium cheroot==10.0.0 # via cherrypy -cherrypy==18.8.0 +cherrypy==18.9.0 # via jasmine -exceptiongroup==1.1.3 +exceptiongroup==1.2.0 # via # trio # trio-websocket @@ -26,7 +26,7 @@ glob2==0.7 # via jasmine-core h11==0.14.0 # via wsproto -idna==3.4 +idna==3.6 # via trio importlib-resources==6.1.1 # via jaraco-text @@ -34,7 +34,7 @@ inflect==7.0.0 # via jaraco-text jaraco-classes==3.3.0 # via -r requirements/js_test.in -jaraco-collections==4.3.0 +jaraco-collections==5.0.0 # via # -r requirements/js_test.in # cherrypy @@ -46,7 +46,7 @@ jaraco-functools==4.0.0 # cheroot # jaraco-text # tempora -jaraco-text==3.11.1 +jaraco-text==3.12.0 # via jaraco-collections jasmine==3.99.0 # via -r requirements/js_test.in @@ -54,9 +54,9 @@ jasmine-core==3.99.0 # via jasmine jinja2==2.11.3 # via jasmine -markupsafe==2.1.3 +markupsafe==2.1.4 # via jinja2 -more-itertools==10.1.0 +more-itertools==10.2.0 # via # cheroot # cherrypy @@ -69,9 +69,9 @@ outcome==1.3.0.post0 # via trio portend==3.2.0 # via cherrypy -pydantic==2.4.2 +pydantic==2.5.3 # via inflect -pydantic-core==2.10.1 +pydantic-core==2.14.6 # via pydantic pysocks==1.7.1 # via urllib3 @@ -79,7 +79,7 @@ pytz==2023.3.post1 # via tempora pyyaml==6.0.1 # via jasmine -selenium==4.15.2 +selenium==4.16.0 # via jasmine sniffio==1.3.0 # via trio @@ -89,20 +89,22 @@ tempora==5.5.0 # via # -r requirements/js_test.in # portend -trio==0.23.1 +trio==0.24.0 # via # selenium # trio-websocket trio-websocket==0.11.1 # via selenium -typing-extensions==4.8.0 +typing-extensions==4.9.0 # via # annotated-types # inflect # pydantic # pydantic-core -urllib3[socks]==2.0.7 - # via selenium +urllib3[socks]==2.1.0 + # via + # selenium + # urllib3 wsproto==1.2.0 # via trio-websocket zc-lockfile==3.0.post1 diff --git a/requirements/test-master.txt b/requirements/test-master.txt index 6f7c3fcff4..8c3d25ecaf 100644 --- a/requirements/test-master.txt +++ b/requirements/test-master.txt @@ -4,7 +4,7 @@ # # make upgrade # -aiohttp==3.8.6 +aiohttp==3.9.1 # via # -c requirements/edx-platform-constraints.txt # openai @@ -26,7 +26,6 @@ asgiref==3.7.2 asn1crypto==1.5.1 # via # -c requirements/edx-platform-constraints.txt - # oscrypto # snowflake-connector-python async-timeout==4.0.3 # via @@ -47,11 +46,11 @@ bleach==6.1.0 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in -celery==5.3.4 +celery==5.3.6 # via # -c requirements/constraints.txt # -r requirements/base.in -certifi==2023.7.22 +certifi==2023.11.17 # via # -c requirements/edx-platform-constraints.txt # requests @@ -65,7 +64,6 @@ cffi==1.16.0 charset-normalizer==2.0.12 # via # -c requirements/edx-platform-constraints.txt - # aiohttp # requests # snowflake-connector-python click==8.1.7 @@ -116,7 +114,7 @@ deprecated==1.2.14 # via # -c requirements/edx-platform-constraints.txt # jwcrypto -django==3.2.22 +django==3.2.23 # via # -c requirements/common_constraints.txt # -c requirements/edx-platform-constraints.txt @@ -161,11 +159,11 @@ django-fernet-fields-v2==0.9 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in -django-filter==23.3 +django-filter==23.5 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in -django-ipware==5.0.1 +django-ipware==6.0.2 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in @@ -190,7 +188,7 @@ django-simple-history==3.1.1 # via # -c requirements/constraints.txt # -r requirements/base.in -django-waffle==4.0.0 +django-waffle==4.1.0 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in @@ -226,7 +224,7 @@ edx-braze-client==0.1.8 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in -edx-django-utils==5.7.0 +edx-django-utils==5.9.0 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in @@ -234,7 +232,7 @@ edx-django-utils==5.7.0 # edx-drf-extensions # edx-rest-api-client # edx-toggles -edx-drf-extensions==8.12.0 +edx-drf-extensions==9.1.2 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in @@ -248,7 +246,7 @@ edx-rbac==1.8.0 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in -edx-rest-api-client==5.6.0 +edx-rest-api-client==5.6.1 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in @@ -260,7 +258,7 @@ edx-toggles==5.1.0 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in -filelock==3.12.4 +filelock==3.13.1 # via # -c requirements/edx-platform-constraints.txt # snowflake-connector-python @@ -269,7 +267,7 @@ frozenlist==1.4.0 # -c requirements/edx-platform-constraints.txt # aiohttp # aiosignal -idna==3.4 +idna==3.6 # via # -c requirements/edx-platform-constraints.txt # requests @@ -300,7 +298,7 @@ jwcrypto==1.5.0 # via # -c requirements/edx-platform-constraints.txt # django-oauth-toolkit -kombu==5.3.3 +kombu==5.3.5 # via celery markupsafe==2.1.3 # via @@ -311,7 +309,7 @@ multidict==6.0.4 # -c requirements/edx-platform-constraints.txt # aiohttp # yarl -newrelic==9.1.0 +newrelic==9.3.0 # via # -c requirements/edx-platform-constraints.txt # edx-django-utils @@ -323,16 +321,12 @@ openai==0.28.1 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in -oscrypto==1.3.0 - # via - # -c requirements/edx-platform-constraints.txt - # snowflake-connector-python packaging==23.2 # via # -c requirements/edx-platform-constraints.txt # drf-yasg # snowflake-connector-python -path==16.7.1 +path==16.9.0 # via # -c requirements/edx-platform-constraints.txt # path-py @@ -340,7 +334,7 @@ path-py==12.5.0 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in -pbr==5.11.1 +pbr==6.0.0 # via # -c requirements/edx-platform-constraints.txt # stevedore @@ -348,7 +342,7 @@ pgpy==0.6.0 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in -pillow==9.5.0 +pillow==10.1.0 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in @@ -356,13 +350,13 @@ platformdirs==3.11.0 # via # -c requirements/edx-platform-constraints.txt # snowflake-connector-python -prompt-toolkit==3.0.39 +prompt-toolkit==3.0.43 # via click-repl -psutil==5.9.5 +psutil==5.9.6 # via # -c requirements/edx-platform-constraints.txt # edx-django-utils -pyasn1==0.5.0 +pyasn1==0.5.1 # via # -c requirements/edx-platform-constraints.txt # pgpy @@ -370,16 +364,13 @@ pycparser==2.21 # via # -c requirements/edx-platform-constraints.txt # cffi -pycryptodomex==3.19.0 - # via - # -c requirements/edx-platform-constraints.txt - # snowflake-connector-python pyjwt[crypto]==2.8.0 # via # -c requirements/edx-platform-constraints.txt # drf-jwt # edx-drf-extensions # edx-rest-api-client + # pyjwt # snowflake-connector-python pymongo==3.13.0 # via @@ -398,11 +389,15 @@ python-dateutil==2.8.2 # -c requirements/edx-platform-constraints.txt # -r requirements/base.in # celery +python-ipware==2.0.0 + # via + # -c requirements/edx-platform-constraints.txt + # django-ipware python-slugify==8.0.1 # via # -c requirements/edx-platform-constraints.txt # code-annotations -pytz==2022.7.1 +pytz==2023.3.post1 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in @@ -426,7 +421,7 @@ requests==2.31.0 # openai # slumber # snowflake-connector-python -ruamel-yaml==0.17.35 +ruamel-yaml==0.18.5 # via # -c requirements/edx-platform-constraints.txt # drf-yasg @@ -453,7 +448,7 @@ slumber==0.7.1 # -c requirements/edx-platform-constraints.txt # -r requirements/base.in # edx-rest-api-client -snowflake-connector-python==3.2.1 +snowflake-connector-python==3.6.0 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in @@ -472,7 +467,7 @@ stevedore==5.1.0 # code-annotations # edx-django-utils # edx-opaque-keys -testfixtures==7.2.0 +testfixtures==7.2.2 # via # -c requirements/edx-platform-constraints.txt # -r requirements/base.in @@ -480,7 +475,7 @@ text-unidecode==1.3 # via # -c requirements/edx-platform-constraints.txt # python-slugify -tomlkit==0.12.1 +tomlkit==0.12.3 # via # -c requirements/edx-platform-constraints.txt # snowflake-connector-python @@ -488,7 +483,7 @@ tqdm==4.66.1 # via # -c requirements/edx-platform-constraints.txt # openai -typing-extensions==4.8.0 +typing-extensions==4.9.0 # via # -c requirements/edx-platform-constraints.txt # asgiref @@ -510,7 +505,7 @@ uritemplate==4.1.1 # -c requirements/edx-platform-constraints.txt # coreapi # drf-yasg -urllib3==1.26.17 +urllib3==1.26.18 # via # -c requirements/edx-platform-constraints.txt # requests @@ -520,7 +515,7 @@ vine==5.1.0 # amqp # celery # kombu -wcwidth==0.2.8 +wcwidth==0.2.12 # via # -c requirements/edx-platform-constraints.txt # prompt-toolkit @@ -528,11 +523,11 @@ webencodings==0.5.1 # via # -c requirements/edx-platform-constraints.txt # bleach -wrapt==1.15.0 +wrapt==1.16.0 # via # -c requirements/edx-platform-constraints.txt # deprecated -yarl==1.9.2 +yarl==1.9.4 # via # -c requirements/edx-platform-constraints.txt # aiohttp diff --git a/requirements/test.txt b/requirements/test.txt index 6880b62747..9e57a322ee 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -4,7 +4,7 @@ # # make upgrade # -aiohttp==3.8.6 +aiohttp==3.9.1 # via # -r requirements/test-master.txt # openai @@ -27,7 +27,6 @@ asgiref==3.7.2 asn1crypto==1.5.1 # via # -r requirements/test-master.txt - # oscrypto # snowflake-connector-python async-timeout==4.0.3 # via @@ -42,6 +41,7 @@ backports-zoneinfo[tzdata]==0.2.1 # via # -r requirements/test-master.txt # -r requirements/test.in + # backports-zoneinfo # celery # kombu # via @@ -52,7 +52,7 @@ bleach==6.1.0 # via # -c requirements/constraints.txt # -r requirements/test-master.txt -certifi==2023.7.22 +certifi==2023.11.17 # via # -r requirements/test-master.txt # requests @@ -68,7 +68,6 @@ chardet==5.2.0 charset-normalizer==2.0.12 # via # -r requirements/test-master.txt - # aiohttp # requests # snowflake-connector-python # via @@ -102,8 +101,10 @@ coreschema==0.0.4 # -r requirements/test-master.txt # coreapi # drf-yasg -coverage[toml]==7.3.2 - # via pytest-cov +coverage[toml]==7.4.0 + # via + # coverage + # pytest-cov cryptography==38.0.4 # via # -r requirements/test-master.txt @@ -123,7 +124,7 @@ deprecated==1.2.14 # via # -r requirements/test-master.txt # jwcrypto -diff-cover==8.0.0 +diff-cover==8.0.3 # via -r requirements/test.in # via # -c requirements/common_constraints.txt @@ -159,9 +160,9 @@ django-crum==0.7.9 # edx-toggles django-fernet-fields-v2==0.9 # via -r requirements/test-master.txt -django-filter==23.3 +django-filter==23.5 # via -r requirements/test-master.txt -django-ipware==5.0.1 +django-ipware==6.0.2 # via -r requirements/test-master.txt django-model-utils==4.3.1 # via @@ -178,7 +179,7 @@ django-simple-history==3.1.1 # via # -c requirements/constraints.txt # -r requirements/test-master.txt -django-waffle==4.0.0 +django-waffle==4.1.0 # via # -r requirements/test-master.txt # edx-django-utils @@ -206,14 +207,14 @@ edx-api-doc-tools==1.7.0 # via -r requirements/test-master.txt edx-braze-client==0.1.8 # via -r requirements/test-master.txt -edx-django-utils==5.7.0 +edx-django-utils==5.9.0 # via # -r requirements/test-master.txt # django-config-models # edx-drf-extensions # edx-rest-api-client # edx-toggles -edx-drf-extensions==8.12.0 +edx-drf-extensions==9.1.2 # via # -r requirements/test-master.txt # edx-rbac @@ -221,9 +222,10 @@ edx-opaque-keys[django]==2.5.1 # via # -r requirements/test-master.txt # edx-drf-extensions + # edx-opaque-keys edx-rbac==1.8.0 # via -r requirements/test-master.txt -edx-rest-api-client==5.6.0 +edx-rest-api-client==5.6.1 # via -r requirements/test-master.txt edx-tincan-py35==1.0.0 # via -r requirements/test-master.txt @@ -233,9 +235,9 @@ factory-boy==3.3.0 # via # -c requirements/constraints.txt # -r requirements/test.in -faker==19.13.0 +faker==22.5.0 # via factory-boy -filelock==3.12.4 +filelock==3.13.1 # via # -r requirements/test-master.txt # snowflake-connector-python @@ -248,7 +250,7 @@ frozenlist==1.4.0 # -r requirements/test-master.txt # aiohttp # aiosignal -idna==3.4 +idna==3.6 # via # -r requirements/test-master.txt # requests @@ -294,7 +296,7 @@ multidict==6.0.4 # -r requirements/test-master.txt # aiohttp # yarl -newrelic==9.1.0 +newrelic==9.3.0 # via # -r requirements/test-master.txt # edx-django-utils @@ -304,29 +306,25 @@ oauthlib==3.2.2 # django-oauth-toolkit openai==0.28.1 # via -r requirements/test-master.txt -oscrypto==1.3.0 - # via - # -r requirements/test-master.txt - # snowflake-connector-python packaging==23.2 # via # -r requirements/test-master.txt # drf-yasg # pytest # snowflake-connector-python -path==16.7.1 +path==16.9.0 # via # -r requirements/test-master.txt # path-py path-py==12.5.0 # via -r requirements/test-master.txt -pbr==5.11.1 +pbr==6.0.0 # via # -r requirements/test-master.txt # stevedore pgpy==0.6.0 # via -r requirements/test-master.txt -pillow==9.5.0 +pillow==10.1.0 # via -r requirements/test-master.txt platformdirs==3.11.0 # via @@ -339,13 +337,13 @@ pluggy==1.3.0 # via # -r requirements/test-master.txt # click-repl -psutil==5.9.5 +psutil==5.9.6 # via # -r requirements/test-master.txt # edx-django-utils py==1.11.0 # via pytest -pyasn1==0.5.0 +pyasn1==0.5.1 # via # -r requirements/test-master.txt # pgpy @@ -353,11 +351,7 @@ pycparser==2.21 # via # -r requirements/test-master.txt # cffi -pycryptodomex==3.19.0 - # via - # -r requirements/test-master.txt - # snowflake-connector-python -pygments==2.16.1 +pygments==2.17.2 # via diff-cover pyjwt[crypto]==2.8.0 # via @@ -365,6 +359,7 @@ pyjwt[crypto]==2.8.0 # drf-jwt # edx-drf-extensions # edx-rest-api-client + # pyjwt # snowflake-connector-python pymongo==3.13.0 # via @@ -393,11 +388,15 @@ python-dateutil==2.8.2 # celery # faker # freezegun +python-ipware==2.0.0 + # via + # -r requirements/test-master.txt + # django-ipware python-slugify==8.0.1 # via # -r requirements/test-master.txt # code-annotations -pytz==2022.7.1 +pytz==2023.3.post1 # via # -r requirements/test-master.txt # django @@ -424,7 +423,7 @@ responses==0.10.15 # via # -c requirements/constraints.txt # -r requirements/test.in -ruamel-yaml==0.17.35 +ruamel-yaml==0.18.5 # via # -r requirements/test-master.txt # drf-yasg @@ -451,7 +450,7 @@ slumber==0.7.1 # via # -r requirements/test-master.txt # edx-rest-api-client -snowflake-connector-python==3.2.1 +snowflake-connector-python==3.6.0 # via -r requirements/test-master.txt sortedcontainers==2.4.0 # via @@ -467,7 +466,7 @@ stevedore==5.1.0 # code-annotations # edx-django-utils # edx-opaque-keys -testfixtures==7.2.0 +testfixtures==7.2.2 # via # -r requirements/test-master.txt # -r requirements/test.in @@ -479,7 +478,7 @@ toml==0.10.2 # via pytest tomli==2.0.1 # via coverage -tomlkit==0.12.1 +tomlkit==0.12.3 # via # -r requirements/test-master.txt # snowflake-connector-python @@ -487,7 +486,7 @@ tqdm==4.66.1 # via # -r requirements/test-master.txt # openai -typing-extensions==4.8.0 +typing-extensions==4.9.0 # via # -r requirements/test-master.txt # asgiref @@ -508,7 +507,7 @@ uritemplate==4.1.1 # -r requirements/test-master.txt # coreapi # drf-yasg -urllib3==1.26.17 +urllib3==1.26.18 # via # -r requirements/test-master.txt # requests @@ -518,7 +517,7 @@ urllib3==1.26.17 # amqp # celery # kombu -wcwidth==0.2.8 +wcwidth==0.2.12 # via # -r requirements/test-master.txt # prompt-toolkit @@ -526,11 +525,11 @@ webencodings==0.5.1 # via # -r requirements/test-master.txt # bleach -wrapt==1.15.0 +wrapt==1.16.0 # via # -r requirements/test-master.txt # deprecated -yarl==1.9.2 +yarl==1.9.4 # via # -r requirements/test-master.txt # aiohttp diff --git a/tests/test_enterprise/api/test_views.py b/tests/test_enterprise/api/test_views.py index 6383f3dce1..97ff1a3512 100644 --- a/tests/test_enterprise/api/test_views.py +++ b/tests/test_enterprise/api/test_views.py @@ -1197,6 +1197,7 @@ class TestEnterpriseCustomerViewSet(BaseTestEnterpriseAPIViews): 'enable_pathways': True, 'enable_programs': True, 'enable_demo_data_for_analytics_and_lpr': False, + 'enable_academies': False, }], ), ( @@ -1255,6 +1256,7 @@ class TestEnterpriseCustomerViewSet(BaseTestEnterpriseAPIViews): 'enable_pathways': True, 'enable_programs': True, 'enable_demo_data_for_analytics_and_lpr': False, + 'enable_academies': False, }, 'active': True, 'user_id': 0, 'user': None, 'data_sharing_consent_records': [], 'groups': [], @@ -1350,6 +1352,7 @@ class TestEnterpriseCustomerViewSet(BaseTestEnterpriseAPIViews): 'enable_pathways': True, 'enable_programs': True, 'enable_demo_data_for_analytics_and_lpr': False, + 'enable_academies': False, }], ), ( @@ -1416,6 +1419,7 @@ class TestEnterpriseCustomerViewSet(BaseTestEnterpriseAPIViews): 'enable_pathways': True, 'enable_programs': True, 'enable_demo_data_for_analytics_and_lpr': False, + 'enable_academies': False, }], ), ( @@ -1653,6 +1657,7 @@ def test_enterprise_customer_with_access_to( 'enable_pathways': True, 'enable_programs': True, 'enable_demo_data_for_analytics_and_lpr': False, + 'enable_academies': False, } else: mock_empty_200_success_response = { diff --git a/tests/test_integrated_channels/test_cornerstone/test_client.py b/tests/test_integrated_channels/test_cornerstone/test_client.py index 06a1f0ddb4..ffc5b07aed 100644 --- a/tests/test_integrated_channels/test_cornerstone/test_client.py +++ b/tests/test_integrated_channels/test_cornerstone/test_client.py @@ -8,9 +8,15 @@ import pytest import responses +from django.apps import apps + from integrated_channels.cornerstone.client import CornerstoneAPIClient from test_utils import factories +IntegratedChannelAPIRequestLogs = apps.get_model( + "integrated_channel", "IntegratedChannelAPIRequestLogs" +) + @pytest.mark.django_db class TestCornerstoneApiClient(unittest.TestCase): @@ -26,7 +32,7 @@ def setUp(self): ) @responses.activate - def test_create_course_completion(self): + def test_create_course_completion_stores_api_record(self): """ ``create_course_completion`` should use the appropriate URLs for transmission. """ @@ -47,9 +53,10 @@ def test_create_course_completion(self): json="{}", status=200, ) + assert IntegratedChannelAPIRequestLogs.objects.count() == 0 output = cornerstone_api_client.create_course_completion( "test-learner@example.com", json.dumps(payload) ) - + assert IntegratedChannelAPIRequestLogs.objects.count() == 1 assert len(responses.calls) == 1 assert output == (200, '"{}"') diff --git a/tests/test_integrated_channels/test_degreed2/test_client.py b/tests/test_integrated_channels/test_degreed2/test_client.py index 52e431f621..bbc3c409f2 100644 --- a/tests/test_integrated_channels/test_degreed2/test_client.py +++ b/tests/test_integrated_channels/test_degreed2/test_client.py @@ -206,6 +206,29 @@ def test_delete_course_completion(self): degreed_api_client = Degreed2APIClient(enterprise_config) degreed_api_client.delete_course_completion(None, None) + @mock.patch('integrated_channels.degreed2.client.Degreed2APIClient._get') + def test_fetch_degreed_course_id_cache(self, mock_get_request): + """ + ``fetch_degreed_course_id`` should fetch data from the API only if the cache is empty. + """ + enterprise_config = factories.Degreed2EnterpriseCustomerConfigurationFactory() + degreed_api_client = Degreed2APIClient(enterprise_config) + mock_get_request.return_value = ( + 200, '{"data": [{"id": "degreed_course_id"}]}' + ) + degreed_external_course_id_1 = 'course_id_1' + degreed_external_course_id_2 = 'course_id_2' + + degreed_api_client.fetch_degreed_course_id(degreed_external_course_id_1) + degreed_api_client.fetch_degreed_course_id(degreed_external_course_id_2) + assert mock_get_request.call_count == 2 + + # The second call for the same course id should return the degreed_course_id from the cache + mock_get_request.reset_mock() + degreed_api_client.fetch_degreed_course_id(degreed_external_course_id_1) + degreed_api_client.fetch_degreed_course_id(degreed_external_course_id_2) + assert mock_get_request.call_count == 0 + @responses.activate @pytest.mark.django_db @mock.patch('enterprise.api_client.client.JwtBuilder', mock.Mock()) @@ -239,6 +262,7 @@ def test_create_content_metadata_success(self): json={"skill_names": ["Supply Chain", "Supply Chain Management"]}, status=200, ) + # The second call for the same course id should return the degreed_course_id from the cache responses.add( responses.GET, course_url + "?filter%5Bexternal_id%5D=key", @@ -253,7 +277,7 @@ def test_create_content_metadata_success(self): ) status_code, response_body = degreed_api_client.create_content_metadata(create_course_payload()) - assert len(responses.calls) == 5 + assert len(responses.calls) == 4 assert responses.calls[0].request.url == oauth_url assert responses.calls[1].request.url == course_url assert status_code == 200 @@ -298,6 +322,7 @@ def test_create_content_metadata_retry_success(self): json={"skill_names": ["Supply Chain", "Supply Chain Management"]}, status=200, ) + # The second call for the same course id should return the degreed_course_id from the cache responses.add( responses.GET, course_url + "?filter%5Bexternal_id%5D=key", @@ -311,7 +336,7 @@ def test_create_content_metadata_retry_success(self): status=200, ) status_code, response_body = degreed_api_client.create_content_metadata(create_course_payload()) - assert len(responses.calls) == 6 + assert len(responses.calls) == 5 assert responses.calls[0].request.url == oauth_url assert responses.calls[1].request.url == course_url assert responses.calls[2].request.url == course_url diff --git a/tests/test_utilities.py b/tests/test_utilities.py index 92edcc185d..906e4e7f3c 100644 --- a/tests/test_utilities.py +++ b/tests/test_utilities.py @@ -177,6 +177,7 @@ def setUp(self): "enable_pathways", "enable_programs", "enable_demo_data_for_analytics_and_lpr", + "enable_academies", ] ), (