diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6dac20dc..130d147f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: matrix: os: [ubuntu-latest] python-version: ['3.12'] - toxenv: [django42, django52, quality] + toxenv: [django52, quality] steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 @@ -36,55 +36,9 @@ jobs: run: tox - name: Run Coverage - if: matrix.python-version == '3.12' && matrix.toxenv=='django42' - uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5.5.4 + if: matrix.python-version == '3.12' && matrix.toxenv=='django52' + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: flags: unittests fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} - - - provider-verification: - name: Pact Provider Verification - runs-on: ubuntu-latest - needs: run_tests - continue-on-error: true # PACT_FLOW_ACCESS_TOKEN secret must be configured for this to pass - - steps: - - name: Checkout code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - - - name: setup python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 - with: - python-version: 3.12 - - - name: Install pip - run: pip install -r requirements/pip.txt - - - name: Install Dependencies - run: | - pip install "Django>=4.2,<5.0" - pip install -r requirements/ci.txt - pip install -r requirements/test.txt - - - name: Verify Pacts - run: | - export PACT_BROKER_TOKEN=${{ secrets.PACT_FLOW_ACCESS_TOKEN }} - if [ -z "$PACT_BROKER_TOKEN" ]; then - echo "PACT_FLOW_ACCESS_TOKEN secret not configured, skipping Pact verification." - exit 0 - fi - export IS_MERGED=${{ github.event.pull_request.merged }} - export PACT_BROKER_BASE_URL='https://edx.pactflow.io' - export PUBLISH_VERSION=`git rev-parse --short HEAD` - if [ $IS_MERGED == false ] - then - export PUBLISH_TAGS=$GITHUB_HEAD_REF - export GIT_ENV='development' - else - export PUBLISH_TAGS=${GITHUB_REF:11} - export GIT_ENV='production' - fi - export PUBLISH_VERIFICATION_RESULTS=true - pytest -s edxval/pacts/verify_pact.py --ds=edxval.settings.pact diff --git a/.github/workflows/verify_changed_contract.yml b/.github/workflows/verify_changed_contract.yml deleted file mode 100644 index dfe635c0..00000000 --- a/.github/workflows/verify_changed_contract.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Verify contract changed by a consumer - -on: - repository_dispatch: - types: - - contract_changed - -env: - CHANGED_PACT_URL: ${{ github.event.client_payload.pact_url }} - GIT_ENV: Production - PACT_BROKER_TOKEN: ${{ secrets.PACT_FLOW_ACCESS_TOKEN }} - PUBLISH_VERIFICATION_RESULTS: true - VERIFY_WITH_BROKER: false - -jobs: - changed-contract-verification: - name: Pact Provider Verification for a changed contract - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - - - name: setup python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 - with: - python-version: 3.12 - - - name: Install pip - run: pip install -r requirements/pip.txt - - - name: Install Dependencies - run: | - pip install -r requirements/ci.txt - pip install -r requirements/test.txt - - - name: Verify Changed Contract - run: | - export PUBLISH_VERSION=`git rev-parse --short HEAD` - export PUBLISH_TAGS=${GITHUB_REF:11} - export GIT_ENV='production' - pytest -s edxval/pacts/verify_pact.py --ds=edxval.settings.pact \ No newline at end of file diff --git a/edxval/__init__.py b/edxval/__init__.py index d05eb3c0..96b7b278 100644 --- a/edxval/__init__.py +++ b/edxval/__init__.py @@ -2,4 +2,4 @@ init """ -__version__ = '4.0.1' +__version__ = '5.0.0' diff --git a/edxval/pacts/README.md b/edxval/pacts/README.md deleted file mode 100644 index fd04f87f..00000000 --- a/edxval/pacts/README.md +++ /dev/null @@ -1,13 +0,0 @@ -### Description -This readme contains the description of different files in the current directory. - -* middleware.py: This contains an authentication middleware that adds an authenticated user to the requests that are made while running provider verification. -* views.py: This will have provider state setup view which is hit during provider verification to setup appropriate DB state per interaction -* utils.py: Different DB utilities used by views.py -* video-encode-manager-edx-val.json: The only pact file is a duplicate of pact file from https://github.com/edx/video-encode-manager/blob/a4f4c12db0c3919858df1e2fa58ee74071bc264a/encode_manager/apps/core/tests/pact_tests/pacts/video-encode-manager-edx-val.json. This is temporarily needed until pact broker can be setup. Until then, any update in the original pact should be ported in the json in VAL. -* verify_pact.py: Runs the provider verification against the pact. Use either `DJANGO_SETTINGS_MODULE=edxval.settings.pact pytest -s edxval/pacts/verify_pact.py` or `pytest -s edxval/pacts/verify_pact.py --ds=edxval.settings.pact` commands to run the verification. - There are 3 instances of running the verification: - * **Verify with broker**: By default, the verification is done against the broker. - * **Changed Pact's Verification**: For this verification, `VERIFY_WITH_BROKER` environment variable should be set to False and `CHANGED_PACT_URL` should point to a valid pact. - * **Local JSON Pact**: Similar to Changed Pact Verification. Alternatively, if only `VERIFY_WITH_BROKER` is set to False, the pact named video-encode-manager-edx-val.json will be verified. - \ No newline at end of file diff --git a/edxval/pacts/__init__.py b/edxval/pacts/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/edxval/pacts/middleware.py b/edxval/pacts/middleware.py deleted file mode 100644 index f04d7bbf..00000000 --- a/edxval/pacts/middleware.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -Contain the middleware logic needed during pact verification -""" -from django.contrib import auth -from django.contrib.auth.models import Permission -from django.utils.deprecation import MiddlewareMixin - -User = auth.get_user_model() - - -class AuthenticationMiddleware(MiddlewareMixin): - """ - Middleware to add default authentication into the requests for pact verification. - - This middleware is required to add a default authenticated user and bypass CSRF validation - into the requests during the pact verification workflow. Without the authentication, the pact verification - process will not work as the apis. - See https://docs.pact.io/faq#how-do-i-test-oauth-or-other-security-headers - """ - - def __init__(self, get_response): - super().__init__(get_response) - self.auth_user = User.objects.get_or_create(username='edx', is_staff=True)[0] - self.auth_user.user_permissions.set(Permission.objects.filter(content_type__app_label='edxval')) - - def process_view(self, request, view_func, view_args, view_kwargs): # pylint: disable=unused-argument - """ - Add a default authenticated user and remove CSRF checks for a request - in a subset of views. - """ - if request.user.is_anonymous and 'Pact-Authentication' in request.headers: - request.user = self.auth_user - request._dont_enforce_csrf_checks = True # pylint: disable=protected-access diff --git a/edxval/pacts/utils.py b/edxval/pacts/utils.py deleted file mode 100644 index e171b9f4..00000000 --- a/edxval/pacts/utils.py +++ /dev/null @@ -1,65 +0,0 @@ -""" -Utility methods needed during pact verification. -""" - -from edxval.models import CourseVideo, EncodedVideo, Profile, Video, VideoImage, VideoTranscript -from edxval.tests import constants - -VIDEO_ID = "3386eda1-8d6e-439d-tb89-e90a5c52h103" -COURSE_ID = "course-v1:testX+test123+2030" -DEFAULT_PROFILE_NAMES = ['desktop_mp4', 'mobile_low', 'mp3', 'hls'] - - -def clear_database(): - """ - Helper method to clear the database before a pact interaction - to make sure that no existing data causes issue during pact verification. - """ - CourseVideo.objects.filter(course_id=COURSE_ID, video__edx_video_id=VIDEO_ID).delete() - Profile.objects.filter(profile_name__in=DEFAULT_PROFILE_NAMES).delete() - Video.objects.filter(edx_video_id=VIDEO_ID).delete() - EncodedVideo.objects.filter(video__edx_video_id=VIDEO_ID).delete() - VideoImage.objects.filter(course_video__video__edx_video_id=VIDEO_ID).delete() - VideoTranscript.objects.filter(video__edx_video_id=VIDEO_ID).delete() - - -def setup_successful_video_details_state(): - """ - Setup the provider state for successful video details update call. - """ - create_course_video() - create_profiles() - - -def setup_unsuccessful_video_transcripts_state(): - """ - Setup the provider state for unsuccessful video transcripts update call. - """ - video = create_video() - VideoTranscript.objects.create(video=video, language_code='en', provider='3PlayMedia', file_format='sjson') - - -def create_video(): - """ - Creates and return a new video object with pre-defined data. - """ - data_dict = {** constants.VIDEO_DICT_FISH, 'edx_video_id': VIDEO_ID} - return Video.objects.create(**data_dict) - - -def create_profiles(): - """ - Create and return a list of default profiles created. - """ - profiles = [] - for profile_name in DEFAULT_PROFILE_NAMES: - profiles.append(Profile.objects.create(profile_name=profile_name)) - return profiles - - -def create_course_video(): - """ - Creates and return a new video object with pre-defined data. - """ - video = create_video() - return CourseVideo.objects.create(course_id=COURSE_ID, video=video) diff --git a/edxval/pacts/verify_pact.py b/edxval/pacts/verify_pact.py deleted file mode 100644 index b6ef852e..00000000 --- a/edxval/pacts/verify_pact.py +++ /dev/null @@ -1,74 +0,0 @@ -"""Pact verifier with Live server test case""" - -import logging -import os - -from django.conf import settings -from django.test import LiveServerTestCase -from django.urls import reverse - -from pact import Verifier - -log = logging.getLogger(__name__) -PACT_DIR = os.path.dirname(os.path.realpath(__file__)) -PACT_FILE = "video-encode-manager-edx-val.json" - - -class ProviderVerificationServer(LiveServerTestCase): - """ Execute the provider verification on the consumer pacts """ - - PACT_DEFAULT_CONFIG = { - 'enable_pending': True, - 'headers': ['Pact-Authentication: AllowAny', ], - 'verbose': False, - 'publish_version': settings.PUBLISH_VERSION, - 'provider_tags': [settings.PUBLISH_TAGS, settings.GIT_ENV], - 'publish_verification_results': settings.PUBLISH_VERIFICATION_RESULTS, - 'verify_with_broker': settings.VERIFY_WITH_BROKER, - } - - PACT_BROKER_CONFIG = { - 'broker_url': settings.PACT_BROKER_BASE_URL, - 'consumer_version_selectors': [ - {'tag': 'production', 'latest': True}, - {"tag": "master", "latest": True}, - ], - **PACT_DEFAULT_CONFIG - } - - @classmethod - def setUpClass(cls): - super().setUpClass() - - cls.verifier = Verifier( - provider='edx-val', - provider_base_url=cls.live_server_url, - ) - - @classmethod - def tearDownClass(cls): - super().tearDownClass() - - def test_verify_pact(self): - """ - Run provider verification either using pact broker or local pact. - - * If VERIFY_WITH_BROKER environment variable is set, broker config will be used to run verification - of pacts on broker. - * If VERIFY_WITH_BROKER is not set, the pact specified by CHANGED_PACT_URL environment variable or the - local directory pact will be verified. VERIFY_WITH_BROKER is not set when the contract is changed by the - consumer and a provider verification build specific to the changed contract should be executed. - """ - if self.PACT_DEFAULT_CONFIG['verify_with_broker']: - output, _ = self.verifier.verify_with_broker( - **self.PACT_BROKER_CONFIG, - provider_states_setup_url=f"{self.live_server_url}{reverse('provider-state-view')}", - ) - else: - output, _ = self.verifier.verify_pacts( - settings.CHANGED_PACT_URL or os.path.join(PACT_DIR, PACT_FILE), - provider_states_setup_url=f"{self.live_server_url}{reverse('provider-state-view')}", - **self.PACT_DEFAULT_CONFIG, - ) - - assert output == 0 diff --git a/edxval/pacts/video-encode-manager-edx-val.json b/edxval/pacts/video-encode-manager-edx-val.json deleted file mode 100644 index df0491c6..00000000 --- a/edxval/pacts/video-encode-manager-edx-val.json +++ /dev/null @@ -1,514 +0,0 @@ -{ - "consumer": { - "name": "video-encode-manager" - }, - "provider": { - "name": "edx-val" - }, - "interactions": [ - { - "description": "A request for video transcript creation for a given provider and language", - "providerState": "A valid video with no video transcript information exists", - "request": { - "method": "post", - "path": "/edxval/videos/video-transcripts/create/", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "video_id": "3386eda1-8d6e-439d-tb89-e90a5c52h103", - "language_code": "en", - "name": "video_transcript", - "file_format": "sjson", - "provider": "3PlayMedia" - }, - "matchingRules": { - "$.body.video_id": { - "match": "regex", - "regex": "[a-zA-Z0-9-]+" - }, - "$.body.language_code": { - "match": "regex", - "regex": "[a-z]+" - }, - "$.body.name": { - "match": "regex", - "regex": "[a-zA-Z0-9-_]+" - }, - "$.body.file_format": { - "match": "regex", - "regex": "srt|sjson" - }, - "$.body.provider": { - "match": "regex", - "regex": "3PlayMedia|Cielo24" - } - } - }, - "response": { - "status": 200, - "headers": { - }, - "body": "" - } - }, - { - "description": "A request for updating video details", - "providerState": "A valid video with no details exists", - "request": { - "method": "put", - "path": "/edxval/videos/3386eda1-8d6e-439d-tb89-e90a5c52h103", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "encoded_videos": [ - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "hls" - }, - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "mp3" - }, - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "mobile_low" - }, - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "desktop_mp4" - } - ], - "courses": [ - - ], - "edx_video_id": "3386eda1-8d6e-439d-tb89-e90a5c52h103", - "client_video_id": "filename", - "duration": 1, - "status": "file_complete" - }, - "matchingRules": { - "$.body.encoded_videos[0].file_size": { - "match": "type" - }, - "$.body.encoded_videos[0].bitrate": { - "match": "type" - }, - "$.body.encoded_videos[1].file_size": { - "match": "type" - }, - "$.body.encoded_videos[1].bitrate": { - "match": "type" - }, - "$.body.encoded_videos[2].file_size": { - "match": "type" - }, - "$.body.encoded_videos[2].bitrate": { - "match": "type" - }, - "$.body.encoded_videos[3].file_size": { - "match": "type" - }, - "$.body.encoded_videos[3].bitrate": { - "match": "type" - }, - "$.body.duration": { - "match": "type" - } - } - }, - "response": { - "status": 200, - "headers": { - }, - "body": { - "encoded_videos": [ - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "hls", - "created": "2020-01-01T00:00:00", - "modified": "2020-01-01T00:00:00" - }, - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "hls", - "created": "2020-01-01T00:00:00", - "modified": "2020-01-01T00:00:00" - }, - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "hls", - "created": "2020-01-01T00:00:00", - "modified": "2020-01-01T00:00:00" - }, - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "hls", - "created": "2020-01-01T00:00:00", - "modified": "2020-01-01T00:00:00" - } - ], - "courses": [ - { - "course-v1:testX+test123+2030": null - } - ], - "edx_video_id": "3386eda1-8d6e-439d-tb89-e90a5c52h103", - "client_video_id": "filename", - "created": "2021-01-01T00:00:00", - "url": "url", - "duration": 1, - "status": "file_complete" - }, - "matchingRules": { - "$.body": { - "match": "type" - }, - "$.body.encoded_videos": { - "min": 4 - }, - "$.body.encoded_videos[*].*": { - "match": "type" - }, - "$.body.encoded_videos[*].file_size": { - "match": "type" - }, - "$.body.encoded_videos[*].bitrate": { - "match": "type" - }, - "$.body.encoded_videos[*].profile": { - "match": "regex", - "regex": "hls|mp3|desktop_mp4|mobile_low" - }, - "$.body.encoded_videos[*].created": { - "match": "regex", - "regex": "\\d+-\\d+-\\d+T\\d+:\\d+:\\d+" - }, - "$.body.encoded_videos[*].modified": { - "match": "regex", - "regex": "\\d+-\\d+-\\d+T\\d+:\\d+:\\d+" - }, - "$.body.client_video_id": { - "match": "regex", - "regex": "[a-zA-Z_]+" - }, - "$.body.duration": { - "match": "type" - }, - "$.body.status": { - "match": "regex", - "regex": "[a-zA-Z_]+" - } - } - } - }, - { - "description": "A request for updating video thumbnails", - "providerState": "A valid video with no image information exists", - "request": { - "method": "post", - "path": "/edxval/videos/video-images/update/", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "edx_video_id": "3386eda1-8d6e-439d-tb89-e90a5c52h103", - "course_id": "course-v1:testX+test123+2030", - "generated_images": [ - "https://video-1.png" - ] - }, - "matchingRules": { - "$.body.edx_video_id": { - "match": "regex", - "regex": "[a-zA-Z0-9-]+" - }, - "$.body.course_id": { - "match": "regex", - "regex": "[^\\/+]+(\\/|\\+)[^\\/+]+(\\/|\\+)[^\\/]+" - }, - "$.body.generated_images": { - "min": 1 - }, - "$.body.generated_images[*].*": { - "match": "type" - }, - "$.body.generated_images[*]": { - "match": "regex", - "regex": "(https:\\/\\/){1}[a-zA-Z.0-9-:\\/]+.png" - } - } - }, - "response": { - "status": 200, - "headers": { - }, - "body": "" - } - }, - { - "description": "A request for updating video status", - "providerState": "A valid video_id video exists", - "request": { - "method": "patch", - "path": "/edxval/videos/status/", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "edx_video_id": "3386eda1-8d6e-439d-tb89-e90a5c52h103", - "status": "file_complete" - }, - "matchingRules": { - "$.body.edx_video_id": { - "match": "regex", - "regex": "[a-zA-Z0-9-]+" - }, - "$.body.status": { - "match": "regex", - "regex": "[a-zA-Z]+" - } - } - }, - "response": { - "status": 200, - "headers": { - }, - "body": { - } - } - }, - { - "description": "A request for video transcript creation for a given provider and language", - "providerState": "A valid video and video transcript information exists", - "request": { - "method": "post", - "path": "/edxval/videos/video-transcripts/create/", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "video_id": "3386eda1-8d6e-439d-tb89-e90a5c52h103", - "language_code": "en", - "name": "video_transcript", - "file_format": "sjson", - "provider": "3PlayMedia" - }, - "matchingRules": { - "$.body.video_id": { - "match": "regex", - "regex": "[a-zA-Z0-9-]+" - }, - "$.body.language_code": { - "match": "regex", - "regex": "[a-z]+" - }, - "$.body.name": { - "match": "regex", - "regex": "[a-zA-Z0-9-_]+" - }, - "$.body.file_format": { - "match": "regex", - "regex": "srt|sjson" - }, - "$.body.provider": { - "match": "regex", - "regex": "3PlayMedia|Cielo24" - } - } - }, - "response": { - "status": 400, - "headers": { - }, - "body": { - "message": "Can not override existing transcript for video \"3386eda1-8d6e-439d-tb89-e90a5c52h103\" and language code \"en\"." - } - } - }, - { - "description": "A request for updating video details", - "providerState": "No video and video details exist", - "request": { - "method": "put", - "path": "/edxval/videos/invalid_video_id", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "encoded_videos": [ - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "hls" - }, - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "mp3" - }, - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "mobile_low" - }, - { - "url": "string", - "file_size": 1, - "bitrate": 1, - "profile": "desktop_mp4" - } - ], - "courses": [ - - ], - "edx_video_id": "invalid_video_id", - "client_video_id": "filename", - "duration": 1, - "status": "ready" - }, - "matchingRules": { - "$.body.encoded_videos[0].file_size": { - "match": "type" - }, - "$.body.encoded_videos[0].bitrate": { - "match": "type" - }, - "$.body.encoded_videos[1].file_size": { - "match": "type" - }, - "$.body.encoded_videos[1].bitrate": { - "match": "type" - }, - "$.body.encoded_videos[2].file_size": { - "match": "type" - }, - "$.body.encoded_videos[2].bitrate": { - "match": "type" - }, - "$.body.encoded_videos[3].file_size": { - "match": "type" - }, - "$.body.encoded_videos[3].bitrate": { - "match": "type" - }, - "$.body.duration": { - "match": "type" - } - } - }, - "response": { - "status": 404, - "headers": { - }, - "body": { - "detail": "Not found." - } - } - }, - { - "description": "A request for updating video thumbnails", - "providerState": "No valid video with video images details exist", - "request": { - "method": "post", - "path": "/edxval/videos/video-images/update/", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "edx_video_id": "3386eda1-8d6e-439d-tb89-e90a5c52h103", - "course_id": "course-v1:testX+test123+2030", - "generated_images": [ - "https://video-1.png" - ] - }, - "matchingRules": { - "$.body.edx_video_id": { - "match": "regex", - "regex": "[a-zA-Z0-9-]+" - }, - "$.body.course_id": { - "match": "regex", - "regex": "[^\\/+]+(\\/|\\+)[^\\/+]+(\\/|\\+)[^\\/]+" - }, - "$.body.generated_images": { - "min": 1 - }, - "$.body.generated_images[*].*": { - "match": "type" - }, - "$.body.generated_images[*]": { - "match": "regex", - "regex": "(https:\\/\\/){1}[a-zA-Z.0-9-:\\/]+.png" - } - } - }, - "response": { - "status": 400, - "headers": { - }, - "body": { - "message": "CourseVideo not found for course_id: course-v1:testX+test123+2030" - } - } - }, - { - "description": "An update video status request", - "providerState": "A video against given video id does not exist", - "request": { - "method": "patch", - "path": "/edxval/videos/status/", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "edx_video_id": "invalid_video_id", - "status": "file_complete" - }, - "matchingRules": { - "$.body.edx_video_id": { - "match": "regex", - "regex": "[a-zA-Z0-9-]+" - }, - "$.body.status": { - "match": "regex", - "regex": "[a-zA-Z]+" - } - } - }, - "response": { - "status": 400, - "headers": { - }, - "body": { - "message": "Video is not found for specified edx_video_id: invalid_video_id" - } - } - } - ], - "metadata": { - "pactSpecification": { - "version": "2.0.0" - } - } -} \ No newline at end of file diff --git a/edxval/pacts/views.py b/edxval/pacts/views.py deleted file mode 100644 index 7c1cab4c..00000000 --- a/edxval/pacts/views.py +++ /dev/null @@ -1,41 +0,0 @@ -""" -Provider state views needed by pact to setup Provider state for pact verification. -""" -import json -import logging - -from django.http import JsonResponse -from django.views.decorators.csrf import csrf_exempt -from django.views.decorators.http import require_POST - -from edxval.pacts.utils import ( - clear_database, - create_course_video, - create_video, - setup_successful_video_details_state, - setup_unsuccessful_video_transcripts_state, -) - -logger = logging.getLogger(__name__) - - -@csrf_exempt -@require_POST -def provider_state(request): - """ - Provider state setup view needed by pact verifier. - """ - state_setup_mapping = { - 'A valid video_id video exists': create_video, - 'A valid video with no details exists': setup_successful_video_details_state, - 'A valid video with no image information exists': create_course_video, - 'A valid video with no video transcript information exists': create_video, - 'A valid video and video transcript information exists': setup_unsuccessful_video_transcripts_state, - } - request_body = json.loads(request.body) - state = request_body.get('state') - clear_database() - if state in state_setup_mapping: - logger.info('Setting up provider state for state value: %s', state) - state_setup_mapping[state]() - return JsonResponse({'result': state}) diff --git a/edxval/settings/pact.py b/edxval/settings/pact.py deleted file mode 100644 index 08ace40b..00000000 --- a/edxval/settings/pact.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -Pact related Django settings. - -Making a separate setting file for pact so that the configuration -does not cause issue with regular unit testing. -""" -import os - -from edxval.settings.test import * # pylint: disable=wildcard-import - -CHANGED_PACT_URL = os.environ.get('CHANGED_PACT_URL') -GIT_ENV = os.environ.get('GIT_ENV', 'development') -PROVIDER_STATES_SETUP_VIEW_URL = True -PACT_BROKER_BASE_URL = os.environ.get('PACT_BROKER_BASE_URL', 'http://localhost:9292') -PUBLISH_TAGS = os.environ.get('PUBLISH_TAGS', 'master') -PUBLISH_VERSION = os.environ.get('PUBLISH_VERSION', '1') -PUBLISH_VERIFICATION_RESULTS = os.environ.get('PUBLISH_VERIFICATION_RESULTS', 'False').lower() in ('true', 'yes', '1') - -# By default, the verification will be done from broker. This option will need to be -# overridden when doing verification for a changed contract -VERIFY_WITH_BROKER = os.environ.get('VERIFY_WITH_BROKER', 'True').lower() in ('true', 'yes', '1') - -MIDDLEWARE = MIDDLEWARE + ('edxval.pacts.middleware.AuthenticationMiddleware',) diff --git a/edxval/urls.py b/edxval/urls.py index d985746d..abf9a817 100644 --- a/edxval/urls.py +++ b/edxval/urls.py @@ -1,7 +1,6 @@ """ Url file for django app edxval. """ -from django.conf import settings from django.urls import path, re_path from edxval import views @@ -35,11 +34,3 @@ name='course-video-ids' ), ] - -if getattr(settings, 'PROVIDER_STATES_SETUP_VIEW_URL', None): - from edxval.pacts.views import provider_state - urlpatterns.append(re_path( - r'^pact/provider_states/$', - provider_state, - name='provider-state-view' - )) diff --git a/requirements/ci.txt b/requirements/ci.txt index 17984d38..48147961 100644 --- a/requirements/ci.txt +++ b/requirements/ci.txt @@ -6,63 +6,63 @@ # annotated-doc==0.0.4 # via typer -cachetools==7.0.5 +cachetools==7.1.4 # via tox -certifi==2026.2.25 +certifi==2026.6.17 # via requests -charset-normalizer==3.4.5 +charset-normalizer==3.4.7 # via requests -click==8.3.1 - # via typer colorama==0.4.6 # via tox -coverage[toml]==7.13.4 +coverage[toml]==7.14.1 # via coveralls coveralls==4.1.0 # via -r requirements/ci.in -distlib==0.4.0 +distlib==0.4.3 # via virtualenv -filelock==3.25.2 +filelock==3.29.4 # via # python-discovery # tox # virtualenv -idna==3.11 +idna==3.18 # via requests -markdown-it-py==4.0.0 +markdown-it-py==4.2.0 # via rich mdurl==0.1.2 # via markdown-it-py -packaging==26.0 +packaging==26.2 # via # pyproject-api # tox -platformdirs==4.9.4 +platformdirs==4.10.0 # via # python-discovery # tox # virtualenv pluggy==1.6.0 # via tox -pygments==2.19.2 +pygments==2.20.0 # via rich -pyproject-api==1.10.0 +pyproject-api==1.10.1 # via tox -python-discovery==1.1.3 - # via virtualenv -requests==2.32.5 +python-discovery==1.4.2 + # via + # tox + # virtualenv +requests==2.34.2 # via coveralls -rich==14.3.3 +rich==15.0.0 # via typer shellingham==1.5.4 # via typer tomli-w==1.2.0 # via tox -tox==4.49.1 +tox==4.55.1 # via -r requirements/ci.in -typer==0.24.1 +typer==0.26.7 # via coveralls -urllib3==2.6.3 +urllib3==2.7.0 # via requests -virtualenv==21.2.0 +virtualenv==21.5.1 # via tox diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 53ab4a7a..9955a103 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -15,9 +15,3 @@ # namespace package declarations in fs/__init__.py. Pin until fs is updated. # See: https://github.com/PyFilesystem/pyfilesystem2/issues/577 setuptools<82 - -# pact-python 3.x has a completely different API from 2.x. -# The verify_pact.py code uses the 2.x API (Verifier with provider/provider_base_url kwargs). -# Pin until the code is updated to use the new API. -# See: https://github.com/openedx/edx-val/issues/598 -pact-python<3 diff --git a/requirements/dev.txt b/requirements/dev.txt index 21373adc..b7bf905a 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -5,13 +5,7 @@ # make upgrade # annotated-doc==0.0.4 - # via - # fastapi - # typer -annotated-types==0.7.0 - # via pydantic -anyio==4.12.1 - # via starlette + # via typer appdirs==1.4.4 # via fs asgiref==3.11.1 @@ -20,66 +14,62 @@ astroid==4.0.4 # via # pylint # pylint-celery -boto3==1.42.66 +boto3==1.43.32 # via -r requirements/test.in -botocore==1.42.66 +botocore==1.43.32 # via # boto3 # s3transfer -cachetools==7.0.5 +cachetools==7.1.4 # via # -r requirements/base.in # tox -certifi==2026.2.25 +certifi==2026.6.17 # via requests -cffi==1.17.1 +cffi==2.0.0 # via # cryptography - # pact-python # pynacl -chardet==7.1.0 +chardet==7.4.3 # via # diff-cover # pysrt -charset-normalizer==3.4.5 +charset-normalizer==3.4.7 # via requests -click==8.3.1 +click==8.4.1 # via # click-log # code-annotations # edx-django-utils # edx-lint - # pact-python - # typer - # uvicorn click-log==0.4.0 # via edx-lint -code-annotations==2.3.2 +code-annotations==3.0.0 # via # edx-lint # edx-toggles colorama==0.4.6 # via tox -coverage[toml]==7.13.4 +coverage[toml]==7.14.1 # via # -r requirements/test.in # coveralls # pytest-cov coveralls==4.1.0 # via -r requirements/ci.in -cryptography==46.0.0 +cryptography==49.0.0 # via # pyjwt # secretstorage ddt==1.7.2 # via -r requirements/test.in -diff-cover==10.2.0 +diff-cover==10.3.0 # via -r requirements/dev.in dill==0.4.1 # via pylint -distlib==0.4.0 +distlib==0.4.3 # via virtualenv -django==5.2.12 +django==5.2.15 # via # -c requirements/common_constraints.txt # -r requirements/base.in @@ -106,13 +96,13 @@ django-waffle==5.0.0 # edx-django-utils # edx-drf-extensions # edx-toggles -djangorestframework==3.16.1 +djangorestframework==3.17.1 # via # drf-jwt # edx-drf-extensions dnspython==2.8.0 # via pymongo -docutils==0.22.4 +docutils==0.23 # via readme-renderer drf-jwt==1.19.2 # via edx-drf-extensions @@ -124,30 +114,23 @@ edx-django-utils==8.0.1 # edx-toggles edx-drf-extensions==10.6.0 # via -r requirements/base.in -edx-lint==5.6.0 +edx-lint==6.1.0 # via -r requirements/quality.in -edx-opaque-keys==3.1.0 +edx-opaque-keys==4.0.0 # via edx-drf-extensions -edx-toggles==5.4.1 +edx-toggles==6.0.0 # via -r requirements/base.in -fastapi==0.135.1 - # via pact-python -filelock==3.25.2 +filelock==3.29.4 # via # python-discovery # tox # virtualenv fs==2.4.16 # via -r requirements/test.in -h11==0.16.0 - # via uvicorn id==1.6.1 # via twine -idna==3.11 - # via - # anyio - # requests - # yarl +idna==3.18 + # via requests iniconfig==2.3.0 # via pytest isort==8.0.1 @@ -156,9 +139,9 @@ isort==8.0.1 # pylint jaraco-classes==3.4.0 # via keyring -jaraco-context==6.1.1 +jaraco-context==6.1.2 # via keyring -jaraco-functools==4.4.0 +jaraco-functools==4.5.0 # via keyring jeepney==0.9.0 # via @@ -174,9 +157,9 @@ jmespath==1.1.0 # botocore keyring==25.7.0 # via twine -lxml==6.0.2 +lxml==6.1.1 # via -r requirements/base.in -markdown-it-py==4.0.0 +markdown-it-py==4.2.0 # via rich markupsafe==3.0.3 # via jinja2 @@ -186,27 +169,21 @@ mdurl==0.1.2 # via markdown-it-py mock==5.2.0 # via -r requirements/test.in -more-itertools==10.8.0 +more-itertools==11.1.0 # via # jaraco-classes # jaraco-functools -multidict==6.7.1 - # via yarl -nh3==0.3.3 +nh3==0.3.5 # via readme-renderer -packaging==26.0 +packaging==26.2 # via # pyproject-api # pytest # tox # twine -pact-python==2.3.3 - # via - # -c requirements/constraints.txt - # -r requirements/test.in -pillow==12.1.1 +pillow==12.2.0 # via -r requirements/base.in -platformdirs==4.9.4 +platformdirs==4.10.0 # via # pylint # python-discovery @@ -218,33 +195,25 @@ pluggy==1.6.0 # pytest # pytest-cov # tox -propcache==0.4.1 - # via yarl psutil==7.2.2 - # via - # edx-django-utils - # pact-python + # via edx-django-utils pycodestyle==2.14.0 # via -r requirements/quality.in pycparser==3.0 # via cffi -pydantic==2.12.5 - # via fastapi -pydantic-core==2.41.5 - # via pydantic pydocstyle==6.3.0 # via -r requirements/quality.in -pygments==2.19.2 +pygments==2.20.0 # via # diff-cover # pytest # readme-renderer # rich -pyjwt[crypto]==2.11.0 +pyjwt[crypto]==2.13.0 # via # drf-jwt # edx-drf-extensions -pylint==4.0.5 +pylint==4.0.6 # via # edx-lint # pylint-celery @@ -258,26 +227,28 @@ pylint-plugin-utils==0.9.0 # via # pylint-celery # pylint-django -pymongo==4.16.0 +pymongo==4.17.0 # via edx-opaque-keys -pynacl==1.6.0 +pynacl==1.6.2 # via edx-django-utils -pyproject-api==1.10.0 +pyproject-api==1.10.1 # via tox pysrt==1.1.2 # via -r requirements/base.in -pytest==9.0.2 +pytest==9.1.0 # via # pytest-cov # pytest-django -pytest-cov==7.0.0 +pytest-cov==7.1.0 # via -r requirements/test.in pytest-django==4.12.0 # via -r requirements/test.in python-dateutil==2.9.0.post0 # via botocore -python-discovery==1.1.3 - # via virtualenv +python-discovery==1.4.2 + # via + # tox + # virtualenv python-slugify==8.0.4 # via code-annotations pyyaml==6.0.3 @@ -285,27 +256,26 @@ pyyaml==6.0.3 # code-annotations # edx-django-release-util # responses -readme-renderer==44.0 +readme-renderer==45.0 # via twine -requests==2.32.5 +requests==2.34.2 # via # coveralls # edx-drf-extensions - # pact-python # requests-toolbelt # responses # twine requests-toolbelt==1.0.0 # via twine -responses==0.26.0 +responses==0.26.1 # via -r requirements/test.in rfc3986==2.0.0 # via twine -rich==14.3.3 +rich==15.0.0 # via # twine # typer -s3transfer==0.16.0 +s3transfer==0.19.0 # via boto3 secretstorage==3.5.0 # via keyring @@ -318,15 +288,12 @@ six==1.17.0 # edx-django-release-util # edx-lint # fs - # pact-python # python-dateutil -snowballstemmer==3.0.1 +snowballstemmer==3.1.1 # via pydocstyle sqlparse==0.5.5 # via django -starlette==0.52.1 - # via fastapi -stevedore==5.7.0 +stevedore==5.8.0 # via # code-annotations # edx-django-utils @@ -335,40 +302,27 @@ text-unidecode==1.3 # via python-slugify tomli-w==1.2.0 # via tox -tomlkit==0.14.0 - # via pylint -tox==4.49.1 +tomlkit==0.15.0 + # via + # edx-lint + # pylint +tox==4.55.1 # via -r requirements/ci.in twine==6.2.0 # via -r requirements/quality.in -typer==0.24.1 +typer==0.26.7 # via coveralls typing-extensions==4.15.0 - # via - # anyio - # edx-opaque-keys - # fastapi - # pydantic - # pydantic-core - # starlette - # typing-inspection -typing-inspection==0.4.2 - # via - # fastapi - # pydantic -urllib3==2.6.3 + # via edx-opaque-keys +urllib3==2.7.0 # via # botocore # id # requests # responses # twine -uvicorn==0.41.0 - # via pact-python -virtualenv==21.2.0 +virtualenv==21.5.1 # via tox -yarl==1.23.0 - # via pact-python # The following packages are considered to be unsafe in a requirements file: setuptools==81.0.0 diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt index d89516b8..ae6076a0 100644 --- a/requirements/pip-tools.txt +++ b/requirements/pip-tools.txt @@ -4,11 +4,11 @@ # # make upgrade # -build==1.4.0 +build==1.5.0 # via pip-tools -click==8.3.1 +click==8.4.1 # via pip-tools -packaging==26.0 +packaging==26.2 # via # build # wheel @@ -18,7 +18,7 @@ pyproject-hooks==1.2.0 # via # build # pip-tools -wheel==0.46.3 +wheel==0.47.0 # via pip-tools # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements/pip.txt b/requirements/pip.txt index 8bd16d64..1f4d2eb9 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -4,13 +4,13 @@ # # make upgrade # -packaging==26.0 +packaging==26.2 # via wheel -wheel==0.46.3 +wheel==0.47.0 # via -r requirements/pip.in # The following packages are considered to be unsafe in a requirements file: -pip==26.0.1 +pip==26.1.2 # via -r requirements/pip.in setuptools==81.0.0 # via diff --git a/requirements/quality.txt b/requirements/quality.txt index c5b0c116..f639ed9e 100644 --- a/requirements/quality.txt +++ b/requirements/quality.txt @@ -4,12 +4,6 @@ # # make upgrade # -annotated-doc==0.0.4 - # via fastapi -annotated-types==0.7.0 - # via pydantic -anyio==4.12.1 - # via starlette appdirs==1.4.4 # via fs asgiref==3.11.1 @@ -18,44 +12,41 @@ astroid==4.0.4 # via # pylint # pylint-celery -boto3==1.42.66 +boto3==1.43.32 # via -r requirements/test.in -botocore==1.42.66 +botocore==1.43.32 # via # boto3 # s3transfer -cachetools==7.0.5 +cachetools==7.1.4 # via -r requirements/base.in -certifi==2026.2.25 +certifi==2026.6.17 # via requests -cffi==1.17.1 +cffi==2.0.0 # via # cryptography - # pact-python # pynacl -chardet==7.1.0 +chardet==7.4.3 # via pysrt -charset-normalizer==3.4.5 +charset-normalizer==3.4.7 # via requests -click==8.3.1 +click==8.4.1 # via # click-log # code-annotations # edx-django-utils # edx-lint - # pact-python - # uvicorn click-log==0.4.0 # via edx-lint -code-annotations==2.3.2 +code-annotations==3.0.0 # via # edx-lint # edx-toggles -coverage[toml]==7.13.4 +coverage[toml]==7.14.1 # via # -r requirements/test.in # pytest-cov -cryptography==46.0.0 +cryptography==49.0.0 # via # pyjwt # secretstorage @@ -63,7 +54,7 @@ ddt==1.7.2 # via -r requirements/test.in dill==0.4.1 # via pylint -django==5.2.12 +django==5.2.15 # via # -c requirements/common_constraints.txt # -r requirements/base.in @@ -90,13 +81,13 @@ django-waffle==5.0.0 # edx-django-utils # edx-drf-extensions # edx-toggles -djangorestframework==3.16.1 +djangorestframework==3.17.1 # via # drf-jwt # edx-drf-extensions dnspython==2.8.0 # via pymongo -docutils==0.22.4 +docutils==0.23 # via readme-renderer drf-jwt==1.19.2 # via edx-drf-extensions @@ -108,25 +99,18 @@ edx-django-utils==8.0.1 # edx-toggles edx-drf-extensions==10.6.0 # via -r requirements/base.in -edx-lint==5.6.0 +edx-lint==6.1.0 # via -r requirements/quality.in -edx-opaque-keys==3.1.0 +edx-opaque-keys==4.0.0 # via edx-drf-extensions -edx-toggles==5.4.1 +edx-toggles==6.0.0 # via -r requirements/base.in -fastapi==0.135.1 - # via pact-python fs==2.4.16 # via -r requirements/test.in -h11==0.16.0 - # via uvicorn id==1.6.1 # via twine -idna==3.11 - # via - # anyio - # requests - # yarl +idna==3.18 + # via requests iniconfig==2.3.0 # via pytest isort==8.0.1 @@ -135,9 +119,9 @@ isort==8.0.1 # pylint jaraco-classes==3.4.0 # via keyring -jaraco-context==6.1.1 +jaraco-context==6.1.2 # via keyring -jaraco-functools==4.4.0 +jaraco-functools==4.5.0 # via keyring jeepney==0.9.0 # via @@ -151,9 +135,9 @@ jmespath==1.1.0 # botocore keyring==25.7.0 # via twine -lxml==6.0.2 +lxml==6.1.1 # via -r requirements/base.in -markdown-it-py==4.0.0 +markdown-it-py==4.2.0 # via rich markupsafe==3.0.3 # via jinja2 @@ -163,56 +147,42 @@ mdurl==0.1.2 # via markdown-it-py mock==5.2.0 # via -r requirements/test.in -more-itertools==10.8.0 +more-itertools==11.1.0 # via # jaraco-classes # jaraco-functools -multidict==6.7.1 - # via yarl -nh3==0.3.3 +nh3==0.3.5 # via readme-renderer -packaging==26.0 +packaging==26.2 # via # pytest # twine -pact-python==2.3.3 - # via - # -c requirements/constraints.txt - # -r requirements/test.in -pillow==12.1.1 +pillow==12.2.0 # via -r requirements/base.in -platformdirs==4.9.4 +platformdirs==4.10.0 # via pylint pluggy==1.6.0 # via # pytest # pytest-cov -propcache==0.4.1 - # via yarl psutil==7.2.2 - # via - # edx-django-utils - # pact-python + # via edx-django-utils pycodestyle==2.14.0 # via -r requirements/quality.in pycparser==3.0 # via cffi -pydantic==2.12.5 - # via fastapi -pydantic-core==2.41.5 - # via pydantic pydocstyle==6.3.0 # via -r requirements/quality.in -pygments==2.19.2 +pygments==2.20.0 # via # pytest # readme-renderer # rich -pyjwt[crypto]==2.11.0 +pyjwt[crypto]==2.13.0 # via # drf-jwt # edx-drf-extensions -pylint==4.0.5 +pylint==4.0.6 # via # edx-lint # pylint-celery @@ -226,17 +196,17 @@ pylint-plugin-utils==0.9.0 # via # pylint-celery # pylint-django -pymongo==4.16.0 +pymongo==4.17.0 # via edx-opaque-keys -pynacl==1.6.0 +pynacl==1.6.2 # via edx-django-utils pysrt==1.1.2 # via -r requirements/base.in -pytest==9.0.2 +pytest==9.1.0 # via # pytest-cov # pytest-django -pytest-cov==7.0.0 +pytest-cov==7.1.0 # via -r requirements/test.in pytest-django==4.12.0 # via -r requirements/test.in @@ -249,24 +219,23 @@ pyyaml==6.0.3 # code-annotations # edx-django-release-util # responses -readme-renderer==44.0 +readme-renderer==45.0 # via twine -requests==2.32.5 +requests==2.34.2 # via # edx-drf-extensions - # pact-python # requests-toolbelt # responses # twine requests-toolbelt==1.0.0 # via twine -responses==0.26.0 +responses==0.26.1 # via -r requirements/test.in rfc3986==2.0.0 # via twine -rich==14.3.3 +rich==15.0.0 # via twine -s3transfer==0.16.0 +s3transfer==0.19.0 # via boto3 secretstorage==3.5.0 # via keyring @@ -277,49 +246,33 @@ six==1.17.0 # edx-django-release-util # edx-lint # fs - # pact-python # python-dateutil -snowballstemmer==3.0.1 +snowballstemmer==3.1.1 # via pydocstyle sqlparse==0.5.5 # via django -starlette==0.52.1 - # via fastapi -stevedore==5.7.0 +stevedore==5.8.0 # via # code-annotations # edx-django-utils # edx-opaque-keys text-unidecode==1.3 # via python-slugify -tomlkit==0.14.0 - # via pylint +tomlkit==0.15.0 + # via + # edx-lint + # pylint twine==6.2.0 # via -r requirements/quality.in typing-extensions==4.15.0 - # via - # anyio - # edx-opaque-keys - # fastapi - # pydantic - # pydantic-core - # starlette - # typing-inspection -typing-inspection==0.4.2 - # via - # fastapi - # pydantic -urllib3==2.6.3 + # via edx-opaque-keys +urllib3==2.7.0 # via # botocore # id # requests # responses # twine -uvicorn==0.41.0 - # via pact-python -yarl==1.23.0 - # via pact-python # The following packages are considered to be unsafe in a requirements file: setuptools==81.0.0 diff --git a/requirements/test.in b/requirements/test.in index 6d4fee44..7460708b 100644 --- a/requirements/test.in +++ b/requirements/test.in @@ -7,7 +7,6 @@ coverage ddt fs mock -pact-python pytest-cov pytest-django responses diff --git a/requirements/test.txt b/requirements/test.txt index cbab2a37..5562eaee 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -4,48 +4,39 @@ # # make upgrade # -annotated-doc==0.0.4 - # via fastapi -annotated-types==0.7.0 - # via pydantic -anyio==4.12.1 - # via starlette appdirs==1.4.4 # via fs asgiref==3.11.1 # via django -boto3==1.42.66 +boto3==1.43.32 # via -r requirements/test.in -botocore==1.42.66 +botocore==1.43.32 # via # boto3 # s3transfer -cachetools==7.0.5 +cachetools==7.1.4 # via -r requirements/base.in -certifi==2026.2.25 +certifi==2026.6.17 # via requests -cffi==1.17.1 +cffi==2.0.0 # via # cryptography - # pact-python # pynacl -chardet==7.1.0 +chardet==7.4.3 # via pysrt -charset-normalizer==3.4.5 +charset-normalizer==3.4.7 # via requests -click==8.3.1 +click==8.4.1 # via # code-annotations # edx-django-utils - # pact-python - # uvicorn -code-annotations==2.3.2 +code-annotations==3.0.0 # via edx-toggles -coverage[toml]==7.13.4 +coverage[toml]==7.14.1 # via # -r requirements/test.in # pytest-cov -cryptography==46.0.0 +cryptography==49.0.0 # via pyjwt ddt==1.7.2 # via -r requirements/test.in @@ -75,7 +66,7 @@ django-waffle==5.0.0 # edx-django-utils # edx-drf-extensions # edx-toggles -djangorestframework==3.16.1 +djangorestframework==3.17.1 # via # drf-jwt # edx-drf-extensions @@ -91,21 +82,14 @@ edx-django-utils==8.0.1 # edx-toggles edx-drf-extensions==10.6.0 # via -r requirements/base.in -edx-opaque-keys==3.1.0 +edx-opaque-keys==4.0.0 # via edx-drf-extensions -edx-toggles==5.4.1 +edx-toggles==6.0.0 # via -r requirements/base.in -fastapi==0.135.1 - # via pact-python fs==2.4.16 # via -r requirements/test.in -h11==0.16.0 - # via uvicorn -idna==3.11 - # via - # anyio - # requests - # yarl +idna==3.18 + # via requests iniconfig==2.3.0 # via pytest jinja2==3.1.6 @@ -114,55 +98,41 @@ jmespath==1.1.0 # via # boto3 # botocore -lxml==6.0.2 +lxml==6.1.1 # via -r requirements/base.in markupsafe==3.0.3 # via jinja2 mock==5.2.0 # via -r requirements/test.in -multidict==6.7.1 - # via yarl -packaging==26.0 +packaging==26.2 # via pytest -pact-python==2.3.3 - # via - # -c requirements/constraints.txt - # -r requirements/test.in -pillow==12.1.1 +pillow==12.2.0 # via -r requirements/base.in pluggy==1.6.0 # via # pytest # pytest-cov -propcache==0.4.1 - # via yarl psutil==7.2.2 - # via - # edx-django-utils - # pact-python + # via edx-django-utils pycparser==3.0 # via cffi -pydantic==2.12.5 - # via fastapi -pydantic-core==2.41.5 - # via pydantic -pygments==2.19.2 +pygments==2.20.0 # via pytest -pyjwt[crypto]==2.11.0 +pyjwt[crypto]==2.13.0 # via # drf-jwt # edx-drf-extensions -pymongo==4.16.0 +pymongo==4.17.0 # via edx-opaque-keys -pynacl==1.6.0 +pynacl==1.6.2 # via edx-django-utils pysrt==1.1.2 # via -r requirements/base.in -pytest==9.0.2 +pytest==9.1.0 # via # pytest-cov # pytest-django -pytest-cov==7.0.0 +pytest-cov==7.1.0 # via -r requirements/test.in pytest-django==4.12.0 # via -r requirements/test.in @@ -175,14 +145,13 @@ pyyaml==6.0.3 # code-annotations # edx-django-release-util # responses -requests==2.32.5 +requests==2.34.2 # via # edx-drf-extensions - # pact-python # responses -responses==0.26.0 +responses==0.26.1 # via -r requirements/test.in -s3transfer==0.16.0 +s3transfer==0.19.0 # via boto3 semantic-version==2.10.0 # via edx-drf-extensions @@ -190,13 +159,10 @@ six==1.17.0 # via # edx-django-release-util # fs - # pact-python # python-dateutil sqlparse==0.5.5 # via django -starlette==0.52.1 - # via fastapi -stevedore==5.7.0 +stevedore==5.8.0 # via # code-annotations # edx-django-utils @@ -204,27 +170,12 @@ stevedore==5.7.0 text-unidecode==1.3 # via python-slugify typing-extensions==4.15.0 - # via - # anyio - # edx-opaque-keys - # fastapi - # pydantic - # pydantic-core - # starlette - # typing-inspection -typing-inspection==0.4.2 - # via - # fastapi - # pydantic -urllib3==2.6.3 + # via edx-opaque-keys +urllib3==2.7.0 # via # botocore # requests # responses -uvicorn==0.41.0 - # via pact-python -yarl==1.23.0 - # via pact-python # The following packages are considered to be unsafe in a requirements file: setuptools==81.0.0 diff --git a/setup.py b/setup.py index 99557c56..9b2ebc68 100644 --- a/setup.py +++ b/setup.py @@ -150,7 +150,6 @@ def get_version(*file_paths): 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.12', 'Framework :: Django', - 'Framework :: Django :: 4.2', 'Framework :: Django :: 5.2', ], packages=PACKAGES, diff --git a/tox.ini b/tox.ini index 675f98da..c8d46047 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,8 @@ [tox] -envlist = py{311,312}-django{42,52}, quality +envlist = py{311,312}-django52, quality [testenv] deps = - django42: Django>=4.2,<5.0 django52: Django>=5.2,<6.0 -r{toxinidir}/requirements/test.txt commands =