diff --git a/.gitignore b/.gitignore
index 93e7105..0809a02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,5 @@ build/
.coverage
dist/
/pii_report/*.yaml
+docs/_build
+venv
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 6e5207d..1cf8e8d 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -14,6 +14,47 @@ Change Log
Unreleased
~~~~~~~~~~
+[5.0.0] - 2024-10-22
+~~~~~~~~~~~~~~~~~~~~
+Removed
+-------
+* Deleted Datadog diagnostics plugin app and middleware, which are no longer in use in edxapp.
+
+[4.5.0] - 2024-09-19
+~~~~~~~~~~~~~~~~~~~~
+Added
+-----
+* Datadog diagnostics middleware can now attempt to close anomalous spans. Can be enabled via Waffle flag ``datadog.diagnostics.close_anomalous_spans`` (controlled separately from logging feature).
+
+[4.4.0] - 2024-09-10
+~~~~~~~~~~~~~~~~~~~~
+Changed
+-------
+* Datadog diagnostics now logs ancestor spans when an anomaly is encountered, up to a limit of 10 (controlled by new Django setting ``DATADOG_DIAGNOSTICS_LOG_SPAN_DEPTH``). Spans are logged in full and on separate lines, so this logging is now much more verbose; consider only enabling this logging for short periods. Log format of first line has also changed slightly.
+
+[4.3.0] - 2024-08-22
+~~~~~~~~~~~~~~~~~~~~
+Added
+-----
+* Added celery lifecycle logging for Datadog diagnostics, to be enabled using ``DATADOG_DIAGNOSTICS_CELERY_LOG_SIGNALS``.
+
+[4.2.0] - 2024-08-13
+~~~~~~~~~~~~~~~~~~~~
+Fixed
+-----
+* Fixed loading of ``DATADOG_DIAGNOSTICS_ENABLE``, which was previously not loaded properly and therefore was always True. Also fixed loading of ``DATADOG_DIAGNOSTICS_MAX_SPANS``, which was presumably broken as well.
+
+Removed
+-------
+* Removed early span-start logging. It never worked properly, possibly because workers are continually being destroyed and created, leading to high log volume.
+
+[4.1.0] - 2024-08-09
+~~~~~~~~~~~~~~~~~~~~
+Changed
+-------
+* Datadog diagnostics will now log all span-starts for the first minute after server startup
+* **WARNING**: Do not use this version; see 4.2.0 release notes.
+
[4.0.0] - 2024-08-05
~~~~~~~~~~~~~~~~~~~~
Changed
diff --git a/docs/conf.py b/docs/conf.py
index fd05e10..8ac6aca 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -15,8 +15,8 @@
import re
import sys
from subprocess import check_call
-
-import edx_theme
+from datetime import datetime
+import sphinx_book_theme
from django import setup as django_setup
@@ -59,7 +59,7 @@ def get_version(*file_paths):
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
- 'edx_theme',
+ 'sphinx_book_theme',
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
@@ -90,8 +90,8 @@ def get_version(*file_paths):
# General information about the project.
project = 'edx-arch-experiments'
-copyright = edx_theme.COPYRIGHT # pylint: disable=redefined-builtin
-author = edx_theme.AUTHOR
+copyright = f'{datetime.now().year}, edX Inc.' # pylint: disable=redefined-builtin
+author ="edX Inc."
project_title = 'edx-arch-experiments'
documentation_title = f"{project_title}"
@@ -162,16 +162,47 @@ def get_version(*file_paths):
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
-html_theme = 'edx_theme'
+html_theme = 'sphinx_book_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
-# html_theme_options = {}
-# Add any paths that contain custom themes here, relative to this directory.
-html_theme_path = [edx_theme.get_html_theme_path()]
+html_theme_options = {
+
+ "repository_url": "https://github.com/edx/edx-arch-experiments",
+ "repository_branch": "main",
+ "path_to_docs": "docs/",
+ "use_repository_button": True,
+ "use_issues_button": True,
+ "use_edit_page_button": True,
+ # Please don't change unless you know what you're doing.
+ "extra_footer": """
+
+
+
+
+ These works by
+ edX LLC
+ are licensed under a
+ Creative Commons Attribution-ShareAlike 4.0 International License.
+ """
+}
+
+html_logo = "https://logos.openedx.org/open-edx-logo-color.png"
+html_favicon = "https://logos.openedx.org/open-edx-favicon.ico"
# The name for this set of Sphinx documents.
# " v documentation" by default.
diff --git a/edx_arch_experiments/__init__.py b/edx_arch_experiments/__init__.py
index a00a1e5..068150b 100644
--- a/edx_arch_experiments/__init__.py
+++ b/edx_arch_experiments/__init__.py
@@ -2,4 +2,4 @@
A plugin to include applications under development by the architecture team at 2U.
"""
-__version__ = '4.0.0'
+__version__ = '5.0.0'
diff --git a/edx_arch_experiments/datadog_diagnostics/README.rst b/edx_arch_experiments/datadog_diagnostics/README.rst
deleted file mode 100644
index 364ad6d..0000000
--- a/edx_arch_experiments/datadog_diagnostics/README.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Datadog Diagnostics
-###################
-
-When installed in the LMS as a plugin app, the ``datadog_diagnostics`` app adds additional logging for debugging our Datadog integration.
-
-This is intended as a temporary situation while we debug the `trace concatenation issue `_.
diff --git a/edx_arch_experiments/datadog_diagnostics/__init__.py b/edx_arch_experiments/datadog_diagnostics/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/edx_arch_experiments/datadog_diagnostics/apps.py b/edx_arch_experiments/datadog_diagnostics/apps.py
index de29169..e69de29 100644
--- a/edx_arch_experiments/datadog_diagnostics/apps.py
+++ b/edx_arch_experiments/datadog_diagnostics/apps.py
@@ -1,74 +0,0 @@
-"""
-App for emitting additional diagnostic information for the Datadog integration.
-"""
-
-import logging
-
-from django.apps import AppConfig
-from django.conf import settings
-
-log = logging.getLogger(__name__)
-
-
-# .. toggle_name: DATADOG_DIAGNOSTICS_ENABLE
-# .. toggle_implementation: DjangoSetting
-# .. toggle_default: True
-# .. toggle_description: Enables logging of Datadog diagnostics information.
-# .. toggle_use_cases: circuit_breaker
-# .. toggle_creation_date: 2024-07-11
-# .. toggle_tickets: https://github.com/edx/edx-arch-experiments/issues/692
-DATADOG_DIAGNOSTICS_ENABLE = getattr(settings, 'DATADOG_DIAGNOSTICS_ENABLE', True)
-
-# .. setting_name: DATADOG_DIAGNOSTICS_MAX_SPANS
-# .. setting_default: 100
-# .. setting_description: Limit of how many spans to hold onto and log
-# when diagnosing Datadog tracing issues. This limits memory consumption
-# avoids logging more data than is actually needed for diagnosis.
-DATADOG_DIAGNOSTICS_MAX_SPANS = getattr(settings, 'DATADOG_DIAGNOSTICS_MAX_SPANS', 100)
-
-
-class MissingSpanProcessor:
- """Datadog span processor that logs unfinished spans at shutdown."""
-
- def __init__(self):
- self.spans_started = 0
- self.spans_finished = 0
- self.open_spans = {}
-
- def on_span_start(self, span):
- self.spans_started += 1
- if len(self.open_spans) < DATADOG_DIAGNOSTICS_MAX_SPANS:
- self.open_spans[span.span_id] = span
-
- def on_span_finish(self, span):
- self.spans_finished += 1
- self.open_spans.pop(span.span_id, None) # "delete if present"
-
- def shutdown(self, _timeout):
- log.info(f"Spans created = {self.spans_started}; spans finished = {self.spans_finished}")
- for span in self.open_spans.values():
- log.error(f"Span created but not finished: {span._pprint()}") # pylint: disable=protected-access
-
-
-class DatadogDiagnostics(AppConfig):
- """
- Django application to log diagnostic information for Datadog.
- """
- name = 'edx_arch_experiments.datadog_diagnostics'
-
- # Mark this as a plugin app
- plugin_app = {}
-
- def ready(self):
- if not DATADOG_DIAGNOSTICS_ENABLE:
- return
-
- try:
- from ddtrace import tracer # pylint: disable=import-outside-toplevel
- tracer._span_processors.append(MissingSpanProcessor()) # pylint: disable=protected-access
- log.info("Attached MissingSpanProcessor for Datadog diagnostics")
- except ImportError:
- log.warning(
- "Unable to attach MissingSpanProcessor for Datadog diagnostics"
- " -- ddtrace module not found."
- )
diff --git a/edx_arch_experiments/datadog_diagnostics/middleware.py b/edx_arch_experiments/datadog_diagnostics/middleware.py
deleted file mode 100644
index 844695c..0000000
--- a/edx_arch_experiments/datadog_diagnostics/middleware.py
+++ /dev/null
@@ -1,106 +0,0 @@
-"""
-Diagnostic middleware for Datadog.
-
-To use, install edx-arch-experiments and add
-``edx_arch_experiments.datadog_diagnostics.middleware.DatadogDiagnosticMiddleware``
-to ``MIDDLEWARE``, then set the below settings as needed.
-"""
-
-import logging
-import time
-
-from django.core.exceptions import MiddlewareNotUsed
-from edx_toggles.toggles import WaffleFlag
-
-log = logging.getLogger(__name__)
-
-# .. toggle_name: datadog.diagnostics.detect_anomalous_trace
-# .. toggle_implementation: WaffleFlag
-# .. toggle_default: False
-# .. toggle_description: Enables logging of anomalous Datadog traces for web requests.
-# .. toggle_warning: This is a noisy feature and so it should only be enabled
-# for a percentage of requests.
-# .. toggle_use_cases: temporary
-# .. toggle_creation_date: 2024-08-01
-# .. toggle_target_removal_date: 2024-11-01
-# .. toggle_tickets: https://github.com/edx/edx-arch-experiments/issues/692
-DETECT_ANOMALOUS_TRACE = WaffleFlag('datadog.diagnostics.detect_anomalous_trace', module_name=__name__)
-
-# .. toggle_name: datadog.diagnostics.log_root_span
-# .. toggle_implementation: WaffleFlag
-# .. toggle_default: False
-# .. toggle_description: Enables logging of Datadog root span IDs for web requests.
-# .. toggle_warning: This is a noisy feature and so it should only be enabled
-# for a percentage of requests.
-# .. toggle_use_cases: temporary
-# .. toggle_creation_date: 2024-07-24
-# .. toggle_target_removal_date: 2024-10-01
-# .. toggle_tickets: https://github.com/edx/edx-arch-experiments/issues/692
-LOG_ROOT_SPAN = WaffleFlag('datadog.diagnostics.log_root_span', module_name=__name__)
-
-
-# pylint: disable=missing-function-docstring
-class DatadogDiagnosticMiddleware:
- """
- Middleware to add diagnostic logging for Datadog.
-
- Best added early in the middleware stack.
-
- Only activates if ``ddtrace`` package is installed and
- ``datadog.diagnostics.log_root_span`` Waffle flag is enabled.
- """
- def __init__(self, get_response):
- self.get_response = get_response
- self.error = False
-
- try:
- from ddtrace import tracer # pylint: disable=import-outside-toplevel
- self.dd_tracer = tracer
- except ImportError:
- # If import fails, don't even load this middleware.
- raise MiddlewareNotUsed # pylint: disable=raise-missing-from
-
- self.worker_start_epoch = time.time()
-
- def __call__(self, request):
- return self.get_response(request)
-
- def process_view(self, request, _view_func, _view_args, _view_kwargs):
- try:
- self.log_diagnostics(request)
- except BaseException as e:
- # If there's an error, it will probably hit every request,
- # so let's just log it once.
- if not self.error:
- self.error = True
- log.error(
- "Encountered error in DatadogDiagnosticMiddleware "
- f"(suppressing further errors): {e!r}"
- )
-
- def log_diagnostics(self, request):
- """
- Contains all the actual logging logic.
- """
- local_root_span = self.dd_tracer.current_root_span()
-
- if DETECT_ANOMALOUS_TRACE.is_enabled():
- root_duration_s = local_root_span.duration
- if root_duration_s is not None:
- worker_run_time_s = time.time() - self.worker_start_epoch
- log.warning(
- f"Anomalous Datadog local root span (duration already set): "
- f"id = {local_root_span.trace_id:x}; "
- f"duration = {root_duration_s:0.3f} sec; "
- f"worker age = {worker_run_time_s:0.3f} sec"
- )
-
- if LOG_ROOT_SPAN.is_enabled():
- route_pattern = getattr(request.resolver_match, 'route', None)
- current_span = self.dd_tracer.current_span()
- # pylint: disable=protected-access
- log.info(
- f"Datadog span diagnostics: Route = {route_pattern}; "
- f"local root span = {local_root_span._pprint()}; "
- f"current span = {current_span._pprint()}"
- )
diff --git a/edx_arch_experiments/datadog_diagnostics/tests/__init__.py b/edx_arch_experiments/datadog_diagnostics/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/edx_arch_experiments/datadog_diagnostics/tests/test_app.py b/edx_arch_experiments/datadog_diagnostics/tests/test_app.py
index b0ce611..e69de29 100644
--- a/edx_arch_experiments/datadog_diagnostics/tests/test_app.py
+++ b/edx_arch_experiments/datadog_diagnostics/tests/test_app.py
@@ -1,51 +0,0 @@
-"""
-Tests for plugin app.
-"""
-
-from unittest.mock import patch
-
-from django.test import TestCase
-
-from .. import apps
-
-
-class FakeSpan:
- """A fake Span instance that just carries a span_id."""
- def __init__(self, span_id):
- self.span_id = span_id
-
- def _pprint(self):
- return f"span_id={self.span_id}"
-
-
-class TestMissingSpanProcessor(TestCase):
- """Tests for MissingSpanProcessor."""
-
- @patch.object(apps, 'DATADOG_DIAGNOSTICS_MAX_SPANS', new=3)
- def test_metrics(self):
- proc = apps.MissingSpanProcessor()
- ids = [2, 4, 6, 8, 10]
-
- for span_id in ids:
- proc.on_span_start(FakeSpan(span_id))
-
- assert {(sk, sv.span_id) for sk, sv in proc.open_spans.items()} == {(2, 2), (4, 4), (6, 6)}
- assert proc.spans_started == 5
- assert proc.spans_finished == 0
-
- for span_id in ids:
- proc.on_span_finish(FakeSpan(span_id))
-
- assert proc.open_spans.keys() == set()
- assert proc.spans_started == 5
- assert proc.spans_finished == 5
-
- @patch('edx_arch_experiments.datadog_diagnostics.apps.log.info')
- @patch('edx_arch_experiments.datadog_diagnostics.apps.log.error')
- def test_logging(self, mock_log_error, mock_log_info):
- proc = apps.MissingSpanProcessor()
- proc.on_span_start(FakeSpan(17))
- proc.shutdown(0)
-
- mock_log_info.assert_called_once_with("Spans created = 1; spans finished = 0")
- mock_log_error.assert_called_once_with("Span created but not finished: span_id=17")
diff --git a/edx_arch_experiments/datadog_diagnostics/tests/test_middleware.py b/edx_arch_experiments/datadog_diagnostics/tests/test_middleware.py
deleted file mode 100644
index 4e48619..0000000
--- a/edx_arch_experiments/datadog_diagnostics/tests/test_middleware.py
+++ /dev/null
@@ -1,110 +0,0 @@
-"""
-Tests for diagnostic middleware.
-"""
-
-import re
-from unittest.mock import Mock, patch
-
-import ddt
-import ddtrace
-from django.test import TestCase
-
-from ..middleware import DETECT_ANOMALOUS_TRACE, LOG_ROOT_SPAN, DatadogDiagnosticMiddleware
-
-
-def fake_view(_request):
- """Fake get_response for middleware."""
-
-
-@ddt.ddt
-class TestDatadogDiagnosticMiddleware(TestCase):
- """Tests for DatadogDiagnosticMiddleware."""
-
- def setUp(self):
- self.middleware = DatadogDiagnosticMiddleware(fake_view)
-
- def run_middleware(self):
- """Run the middleware using a fake request."""
- resolver = Mock()
- resolver.route = "/some/path"
- request = Mock()
- request.resolver_match = resolver
- self.middleware.process_view(request, None, None, None)
-
- @patch('edx_arch_experiments.datadog_diagnostics.middleware.log.error')
- def test_log_diagnostics_error_only_once(self, mock_log_error):
- """
- If the log_diagnostics function is broken, only log the error once.
- The method should still be called every time in case it is still doing
- useful work before the error, though.
- """
-
- bad_method = Mock(side_effect=lambda request: 1/0)
- self.middleware.log_diagnostics = bad_method
-
- self.run_middleware()
- self.run_middleware()
-
- # Called twice
- assert len(bad_method.call_args_list) == 2
-
- # But only log once
- mock_log_error.assert_called_once_with(
- "Encountered error in DatadogDiagnosticMiddleware (suppressing further errors): "
- "ZeroDivisionError('division by zero')"
- )
-
- @ddt.data(
- # Feature disabled
- (False, False),
- (False, True),
- # Enabled, but nothing anomalous
- (True, False),
- # Enabled and anomaly detected
- (True, True),
- )
- @ddt.unpack
- @patch('edx_arch_experiments.datadog_diagnostics.middleware.log.warning')
- def test_anomalous_trace(self, enabled, cause_anomaly, mock_log_warning):
- with (
- patch.object(DETECT_ANOMALOUS_TRACE, 'is_enabled', return_value=enabled),
- patch.object(LOG_ROOT_SPAN, 'is_enabled', return_value=False),
- # Need at least two levels of spans in order to fake
- # an anomaly. (Otherwise current_root_span returns None.)
- ddtrace.tracer.trace("test_local_root"),
- ddtrace.tracer.trace("inner_span"),
- ):
- if cause_anomaly:
- ddtrace.tracer.current_root_span().finish()
- self.run_middleware()
-
- if enabled and cause_anomaly:
- mock_log_warning.assert_called_once()
- log_msg = mock_log_warning.call_args_list[0][0][0] # first arg of first call
- assert re.fullmatch(
- r"Anomalous Datadog local root span \(duration already set\): "
- r"id = [0-9A-Fa-f]+; duration = [0-9]\.[0-9]{3} sec; worker age = [0-9]\.[0-9]{3} sec",
- log_msg
- )
- else:
- mock_log_warning.assert_not_called()
-
- @patch('edx_arch_experiments.datadog_diagnostics.middleware.log.info')
- def test_log_root_span(self, mock_log_info):
- with (
- patch.object(DETECT_ANOMALOUS_TRACE, 'is_enabled', return_value=False),
- patch.object(LOG_ROOT_SPAN, 'is_enabled', return_value=True),
- # Need at least two levels of spans for interesting logging
- ddtrace.tracer.trace("test_local_root"),
- ddtrace.tracer.trace("inner_span"),
- ):
- self.run_middleware()
-
- mock_log_info.assert_called_once()
- log_msg = mock_log_info.call_args_list[0][0][0] # first arg of first call
- assert re.fullmatch(
- r"Datadog span diagnostics: Route = /some/path; "
- r"local root span = name='test_local_root' .*; "
- r"current span = name='inner_span' .*",
- log_msg
- )
diff --git a/edx_arch_experiments/scripts/generate_code_owner_mappings.py b/edx_arch_experiments/scripts/generate_code_owner_mappings.py
index f1538ba..a80e6e6 100644
--- a/edx_arch_experiments/scripts/generate_code_owner_mappings.py
+++ b/edx_arch_experiments/scripts/generate_code_owner_mappings.py
@@ -31,6 +31,7 @@
'config_models': 'https://github.com/openedx/django-config-models',
'consent': 'https://github.com/openedx/edx-enterprise',
'csrf': 'https://github.com/openedx/edx-drf-extensions',
+ 'edx_arch_experiments': 'https://github.com/edx/edx-arch-experiments',
'edx_name_affirmation': 'https://github.com/edx/edx-name-affirmation',
'edx_proctoring': 'https://github.com/openedx/edx-proctoring',
'edx_recommendations': 'https://github.com/edx/edx-recommendations',
@@ -48,6 +49,7 @@
'openassessment': 'https://github.com/openedx/edx-ora2',
'ora2': 'https://github.com/openedx/edx-ora2',
'organizations': 'https://github.com/openedx/edx-organizations',
+ 'persona_integration': 'https://github.com/edx/persona-integration',
'search': 'https://github.com/openedx/edx-search',
'super_csv': 'https://github.com/openedx/super-csv',
'translatable_xblocks': 'https://github.com/edx/translatable-xblocks',
diff --git a/requirements/base.txt b/requirements/base.txt
index 049726c..17b4ae6 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -6,13 +6,13 @@
#
asgiref==3.8.1
# via django
-attrs==23.2.0
+attrs==24.2.0
# via
# jsonschema
# referencing
-certifi==2024.7.4
+certifi==2024.8.30
# via requests
-cffi==1.16.0
+cffi==1.17.1
# via
# cryptography
# pynacl
@@ -24,9 +24,9 @@ click==8.1.7
# edx-django-utils
code-annotations==1.8.0
# via edx-toggles
-cryptography==43.0.0
+cryptography==43.0.1
# via pyjwt
-django==4.2.14
+django==4.2.16
# via
# -c https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt
# -r requirements/base.in
@@ -63,13 +63,13 @@ edx-django-utils==5.15.0
# -r requirements/base.in
# edx-drf-extensions
# edx-toggles
-edx-drf-extensions==10.3.0
+edx-drf-extensions==10.4.0
# via -r requirements/base.in
-edx-opaque-keys==2.10.0
+edx-opaque-keys==2.11.0
# via edx-drf-extensions
edx-toggles==5.2.0
# via -r requirements/base.in
-idna==3.7
+idna==3.10
# via requests
jinja2==3.1.4
# via code-annotations
@@ -79,9 +79,9 @@ jsonschema-specifications==2023.12.1
# via jsonschema
markupsafe==2.1.5
# via jinja2
-newrelic==9.12.0
+newrelic==9.13.0
# via edx-django-utils
-pbr==6.0.0
+pbr==6.1.0
# via stevedore
psutil==6.0.0
# via edx-django-utils
@@ -91,13 +91,13 @@ pyjwt[crypto]==2.9.0
# via
# drf-jwt
# edx-drf-extensions
-pymongo==4.8.0
+pymongo==4.9.1
# via edx-opaque-keys
pynacl==1.5.0
# via edx-django-utils
python-slugify==8.0.4
# via code-annotations
-pyyaml==6.0.1
+pyyaml==6.0.2
# via code-annotations
referencing==0.35.1
# via
@@ -105,7 +105,7 @@ referencing==0.35.1
# jsonschema-specifications
requests==2.32.3
# via edx-drf-extensions
-rpds-py==0.19.1
+rpds-py==0.20.0
# via
# jsonschema
# referencing
@@ -115,7 +115,7 @@ six==1.16.0
# via edx-codejail
sqlparse==0.5.1
# via django
-stevedore==5.2.0
+stevedore==5.3.0
# via
# code-annotations
# edx-django-utils
@@ -124,9 +124,9 @@ text-unidecode==1.3
# via python-slugify
typing-extensions==4.12.2
# via edx-opaque-keys
-urllib3==2.2.2
+urllib3==2.2.3
# via requests
# The following packages are considered to be unsafe in a requirements file:
-setuptools==72.1.0
+setuptools==75.1.0
# via -r requirements/base.in
diff --git a/requirements/ci.txt b/requirements/ci.txt
index 564c0f5..3625d4c 100644
--- a/requirements/ci.txt
+++ b/requirements/ci.txt
@@ -4,7 +4,7 @@
#
# make upgrade
#
-cachetools==5.4.0
+cachetools==5.5.0
# via tox
chardet==5.2.0
# via tox
@@ -12,7 +12,7 @@ colorama==0.4.6
# via tox
distlib==0.3.8
# via virtualenv
-filelock==3.15.4
+filelock==3.16.1
# via
# tox
# virtualenv
@@ -20,15 +20,15 @@ packaging==24.1
# via
# pyproject-api
# tox
-platformdirs==4.2.2
+platformdirs==4.3.6
# via
# tox
# virtualenv
pluggy==1.5.0
# via tox
-pyproject-api==1.7.1
+pyproject-api==1.8.0
# via tox
-tox==4.16.0
+tox==4.20.0
# via -r requirements/ci.in
-virtualenv==20.26.3
+virtualenv==20.26.5
# via tox
diff --git a/requirements/dev.txt b/requirements/dev.txt
index 3606ea3..65ad589 100644
--- a/requirements/dev.txt
+++ b/requirements/dev.txt
@@ -13,38 +13,28 @@ astroid==3.2.4
# -r requirements/quality.txt
# pylint
# pylint-celery
-attrs==23.2.0
+attrs==24.2.0
# via
# -r requirements/quality.txt
- # cattrs
- # ddtrace
# jsonschema
# referencing
backports-tarfile==1.2.0
# via
# -r requirements/quality.txt
# jaraco-context
-build==1.2.1
+build==1.2.2
# via
# -r requirements/pip-tools.txt
# pip-tools
-bytecode==0.15.1
- # via
- # -r requirements/quality.txt
- # ddtrace
-cachetools==5.4.0
+cachetools==5.5.0
# via
# -r requirements/ci.txt
# tox
-cattrs==23.2.3
- # via
- # -r requirements/quality.txt
- # ddtrace
-certifi==2024.7.4
+certifi==2024.8.30
# via
# -r requirements/quality.txt
# requests
-cffi==1.16.0
+cffi==1.17.1
# via
# -r requirements/quality.txt
# cryptography
@@ -80,28 +70,18 @@ colorama==0.4.6
# via
# -r requirements/ci.txt
# tox
-coverage[toml]==7.6.0
+coverage[toml]==7.6.1
# via
# -r requirements/quality.txt
# pytest-cov
-cryptography==43.0.0
+cryptography==43.0.1
# via
# -r requirements/quality.txt
# pyjwt
# secretstorage
-ddsketch==3.0.1
- # via
- # -r requirements/quality.txt
- # ddtrace
ddt==1.7.2
# via -r requirements/quality.txt
-ddtrace==2.10.1
- # via -r requirements/quality.txt
-deprecated==1.2.14
- # via
- # -r requirements/quality.txt
- # opentelemetry-api
-diff-cover==9.1.1
+diff-cover==9.2.0
# via -r requirements/dev.in
dill==0.3.8
# via
@@ -111,7 +91,7 @@ distlib==0.3.8
# via
# -r requirements/ci.txt
# virtualenv
-django==4.2.14
+django==4.2.16
# via
# -c https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt
# -r requirements/quality.txt
@@ -158,37 +138,31 @@ edx-django-utils==5.15.0
# -r requirements/quality.txt
# edx-drf-extensions
# edx-toggles
-edx-drf-extensions==10.3.0
+edx-drf-extensions==10.4.0
# via -r requirements/quality.txt
-edx-i18n-tools==1.6.2
+edx-i18n-tools==1.6.3
# via -r requirements/dev.in
-edx-lint==5.3.7
+edx-lint==5.4.0
# via -r requirements/quality.txt
-edx-opaque-keys==2.10.0
+edx-opaque-keys==2.11.0
# via
# -r requirements/quality.txt
# edx-drf-extensions
edx-toggles==5.2.0
# via -r requirements/quality.txt
-envier==0.5.2
- # via
- # -r requirements/quality.txt
- # ddtrace
-filelock==3.15.4
+filelock==3.16.1
# via
# -r requirements/ci.txt
# tox
# virtualenv
-idna==3.7
+idna==3.10
# via
# -r requirements/quality.txt
# requests
-importlib-metadata==6.11.0
+importlib-metadata==8.4.0
# via
- # -c https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt
# -r requirements/quality.txt
# keyring
- # opentelemetry-api
# twine
iniconfig==2.0.0
# via
@@ -202,7 +176,7 @@ jaraco-classes==3.4.0
# via
# -r requirements/quality.txt
# keyring
-jaraco-context==5.3.0
+jaraco-context==6.0.1
# via
# -r requirements/quality.txt
# keyring
@@ -226,12 +200,16 @@ jsonschema-specifications==2023.12.1
# via
# -r requirements/quality.txt
# jsonschema
-keyring==25.2.1
+keyring==25.4.0
# via
# -r requirements/quality.txt
# twine
-lxml==5.2.2
- # via edx-i18n-tools
+lxml[html-clean,html_clean]==5.3.0
+ # via
+ # edx-i18n-tools
+ # lxml-html-clean
+lxml-html-clean==0.2.2
+ # via lxml
markdown-it-py==3.0.0
# via
# -r requirements/quality.txt
@@ -248,12 +226,12 @@ mdurl==0.1.2
# via
# -r requirements/quality.txt
# markdown-it-py
-more-itertools==10.3.0
+more-itertools==10.5.0
# via
# -r requirements/quality.txt
# jaraco-classes
# jaraco-functools
-newrelic==9.12.0
+newrelic==9.13.0
# via
# -r requirements/quality.txt
# edx-django-utils
@@ -261,10 +239,6 @@ nh3==0.2.18
# via
# -r requirements/quality.txt
# readme-renderer
-opentelemetry-api==1.26.0
- # via
- # -r requirements/quality.txt
- # ddtrace
packaging==24.1
# via
# -r requirements/ci.txt
@@ -276,7 +250,7 @@ packaging==24.1
# tox
path==16.16.0
# via edx-i18n-tools
-pbr==6.0.0
+pbr==6.1.0
# via
# -r requirements/quality.txt
# stevedore
@@ -286,7 +260,7 @@ pkginfo==1.10.0
# via
# -r requirements/quality.txt
# twine
-platformdirs==4.2.2
+platformdirs==4.3.6
# via
# -r requirements/ci.txt
# -r requirements/quality.txt
@@ -302,15 +276,11 @@ pluggy==1.5.0
# tox
polib==1.2.0
# via edx-i18n-tools
-protobuf==5.27.3
- # via
- # -r requirements/quality.txt
- # ddtrace
psutil==6.0.0
# via
# -r requirements/quality.txt
# edx-django-utils
-pycodestyle==2.12.0
+pycodestyle==2.12.1
# via -r requirements/quality.txt
pycparser==2.22
# via
@@ -329,7 +299,7 @@ pyjwt[crypto]==2.9.0
# -r requirements/quality.txt
# drf-jwt
# edx-drf-extensions
-pylint==3.2.6
+pylint==3.2.7
# via
# -r requirements/quality.txt
# edx-lint
@@ -349,7 +319,7 @@ pylint-plugin-utils==0.8.2
# -r requirements/quality.txt
# pylint-celery
# pylint-django
-pymongo==4.8.0
+pymongo==4.9.1
# via
# -r requirements/quality.txt
# edx-opaque-keys
@@ -357,7 +327,7 @@ pynacl==1.5.0
# via
# -r requirements/quality.txt
# edx-django-utils
-pyproject-api==1.7.1
+pyproject-api==1.8.0
# via
# -r requirements/ci.txt
# tox
@@ -366,20 +336,23 @@ pyproject-hooks==1.1.0
# -r requirements/pip-tools.txt
# build
# pip-tools
-pytest==8.3.2
+pytest==8.3.3
# via
# -r requirements/quality.txt
# pytest-cov
# pytest-django
+ # pytest-randomly
pytest-cov==5.0.0
# via -r requirements/quality.txt
-pytest-django==4.8.0
+pytest-django==4.9.0
+ # via -r requirements/quality.txt
+pytest-randomly==3.15.0
# via -r requirements/quality.txt
python-slugify==8.0.4
# via
# -r requirements/quality.txt
# code-annotations
-pyyaml==6.0.1
+pyyaml==6.0.2
# via
# -r requirements/quality.txt
# code-annotations
@@ -407,11 +380,11 @@ rfc3986==2.0.0
# via
# -r requirements/quality.txt
# twine
-rich==13.7.1
+rich==13.8.1
# via
# -r requirements/quality.txt
# twine
-rpds-py==0.19.1
+rpds-py==0.20.0
# via
# -r requirements/quality.txt
# jsonschema
@@ -427,8 +400,6 @@ semantic-version==2.10.0
six==1.16.0
# via
# -r requirements/quality.txt
- # ddsketch
- # ddtrace
# edx-codejail
# edx-lint
snowballstemmer==2.2.0
@@ -439,7 +410,7 @@ sqlparse==0.5.1
# via
# -r requirements/quality.txt
# django
-stevedore==5.2.0
+stevedore==5.3.0
# via
# -r requirements/quality.txt
# code-annotations
@@ -449,41 +420,32 @@ text-unidecode==1.3
# via
# -r requirements/quality.txt
# python-slugify
-tomlkit==0.13.0
+tomlkit==0.13.2
# via
# -r requirements/quality.txt
# pylint
-tox==4.16.0
+tox==4.20.0
# via -r requirements/ci.txt
twine==5.1.1
# via -r requirements/quality.txt
typing-extensions==4.12.2
# via
# -r requirements/quality.txt
- # ddtrace
# edx-opaque-keys
-urllib3==2.2.2
+urllib3==2.2.3
# via
# -r requirements/quality.txt
# requests
# twine
-virtualenv==20.26.3
+virtualenv==20.26.5
# via
# -r requirements/ci.txt
# tox
-wheel==0.43.0
+wheel==0.44.0
# via
# -r requirements/pip-tools.txt
# pip-tools
-wrapt==1.16.0
- # via
- # -r requirements/quality.txt
- # deprecated
-xmltodict==0.13.0
- # via
- # -r requirements/quality.txt
- # ddtrace
-zipp==3.19.2
+zipp==3.20.2
# via
# -r requirements/quality.txt
# importlib-metadata
@@ -493,7 +455,7 @@ pip==24.2
# via
# -r requirements/pip-tools.txt
# pip-tools
-setuptools==72.1.0
+setuptools==75.1.0
# via
# -r requirements/pip-tools.txt
# -r requirements/quality.txt
diff --git a/requirements/doc.in b/requirements/doc.in
index 690e8e1..9f6e84a 100644
--- a/requirements/doc.in
+++ b/requirements/doc.in
@@ -4,6 +4,6 @@
-r test.txt # Core and testing dependencies for this package
doc8 # reStructuredText style checker
-edx_sphinx_theme # edX theme for Sphinx output
+sphinx_book_theme # edX theme for Sphinx output
readme_renderer # Validates README.rst for usage on PyPI
Sphinx # Documentation builder
diff --git a/requirements/doc.txt b/requirements/doc.txt
index 5eac2f6..d45ba4a 100644
--- a/requirements/doc.txt
+++ b/requirements/doc.txt
@@ -4,34 +4,42 @@
#
# make upgrade
#
+accessible-pygments==0.0.5
+ # via pydata-sphinx-theme
alabaster==0.7.16
# via sphinx
asgiref==3.8.1
# via
# -r requirements/test.txt
# django
-attrs==23.2.0
+attrs==24.2.0
# via
# -r requirements/test.txt
- # cattrs
- # ddtrace
# jsonschema
# referencing
-babel==2.15.0
- # via sphinx
-bytecode==0.15.1
+babel==2.16.0
+ # via
+ # pydata-sphinx-theme
+ # sphinx
+beautifulsoup4==4.12.3
+ # via pydata-sphinx-theme
+billiard==4.2.0
# via
# -r requirements/test.txt
- # ddtrace
-cattrs==23.2.3
+ # celery
+bytecode==0.15.1
+
+bytecode==0.15.1
# via
# -r requirements/test.txt
# ddtrace
-certifi==2024.7.4
+celery==5.4.0
+ # via -r requirements/test.txt
+certifi==2024.8.30
# via
# -r requirements/test.txt
# requests
-cffi==1.16.0
+cffi==1.17.1
# via
# -r requirements/test.txt
# cryptography
@@ -49,30 +57,19 @@ code-annotations==1.8.0
# via
# -r requirements/test.txt
# edx-toggles
-coverage[toml]==7.6.0
+coverage[toml]==7.6.1
# via
# -r requirements/test.txt
# pytest-cov
-cryptography==43.0.0
+cryptography==43.0.1
# via
# -r requirements/test.txt
# pyjwt
-ddsketch==3.0.1
- # via
- # -r requirements/test.txt
- # ddtrace
ddt==1.7.2
# via -r requirements/test.txt
-ddtrace==2.10.1
- # via -r requirements/test.txt
-deprecated==1.2.14
- # via
- # -r requirements/test.txt
- # opentelemetry-api
-django==4.2.14
+django==4.2.16
# via
# -c https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt
- # -r requirements/test.txt
# django-crum
# django-waffle
# djangorestframework
@@ -100,11 +97,12 @@ dnspython==2.6.1
# via
# -r requirements/test.txt
# pymongo
-doc8==1.1.1
+doc8==1.1.2
# via -r requirements/doc.in
-docutils==0.19
+docutils==0.21.2
# via
# doc8
+ # pydata-sphinx-theme
# readme-renderer
# restructuredtext-lint
# sphinx
@@ -119,31 +117,28 @@ edx-django-utils==5.15.0
# -r requirements/test.txt
# edx-drf-extensions
# edx-toggles
-edx-drf-extensions==10.3.0
+edx-drf-extensions==10.4.0
# via -r requirements/test.txt
-edx-opaque-keys==2.10.0
+edx-opaque-keys==2.11.0
# via
# -r requirements/test.txt
# edx-drf-extensions
-edx-sphinx-theme==3.1.0
- # via -r requirements/doc.in
edx-toggles==5.2.0
# via -r requirements/test.txt
envier==0.5.2
# via
# -r requirements/test.txt
# ddtrace
-idna==3.7
+exceptiongroup==1.2.2
+ # via
+ # cattrs
+ # pytest
+idna==3.10
# via
# -r requirements/test.txt
# requests
imagesize==1.4.1
# via sphinx
-importlib-metadata==6.11.0
- # via
- # -c https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt
- # -r requirements/test.txt
- # opentelemetry-api
iniconfig==2.0.0
# via
# -r requirements/test.txt
@@ -163,22 +158,19 @@ markupsafe==2.1.5
# via
# -r requirements/test.txt
# jinja2
-newrelic==9.12.0
+newrelic==9.13.0
# via
# -r requirements/test.txt
# edx-django-utils
nh3==0.2.18
# via readme-renderer
-opentelemetry-api==1.26.0
- # via
- # -r requirements/test.txt
- # ddtrace
packaging==24.1
# via
# -r requirements/test.txt
+ # pydata-sphinx-theme
# pytest
# sphinx
-pbr==6.0.0
+pbr==6.1.0
# via
# -r requirements/test.txt
# stevedore
@@ -186,10 +178,6 @@ pluggy==1.5.0
# via
# -r requirements/test.txt
# pytest
-protobuf==5.27.3
- # via
- # -r requirements/test.txt
- # ddtrace
psutil==6.0.0
# via
# -r requirements/test.txt
@@ -198,9 +186,13 @@ pycparser==2.22
# via
# -r requirements/test.txt
# cffi
+pydata-sphinx-theme==0.15.4
+ # via sphinx-book-theme
pygments==2.18.0
# via
+ # accessible-pygments
# doc8
+ # pydata-sphinx-theme
# readme-renderer
# sphinx
pyjwt[crypto]==2.9.0
@@ -208,7 +200,7 @@ pyjwt[crypto]==2.9.0
# -r requirements/test.txt
# drf-jwt
# edx-drf-extensions
-pymongo==4.8.0
+pymongo==4.9.1
# via
# -r requirements/test.txt
# edx-opaque-keys
@@ -216,24 +208,27 @@ pynacl==1.5.0
# via
# -r requirements/test.txt
# edx-django-utils
-pytest==8.3.2
+pytest==8.3.3
# via
# -r requirements/test.txt
# pytest-cov
# pytest-django
+ # pytest-randomly
pytest-cov==5.0.0
# via -r requirements/test.txt
-pytest-django==4.8.0
+pytest-django==4.9.0
+ # via -r requirements/test.txt
+pytest-randomly==3.15.0
# via -r requirements/test.txt
python-slugify==8.0.4
# via
# -r requirements/test.txt
# code-annotations
-pyyaml==6.0.1
+pyyaml==6.0.2
# via
# -r requirements/test.txt
# code-annotations
-readme-renderer==43.0
+readme-renderer==44.0
# via -r requirements/doc.in
referencing==0.35.1
# via
@@ -247,7 +242,7 @@ requests==2.32.3
# sphinx
restructuredtext-lint==1.4.0
# via doc8
-rpds-py==0.19.1
+rpds-py==0.20.0
# via
# -r requirements/test.txt
# jsonschema
@@ -259,16 +254,18 @@ semantic-version==2.10.0
six==1.16.0
# via
# -r requirements/test.txt
- # ddsketch
- # ddtrace
# edx-codejail
- # edx-sphinx-theme
snowballstemmer==2.2.0
# via sphinx
+soupsieve==2.5
+ # via beautifulsoup4
sphinx==5.3.0
# via
# -r requirements/doc.in
- # edx-sphinx-theme
+ # pydata-sphinx-theme
+ # sphinx-book-theme
+sphinx-book-theme==1.1.3
+ # via -r requirements/doc.in
sphinxcontrib-applehelp==2.0.0
# via sphinx
sphinxcontrib-devhelp==2.0.0
@@ -285,7 +282,7 @@ sqlparse==0.5.1
# via
# -r requirements/test.txt
# django
-stevedore==5.2.0
+stevedore==5.3.0
# via
# -r requirements/test.txt
# code-annotations
@@ -296,28 +293,33 @@ text-unidecode==1.3
# via
# -r requirements/test.txt
# python-slugify
+tomli==2.0.1
+ # via
+ # coverage
+ # doc8
+ # pytest
typing-extensions==4.12.2
# via
# -r requirements/test.txt
+ # asgiref
+ # bytecode
+ # cattrs
# ddtrace
# edx-opaque-keys
-urllib3==2.2.2
- # via
- # -r requirements/test.txt
- # requests
-wrapt==1.16.0
- # via
- # -r requirements/test.txt
- # deprecated
-xmltodict==0.13.0
+
+ # pydata-sphinx-theme
+tzdata==2024.1
# via
# -r requirements/test.txt
- # ddtrace
-zipp==3.19.2
+ # celery
+ # kombu
+urllib3==2.2.3
# via
# -r requirements/test.txt
- # importlib-metadata
+ # requests
# The following packages are considered to be unsafe in a requirements file:
-setuptools==72.1.0
- # via -r requirements/test.txt
+setuptools==75.1.0
+ # via
+ # -r requirements/test.txt
+ # sphinx
diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt
index b0c1866..49831ac 100644
--- a/requirements/pip-tools.txt
+++ b/requirements/pip-tools.txt
@@ -4,7 +4,7 @@
#
# make upgrade
#
-build==1.2.1
+build==1.2.2
# via pip-tools
click==8.1.7
# via pip-tools
@@ -16,11 +16,11 @@ pyproject-hooks==1.1.0
# via
# build
# pip-tools
-wheel==0.43.0
+wheel==0.44.0
# via pip-tools
# The following packages are considered to be unsafe in a requirements file:
pip==24.2
# via pip-tools
-setuptools==72.1.0
+setuptools==75.1.0
# via pip-tools
diff --git a/requirements/pip.txt b/requirements/pip.txt
index 54b0571..36c777e 100644
--- a/requirements/pip.txt
+++ b/requirements/pip.txt
@@ -4,11 +4,11 @@
#
# make upgrade
#
-wheel==0.43.0
+wheel==0.44.0
# via -r requirements/pip.in
# The following packages are considered to be unsafe in a requirements file:
pip==24.2
# via -r requirements/pip.in
-setuptools==72.1.0
+setuptools==75.1.0
# via -r requirements/pip.in
diff --git a/requirements/quality.txt b/requirements/quality.txt
index e10c684..bc99982 100644
--- a/requirements/quality.txt
+++ b/requirements/quality.txt
@@ -12,28 +12,18 @@ astroid==3.2.4
# via
# pylint
# pylint-celery
-attrs==23.2.0
+attrs==24.2.0
# via
# -r requirements/test.txt
- # cattrs
- # ddtrace
# jsonschema
# referencing
backports-tarfile==1.2.0
# via jaraco-context
-bytecode==0.15.1
- # via
- # -r requirements/test.txt
- # ddtrace
-cattrs==23.2.3
- # via
- # -r requirements/test.txt
- # ddtrace
-certifi==2024.7.4
+certifi==2024.8.30
# via
# -r requirements/test.txt
# requests
-cffi==1.16.0
+cffi==1.17.1
# via
# -r requirements/test.txt
# cryptography
@@ -56,30 +46,20 @@ code-annotations==1.8.0
# -r requirements/test.txt
# edx-lint
# edx-toggles
-coverage[toml]==7.6.0
+coverage[toml]==7.6.1
# via
# -r requirements/test.txt
# pytest-cov
-cryptography==43.0.0
+cryptography==43.0.1
# via
# -r requirements/test.txt
# pyjwt
# secretstorage
-ddsketch==3.0.1
- # via
- # -r requirements/test.txt
- # ddtrace
ddt==1.7.2
# via -r requirements/test.txt
-ddtrace==2.10.1
- # via -r requirements/test.txt
-deprecated==1.2.14
- # via
- # -r requirements/test.txt
- # opentelemetry-api
dill==0.3.8
# via pylint
-django==4.2.14
+django==4.2.16
# via
# -c https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt
# -r requirements/test.txt
@@ -123,30 +103,23 @@ edx-django-utils==5.15.0
# -r requirements/test.txt
# edx-drf-extensions
# edx-toggles
-edx-drf-extensions==10.3.0
+edx-drf-extensions==10.4.0
# via -r requirements/test.txt
-edx-lint==5.3.7
+edx-lint==5.4.0
# via -r requirements/quality.in
-edx-opaque-keys==2.10.0
+edx-opaque-keys==2.11.0
# via
# -r requirements/test.txt
# edx-drf-extensions
edx-toggles==5.2.0
# via -r requirements/test.txt
-envier==0.5.2
- # via
- # -r requirements/test.txt
- # ddtrace
-idna==3.7
+idna==3.10
# via
# -r requirements/test.txt
# requests
-importlib-metadata==6.11.0
+importlib-metadata==8.4.0
# via
- # -c https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt
- # -r requirements/test.txt
# keyring
- # opentelemetry-api
# twine
iniconfig==2.0.0
# via
@@ -158,7 +131,7 @@ isort==5.13.2
# pylint
jaraco-classes==3.4.0
# via keyring
-jaraco-context==5.3.0
+jaraco-context==6.0.1
# via keyring
jaraco-functools==4.0.2
# via keyring
@@ -176,7 +149,7 @@ jsonschema-specifications==2023.12.1
# via
# -r requirements/test.txt
# jsonschema
-keyring==25.2.1
+keyring==25.4.0
# via twine
markdown-it-py==3.0.0
# via rich
@@ -188,45 +161,37 @@ mccabe==0.7.0
# via pylint
mdurl==0.1.2
# via markdown-it-py
-more-itertools==10.3.0
+more-itertools==10.5.0
# via
# jaraco-classes
# jaraco-functools
-newrelic==9.12.0
+newrelic==9.13.0
# via
# -r requirements/test.txt
# edx-django-utils
nh3==0.2.18
# via readme-renderer
-opentelemetry-api==1.26.0
- # via
- # -r requirements/test.txt
- # ddtrace
packaging==24.1
# via
# -r requirements/test.txt
# pytest
-pbr==6.0.0
+pbr==6.1.0
# via
# -r requirements/test.txt
# stevedore
pkginfo==1.10.0
# via twine
-platformdirs==4.2.2
+platformdirs==4.3.6
# via pylint
pluggy==1.5.0
# via
# -r requirements/test.txt
# pytest
-protobuf==5.27.3
- # via
- # -r requirements/test.txt
- # ddtrace
psutil==6.0.0
# via
# -r requirements/test.txt
# edx-django-utils
-pycodestyle==2.12.0
+pycodestyle==2.12.1
# via -r requirements/quality.in
pycparser==2.22
# via
@@ -243,7 +208,7 @@ pyjwt[crypto]==2.9.0
# -r requirements/test.txt
# drf-jwt
# edx-drf-extensions
-pylint==3.2.6
+pylint==3.2.7
# via
# edx-lint
# pylint-celery
@@ -257,7 +222,7 @@ pylint-plugin-utils==0.8.2
# via
# pylint-celery
# pylint-django
-pymongo==4.8.0
+pymongo==4.9.1
# via
# -r requirements/test.txt
# edx-opaque-keys
@@ -265,20 +230,23 @@ pynacl==1.5.0
# via
# -r requirements/test.txt
# edx-django-utils
-pytest==8.3.2
+pytest==8.3.3
# via
# -r requirements/test.txt
# pytest-cov
# pytest-django
+ # pytest-randomly
pytest-cov==5.0.0
# via -r requirements/test.txt
-pytest-django==4.8.0
+pytest-django==4.9.0
+ # via -r requirements/test.txt
+pytest-randomly==3.15.0
# via -r requirements/test.txt
python-slugify==8.0.4
# via
# -r requirements/test.txt
# code-annotations
-pyyaml==6.0.1
+pyyaml==6.0.2
# via
# -r requirements/test.txt
# code-annotations
@@ -299,9 +267,9 @@ requests-toolbelt==1.0.0
# via twine
rfc3986==2.0.0
# via twine
-rich==13.7.1
+rich==13.8.1
# via twine
-rpds-py==0.19.1
+rpds-py==0.20.0
# via
# -r requirements/test.txt
# jsonschema
@@ -315,8 +283,6 @@ semantic-version==2.10.0
six==1.16.0
# via
# -r requirements/test.txt
- # ddsketch
- # ddtrace
# edx-codejail
# edx-lint
snowballstemmer==2.2.0
@@ -325,7 +291,7 @@ sqlparse==0.5.1
# via
# -r requirements/test.txt
# django
-stevedore==5.2.0
+stevedore==5.3.0
# via
# -r requirements/test.txt
# code-annotations
@@ -335,33 +301,22 @@ text-unidecode==1.3
# via
# -r requirements/test.txt
# python-slugify
-tomlkit==0.13.0
+tomlkit==0.13.2
# via pylint
twine==5.1.1
# via -r requirements/quality.in
typing-extensions==4.12.2
# via
# -r requirements/test.txt
- # ddtrace
# edx-opaque-keys
-urllib3==2.2.2
+urllib3==2.2.3
# via
# -r requirements/test.txt
# requests
# twine
-wrapt==1.16.0
- # via
- # -r requirements/test.txt
- # deprecated
-xmltodict==0.13.0
- # via
- # -r requirements/test.txt
- # ddtrace
-zipp==3.19.2
- # via
- # -r requirements/test.txt
- # importlib-metadata
+zipp==3.20.2
+ # via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
-setuptools==72.1.0
+setuptools==75.1.0
# via -r requirements/test.txt
diff --git a/requirements/scripts.txt b/requirements/scripts.txt
index c7740dd..e698b69 100644
--- a/requirements/scripts.txt
+++ b/requirements/scripts.txt
@@ -8,19 +8,19 @@ asgiref==3.8.1
# via
# -r requirements/base.txt
# django
-attrs==23.2.0
+attrs==24.2.0
# via
# -r requirements/base.txt
# jsonschema
# openedx-events
# referencing
-avro==1.11.3
+avro==1.12.0
# via confluent-kafka
-certifi==2024.7.4
+certifi==2024.8.30
# via
# -r requirements/base.txt
# requests
-cffi==1.16.0
+cffi==1.17.1
# via
# -r requirements/base.txt
# cryptography
@@ -38,13 +38,13 @@ code-annotations==1.8.0
# via
# -r requirements/base.txt
# edx-toggles
-confluent-kafka[avro]==2.5.0
+confluent-kafka[avro]==2.5.3
# via -r requirements/scripts.in
-cryptography==43.0.0
+cryptography==43.0.1
# via
# -r requirements/base.txt
# pyjwt
-django==4.2.14
+django==4.2.16
# via
# -c https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt
# -r requirements/base.txt
@@ -92,11 +92,11 @@ edx-django-utils==5.15.0
# edx-event-bus-kafka
# edx-toggles
# openedx-events
-edx-drf-extensions==10.3.0
+edx-drf-extensions==10.4.0
# via -r requirements/base.txt
-edx-event-bus-kafka==5.8.0
+edx-event-bus-kafka==5.8.1
# via -r requirements/scripts.in
-edx-opaque-keys[django]==2.10.0
+edx-opaque-keys[django]==2.11.0
# via
# -r requirements/base.txt
# edx-ccx-keys
@@ -106,11 +106,11 @@ edx-toggles==5.2.0
# via
# -r requirements/base.txt
# edx-event-bus-kafka
-fastavro==1.9.5
+fastavro==1.9.7
# via
# confluent-kafka
# openedx-events
-idna==3.7
+idna==3.10
# via
# -r requirements/base.txt
# requests
@@ -128,13 +128,13 @@ markupsafe==2.1.5
# via
# -r requirements/base.txt
# jinja2
-newrelic==9.12.0
+newrelic==9.13.0
# via
# -r requirements/base.txt
# edx-django-utils
-openedx-events==9.11.0
+openedx-events==9.14.1
# via edx-event-bus-kafka
-pbr==6.0.0
+pbr==6.1.0
# via
# -r requirements/base.txt
# stevedore
@@ -151,7 +151,7 @@ pyjwt[crypto]==2.9.0
# -r requirements/base.txt
# drf-jwt
# edx-drf-extensions
-pymongo==4.8.0
+pymongo==4.9.1
# via
# -r requirements/base.txt
# edx-opaque-keys
@@ -163,7 +163,7 @@ python-slugify==8.0.4
# via
# -r requirements/base.txt
# code-annotations
-pyyaml==6.0.1
+pyyaml==6.0.2
# via
# -r requirements/base.txt
# code-annotations
@@ -177,7 +177,7 @@ requests==2.32.3
# -r requirements/base.txt
# confluent-kafka
# edx-drf-extensions
-rpds-py==0.19.1
+rpds-py==0.20.0
# via
# -r requirements/base.txt
# jsonschema
@@ -195,7 +195,7 @@ sqlparse==0.5.1
# via
# -r requirements/base.txt
# django
-stevedore==5.2.0
+stevedore==5.3.0
# via
# -r requirements/base.txt
# code-annotations
@@ -209,11 +209,11 @@ typing-extensions==4.12.2
# via
# -r requirements/base.txt
# edx-opaque-keys
-urllib3==2.2.2
+urllib3==2.2.3
# via
# -r requirements/base.txt
# requests
# The following packages are considered to be unsafe in a requirements file:
-setuptools==72.1.0
+setuptools==75.1.0
# via -r requirements/base.txt
diff --git a/requirements/test.in b/requirements/test.in
index 9974b96..37a4119 100644
--- a/requirements/test.in
+++ b/requirements/test.in
@@ -5,6 +5,6 @@
pytest-cov # pytest extension for code coverage statistics
pytest-django # pytest extension for better Django support
+pytest-randomly # pytest extension for discovering order-sensitive tests
code-annotations # provides commands used by the pii_check make target.
ddt # data-driven tests
-ddtrace # Required for testing datadog_diagnostics app and middleware
diff --git a/requirements/test.txt b/requirements/test.txt
index 3d2ee70..94c920d 100644
--- a/requirements/test.txt
+++ b/requirements/test.txt
@@ -8,22 +8,16 @@ asgiref==3.8.1
# via
# -r requirements/base.txt
# django
-attrs==23.2.0
+attrs==24.2.0
# via
# -r requirements/base.txt
- # cattrs
- # ddtrace
# jsonschema
# referencing
-bytecode==0.15.1
- # via ddtrace
-cattrs==23.2.3
- # via ddtrace
-certifi==2024.7.4
+certifi==2024.8.30
# via
# -r requirements/base.txt
# requests
-cffi==1.16.0
+cffi==1.17.1
# via
# -r requirements/base.txt
# cryptography
@@ -42,20 +36,14 @@ code-annotations==1.8.0
# -r requirements/base.txt
# -r requirements/test.in
# edx-toggles
-coverage[toml]==7.6.0
+coverage[toml]==7.6.1
# via pytest-cov
-cryptography==43.0.0
+cryptography==43.0.1
# via
# -r requirements/base.txt
# pyjwt
-ddsketch==3.0.1
- # via ddtrace
ddt==1.7.2
# via -r requirements/test.in
-ddtrace==2.10.1
- # via -r requirements/test.in
-deprecated==1.2.14
- # via opentelemetry-api
# via
# -c https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt
# -r requirements/base.txt
@@ -97,24 +85,18 @@ edx-django-utils==5.15.0
# -r requirements/base.txt
# edx-drf-extensions
# edx-toggles
-edx-drf-extensions==10.3.0
+edx-drf-extensions==10.4.0
# via -r requirements/base.txt
-edx-opaque-keys==2.10.0
+edx-opaque-keys==2.11.0
# via
# -r requirements/base.txt
# edx-drf-extensions
edx-toggles==5.2.0
# via -r requirements/base.txt
-envier==0.5.2
- # via ddtrace
-idna==3.7
+idna==3.10
# via
# -r requirements/base.txt
# requests
-importlib-metadata==6.11.0
- # via
- # -c https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt
- # opentelemetry-api
iniconfig==2.0.0
# via pytest
jinja2==3.1.4
@@ -131,22 +113,18 @@ markupsafe==2.1.5
# via
# -r requirements/base.txt
# jinja2
-newrelic==9.12.0
+newrelic==9.13.0
# via
# -r requirements/base.txt
# edx-django-utils
-opentelemetry-api==1.26.0
- # via ddtrace
packaging==24.1
# via pytest
-pbr==6.0.0
+pbr==6.1.0
# via
# -r requirements/base.txt
# stevedore
pluggy==1.5.0
# via pytest
-protobuf==5.27.3
- # via ddtrace
psutil==6.0.0
# via
# -r requirements/base.txt
@@ -160,7 +138,7 @@ pyjwt[crypto]==2.9.0
# -r requirements/base.txt
# drf-jwt
# edx-drf-extensions
-pymongo==4.8.0
+pymongo==4.9.1
# via
# -r requirements/base.txt
# edx-opaque-keys
@@ -168,19 +146,22 @@ pynacl==1.5.0
# via
# -r requirements/base.txt
# edx-django-utils
-pytest==8.3.2
+pytest==8.3.3
# via
# pytest-cov
# pytest-django
+ # pytest-randomly
pytest-cov==5.0.0
# via -r requirements/test.in
-pytest-django==4.8.0
+pytest-django==4.9.0
+ # via -r requirements/test.in
+pytest-randomly==3.15.0
# via -r requirements/test.in
python-slugify==8.0.4
# via
# -r requirements/base.txt
# code-annotations
-pyyaml==6.0.1
+pyyaml==6.0.2
# via
# -r requirements/base.txt
# code-annotations
@@ -193,7 +174,7 @@ requests==2.32.3
# via
# -r requirements/base.txt
# edx-drf-extensions
-rpds-py==0.19.1
+rpds-py==0.20.0
# via
# -r requirements/base.txt
# jsonschema
@@ -205,14 +186,12 @@ semantic-version==2.10.0
six==1.16.0
# via
# -r requirements/base.txt
- # ddsketch
- # ddtrace
# edx-codejail
sqlparse==0.5.1
# via
# -r requirements/base.txt
# django
-stevedore==5.2.0
+stevedore==5.3.0
# via
# -r requirements/base.txt
# code-annotations
@@ -225,19 +204,12 @@ text-unidecode==1.3
typing-extensions==4.12.2
# via
# -r requirements/base.txt
- # ddtrace
# edx-opaque-keys
-urllib3==2.2.2
+urllib3==2.2.3
# via
# -r requirements/base.txt
# requests
-wrapt==1.16.0
- # via deprecated
-xmltodict==0.13.0
- # via ddtrace
-zipp==3.19.2
- # via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
-setuptools==72.1.0
+setuptools==75.1.0
# via -r requirements/base.txt
diff --git a/setup.py b/setup.py
index bc11b14..3b29fa9 100644
--- a/setup.py
+++ b/setup.py
@@ -164,7 +164,6 @@ def is_requirement(line):
"arch_experiments = edx_arch_experiments.apps:EdxArchExperimentsConfig",
"config_watcher = edx_arch_experiments.config_watcher.apps:ConfigWatcher",
"codejail_service = edx_arch_experiments.codejail_service.apps:CodejailService",
- "datadog_diagnostics = edx_arch_experiments.datadog_diagnostics.apps:DatadogDiagnostics",
],
"cms.djangoapp": [
"config_watcher = edx_arch_experiments.config_watcher.apps:ConfigWatcher",
diff --git a/tox.ini b/tox.ini
index 096d3f0..828c25a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -31,7 +31,7 @@ match-dir = (?!migrations)
[pytest]
DJANGO_SETTINGS_MODULE = test_settings
-addopts = --cov edx_arch_experiments --cov-report term-missing --cov-report xml
+addopts = -p randomly --cov edx_arch_experiments --cov-report term-missing --cov-report xml
norecursedirs = .* requirements site-packages
[testenv]