diff --git a/docs/lms-openapi.yaml b/docs/lms-openapi.yaml index 32f67203b4..0f0ac22253 100644 --- a/docs/lms-openapi.yaml +++ b/docs/lms-openapi.yaml @@ -3469,8 +3469,58 @@ paths: /dashboard/v0/programs/{enterprise_uuid}/: get: operationId: dashboard_v0_programs_read - description: Return a list of a enterprise learner's all enrolled programs with - their progress. + summary: For an enterprise learner, get list of enrolled programs with progress. + description: |- + **Example Request** + + GET /api/dashboard/v1/programs/{enterprise_uuid}/ + + **Parameters** + + * `enterprise_uuid`: UUID of an enterprise customer. + + **Example Response** + + [ + { + "uuid": "ff41a5eb-2a73-4933-8e80-a1c66068ed2c", + "title": "Demonstration Program", + "type": "MicroMasters", + "banner_image": { + "large": { + "url": "http://example.com/images/foo.large.jpg", + "width": 1440, + "height": 480 + }, + "medium": { + "url": "http://example.com/images/foo.medium.jpg", + "width": 726, + "height": 242 + }, + "small": { + "url": "http://example.com/images/foo.small.jpg", + "width": 435, + "height": 145 + }, + "x-small": { + "url": "http://example.com/images/foo.x-small.jpg", + "width": 348, + "height": 116 + } + }, + "authoring_organizations": [ + { + "key": "example" + } + ], + "progress": { + "uuid": "ff41a5eb-2a73-4933-8e80-a1c66068ed2c", + "completed": 0, + "in_progress": 0, + "not_started": 2 + } + } + ] parameters: [] responses: '200': @@ -3485,7 +3535,118 @@ paths: /dashboard/v0/programs/{program_uuid}/progress_details/: get: operationId: dashboard_v0_programs_progress_details_list - description: Retrieves progress details of a user in a specified program. + summary: Retrieves progress details of a learner in a specified program. + description: |- + **Example Request** + + GET api/dashboard/v1/programs/{program_uuid}/progress_details/ + + **Parameters** + + * `program_uuid`: A string representation of the uuid of the program. + + **Response Values** + + If the request for information about the program is successful, an HTTP 200 "OK" response + is returned. + + The HTTP 200 response has the following values. + + * `urls`: Urls to enroll/purchase a course or view program record. + + * `program_data`: Holds meta information about the program. + + * `course_data`: Learner's progress details for all courses in the program (in-progress/remaining/completed). + + * `certificate_data`: Details about learner's certificates status for all courses in the program and the + program itself. + + * `industry_pathways`: Industry pathways for the program, comes under additional credit opportunities. + + * `credit_pathways`: Credit pathways for the program, comes under additional credit opportunities. + + **Example Response** + + { + "urls": { + "program_listing_url": "/dashboard/programs/", + "track_selection_url": "/course_modes/choose/", + "commerce_api_url": "/api/commerce/v1/baskets/", + "buy_button_url": "http://example.com/basket/add/?", + "program_record_url": "https://example.com/records/programs/8675309" + }, + "program_data": { + "uuid": "a156a6e2-de91-4ce7-947a-888943e6b12a", + "title": "Demonstration Program", + "subtitle": "", + "type": "MicroMasters", + "status": "active", + "marketing_slug": "demo-program", + "marketing_url": "micromasters/demo-program", + "authoring_organizations": [], + "card_image_url": "http://example.com/asset-v1:DemoX+Demo_Course.jpg", + "is_program_eligible_for_one_click_purchase": false, + "pathway_ids": [ + 1, + 2 + ], + "is_learner_eligible_for_one_click_purchase": false, + "skus": ["AUD90210"], + }, + "course_data": { + "uuid": "a156a6e2-de91-4ce7-947a-888943e6b12a", + "completed": [], + "in_progress": [], + "not_started": [ + { + "key": "example+DemoX", + "uuid": "fe1a9ad4-a452-45cd-80e5-9babd3d43f96", + "title": "Demonstration Course", + "course_runs": [], + "entitlements": [], + "owners": [], + "image": "", + "short_description": "", + "type": "457f07ec-a78f-45b4-ba09-5fb176520d8a", + } + ], + }, + "certificate_data": [{ + "type": "course", + "title": "Demo Course", + 'url': "/certificates/8675309", + }], + "industry_pathways": [ + { + "id": 2, + "uuid": "1b8fadf1-f6aa-4282-94e3-325b922a027f", + "name": "Demo Industry Pathway", + "org_name": "example", + "email": "example@example.com", + "description": "Sample demo industry pathway", + "destination_url": "http://example.edu/online/pathways/example-methods", + "pathway_type": "industry", + "program_uuids": [ + "a156a6e2-de91-4ce7-947a-888943e6b12a" + ] + } + ], + "credit_pathways": [ + { + "id": 1, + "uuid": "86b9701a-61e6-48a2-92eb-70a824521c1f", + "name": "Demo Credit Pathway", + "org_name": "example", + "email": "example@example.com", + "description": "Sample demo credit pathway!", + "destination_url": "http://example.edu/online/pathways/example-thinking", + "pathway_type": "credit", + "program_uuids": [ + "a156a6e2-de91-4ce7-947a-888943e6b12a" + ] + } + ] + } parameters: [] responses: '200': @@ -5145,26 +5306,6 @@ paths: Override the list method to expire records that are past the policy and requested via the API before returning those records. parameters: - - name: uuid - in: query - description: uuid - required: false - type: string - - name: user - in: query - description: user - required: false - type: string - - name: course_uuid - in: query - description: course_uuid - required: false - type: string - - name: expired_at__isnull - in: query - description: expired_at__isnull - required: false - type: string - name: page in: query description: A page number within the paginated result set. @@ -5351,16 +5492,6 @@ paths: operationId: experiments_v0_data_list description: '' parameters: - - name: experiment_id - in: query - description: experiment_id - required: false - type: string - - name: key - in: query - description: key - required: false - type: string - name: page in: query description: A page number within the paginated result set. @@ -5493,16 +5624,6 @@ paths: operationId: experiments_v0_key-value_list description: '' parameters: - - name: experiment_id - in: query - description: experiment_id - required: false - type: string - - name: key - in: query - description: key - required: false - type: string - name: page in: query description: A page number within the paginated result set. @@ -6245,6 +6366,198 @@ paths: tags: - learner_home parameters: [] + /learner_home/v1/programs/{enterprise_uuid}/: + get: + operationId: learner_home_v1_programs_read + summary: For an enterprise learner, get list of enrolled programs with progress. + description: |- + **Example Request** + + GET /api/dashboard/v1/programs/{enterprise_uuid}/ + + **Parameters** + + * `enterprise_uuid`: UUID of an enterprise customer. + + **Example Response** + + [ + { + "uuid": "ff41a5eb-2a73-4933-8e80-a1c66068ed2c", + "title": "Demonstration Program", + "type": "MicroMasters", + "banner_image": { + "large": { + "url": "http://example.com/images/foo.large.jpg", + "width": 1440, + "height": 480 + }, + "medium": { + "url": "http://example.com/images/foo.medium.jpg", + "width": 726, + "height": 242 + }, + "small": { + "url": "http://example.com/images/foo.small.jpg", + "width": 435, + "height": 145 + }, + "x-small": { + "url": "http://example.com/images/foo.x-small.jpg", + "width": 348, + "height": 116 + } + }, + "authoring_organizations": [ + { + "key": "example" + } + ], + "progress": { + "uuid": "ff41a5eb-2a73-4933-8e80-a1c66068ed2c", + "completed": 0, + "in_progress": 0, + "not_started": 2 + } + } + ] + parameters: [] + responses: + '200': + description: '' + tags: + - learner_home + parameters: + - name: enterprise_uuid + in: path + required: true + type: string + /learner_home/v1/programs/{program_uuid}/progress_details/: + get: + operationId: learner_home_v1_programs_progress_details_list + summary: Retrieves progress details of a learner in a specified program. + description: |- + **Example Request** + + GET api/dashboard/v1/programs/{program_uuid}/progress_details/ + + **Parameters** + + * `program_uuid`: A string representation of the uuid of the program. + + **Response Values** + + If the request for information about the program is successful, an HTTP 200 "OK" response + is returned. + + The HTTP 200 response has the following values. + + * `urls`: Urls to enroll/purchase a course or view program record. + + * `program_data`: Holds meta information about the program. + + * `course_data`: Learner's progress details for all courses in the program (in-progress/remaining/completed). + + * `certificate_data`: Details about learner's certificates status for all courses in the program and the + program itself. + + * `industry_pathways`: Industry pathways for the program, comes under additional credit opportunities. + + * `credit_pathways`: Credit pathways for the program, comes under additional credit opportunities. + + **Example Response** + + { + "urls": { + "program_listing_url": "/dashboard/programs/", + "track_selection_url": "/course_modes/choose/", + "commerce_api_url": "/api/commerce/v1/baskets/", + "buy_button_url": "http://example.com/basket/add/?", + "program_record_url": "https://example.com/records/programs/8675309" + }, + "program_data": { + "uuid": "a156a6e2-de91-4ce7-947a-888943e6b12a", + "title": "Demonstration Program", + "subtitle": "", + "type": "MicroMasters", + "status": "active", + "marketing_slug": "demo-program", + "marketing_url": "micromasters/demo-program", + "authoring_organizations": [], + "card_image_url": "http://example.com/asset-v1:DemoX+Demo_Course.jpg", + "is_program_eligible_for_one_click_purchase": false, + "pathway_ids": [ + 1, + 2 + ], + "is_learner_eligible_for_one_click_purchase": false, + "skus": ["AUD90210"], + }, + "course_data": { + "uuid": "a156a6e2-de91-4ce7-947a-888943e6b12a", + "completed": [], + "in_progress": [], + "not_started": [ + { + "key": "example+DemoX", + "uuid": "fe1a9ad4-a452-45cd-80e5-9babd3d43f96", + "title": "Demonstration Course", + "course_runs": [], + "entitlements": [], + "owners": [], + "image": "", + "short_description": "", + "type": "457f07ec-a78f-45b4-ba09-5fb176520d8a", + } + ], + }, + "certificate_data": [{ + "type": "course", + "title": "Demo Course", + 'url': "/certificates/8675309", + }], + "industry_pathways": [ + { + "id": 2, + "uuid": "1b8fadf1-f6aa-4282-94e3-325b922a027f", + "name": "Demo Industry Pathway", + "org_name": "example", + "email": "example@example.com", + "description": "Sample demo industry pathway", + "destination_url": "http://example.edu/online/pathways/example-methods", + "pathway_type": "industry", + "program_uuids": [ + "a156a6e2-de91-4ce7-947a-888943e6b12a" + ] + } + ], + "credit_pathways": [ + { + "id": 1, + "uuid": "86b9701a-61e6-48a2-92eb-70a824521c1f", + "name": "Demo Credit Pathway", + "org_name": "example", + "email": "example@example.com", + "description": "Sample demo credit pathway!", + "destination_url": "http://example.edu/online/pathways/example-thinking", + "pathway_type": "credit", + "program_uuids": [ + "a156a6e2-de91-4ce7-947a-888943e6b12a" + ] + } + ] + } + parameters: [] + responses: + '200': + description: '' + tags: + - learner_home + parameters: + - name: program_uuid + in: path + required: true + type: string /learning_sequences/v1/course_outline/{course_key_str}: get: operationId: learning_sequences_v1_course_outline_read @@ -9338,16 +9651,6 @@ paths: operationId: user_v1_user_prefs_list description: DRF class for interacting with the UserPreference ORM parameters: - - name: key - in: query - description: key - required: false - type: string - - name: user - in: query - description: user - required: false - type: string - name: page in: query description: A page number within the paginated result set. @@ -9850,6 +10153,16 @@ paths: description: '' tags: - val + patch: + operationId: val_v0_videos_video-transcripts_partial_update + description: Partially update a video transcript, only supporting updating the + `provider` field. + parameters: [] + responses: + '200': + description: '' + tags: + - val delete: operationId: val_v0_videos_video-transcripts_delete description: Delete a video transcript instance with the given information. @@ -9870,6 +10183,16 @@ paths: description: '' tags: - val + patch: + operationId: val_v0_videos_video-transcripts_create_partial_update + description: Partially update a video transcript, only supporting updating the + `provider` field. + parameters: [] + responses: + '200': + description: '' + tags: + - val delete: operationId: val_v0_videos_video-transcripts_create_delete description: Delete a video transcript instance with the given information. diff --git a/mypy.ini b/mypy.ini index c6cac098c2..be694dc373 100644 --- a/mypy.ini +++ b/mypy.ini @@ -11,6 +11,7 @@ files = openedx/core/djangoapps/content/learning_sequences, openedx/core/djangoapps/content_staging, openedx/core/djangoapps/content_libraries, + openedx/core/djangoapps/programs/rest_api, openedx/core/djangoapps/xblock, openedx/core/lib/derived.py, openedx/core/types, diff --git a/openedx/core/djangoapps/programs/rest_api/v1/views.py b/openedx/core/djangoapps/programs/rest_api/v1/views.py index e271ec686a..69f47d268a 100644 --- a/openedx/core/djangoapps/programs/rest_api/v1/views.py +++ b/openedx/core/djangoapps/programs/rest_api/v1/views.py @@ -1,5 +1,6 @@ """Views for the Programs REST API v1.""" +from typing import Any, TYPE_CHECKING import logging from enterprise.models import EnterpriseCourseEnrollment @@ -16,80 +17,74 @@ from openedx.core.djangoapps.programs.utils import ( get_program_urls, ) +if TYPE_CHECKING: + from django.http import HttpRequest, HttpResponse + from django.contrib.auth.models import AnonymousUser, User # pylint: disable=imported-auth-user + from django.contrib.sites.models import Site + logger = logging.getLogger(__name__) class Programs(APIView): - """ - **Use Case** - - * Get a list of all programs in which request user has enrolled. - - **Example Request** - - GET /api/dashboard/v1/programs/{enterprise_uuid}/ - - **GET Parameters** - - A GET request must include the following parameters. - - * enterprise_uuid: UUID of an enterprise customer. - - **Example GET Response** - - [ - { - "uuid": "ff41a5eb-2a73-4933-8e80-a1c66068ed2c", - "title": "edX Demonstration Program", - "type": "MicroMasters", - "banner_image": { - "large": { - "url": "http://localhost:18381/media/programs/banner_images/ff41a5eb-2a73-4933-8e80.large.jpg", - "width": 1440, - "height": 480 - }, - "medium": { - "url": "http://localhost:18381/media/programs/banner_images/ff41a5eb-2a73-4933-8e80.medium.jpg", - "width": 726, - "height": 242 - }, - "small": { - "url": "http://localhost:18381/media/programs/banner_images/ff41a5eb-2a73-4933-8e80.small.jpg", - "width": 435, - "height": 145 - }, - "x-small": { - "url": "http://localhost:18381/media/programs/banner_images/ff41a5eb-2a73-4933-8e8.x-small.jpg", - "width": 348, - "height": 116 - } - }, - "authoring_organizations": [ - { - "key": "edX" - } - ], - "progress": { - "uuid": "ff41a5eb-2a73-4933-8e80-a1c66068ed2c", - "completed": 0, - "in_progress": 0, - "not_started": 2 - } - } - ] - """ + """Program endpoints""" permission_classes = (IsAuthenticated,) - def get(self, request, enterprise_uuid): - """ - Return a list of a enterprise learner's all enrolled programs with their progress. + def get(self, request: "HttpRequest", enterprise_uuid: str) -> "HttpResponse": + """For an enterprise learner, get list of enrolled programs with progress. - Args: - request (Request): DRF request object. - enterprise_uuid (string): UUID of an enterprise customer. + **Example Request** + + GET /api/dashboard/v1/programs/{enterprise_uuid}/ + + **Parameters** + + * `enterprise_uuid`: UUID of an enterprise customer. + + **Example Response** + + [ + { + "uuid": "ff41a5eb-2a73-4933-8e80-a1c66068ed2c", + "title": "Demonstration Program", + "type": "MicroMasters", + "banner_image": { + "large": { + "url": "http://example.com/images/foo.large.jpg", + "width": 1440, + "height": 480 + }, + "medium": { + "url": "http://example.com/images/foo.medium.jpg", + "width": 726, + "height": 242 + }, + "small": { + "url": "http://example.com/images/foo.small.jpg", + "width": 435, + "height": 145 + }, + "x-small": { + "url": "http://example.com/images/foo.x-small.jpg", + "width": 348, + "height": 116 + } + }, + "authoring_organizations": [ + { + "key": "example" + } + ], + "progress": { + "uuid": "ff41a5eb-2a73-4933-8e80-a1c66068ed2c", + "completed": 0, + "in_progress": 0, + "not_started": 2 + } + } + ] """ - user = request.user + user: "AnonymousUser | User" = request.user enrollments = self._get_enterprise_course_enrollments(enterprise_uuid, user) # return empty reponse if no enterprise enrollments exists for a user @@ -110,39 +105,37 @@ class Programs(APIView): return Response(programs) - def _combine_programs_data_and_progress(self, programs_data, programs_progress): + def _combine_programs_data_and_progress( + self, + programs_data: list[dict | None], + programs_progress: list[dict | None], + ) -> list[dict | None]: """ Return the combined program and progress data so that api clinet can easily process the data. """ for program_data in programs_data: program_progress = next( - ( - item - for item in programs_progress - if item["uuid"] == program_data["uuid"] - ), + (item for item in programs_progress if item["uuid"] == program_data["uuid"]), # type: ignore[index] None, ) - program_data["progress"] = program_progress + program_data["progress"] = program_progress # type: ignore[index] return programs_data - def _extract_minimal_required_programs_data(self, programs_data): + def _extract_minimal_required_programs_data(self, programs_data: list[dict | None]) -> list[dict[str, Any] | None]: """ Return only the minimal required program data need for program listing page. """ def transform(key, value): - transformers = { - "authoring_organizations": transform_authoring_organizations - } + transformers = {"authoring_organizations": transform_authoring_organizations} if key in transformers: return transformers[key](value) return value - def transform_authoring_organizations(authoring_organizations): + def transform_authoring_organizations(authoring_organizations) -> list[dict[str, Any]]: """ Extract only the required data for `authoring_organizations` for a program """ @@ -164,19 +157,22 @@ class Programs(APIView): "banner_image", "authoring_organizations", ] - programs = [] + programs: list[dict[str, Any] | None] = [] for program_data in programs_data: program = {} for program_data_key in program_data_keys: program[program_data_key] = transform( - program_data_key, program_data[program_data_key] + program_data_key, + program_data[program_data_key], # type: ignore[index] ) programs.append(program) return programs - def _get_enterprise_course_enrollments(self, enterprise_uuid, user): + def _get_enterprise_course_enrollments( + self, enterprise_uuid: str, user: "AnonymousUser | User" + ) -> list[CourseEnrollment]: """ Return only enterprise enrollments for a user. """ @@ -197,146 +193,129 @@ class Programs(APIView): class ProgramProgressDetailView(APIView): - """ - **Use Case** + """Endpoints For Program Progress Meter""" - * Get progress details of a learner enrolled in a program. + permission_classes = (IsAuthenticated,) - **Example Request** + def get(self, request: "HttpRequest", program_uuid: str) -> "HttpResponse": + """Retrieves progress details of a learner in a specified program. - GET api/dashboard/v1/programs/{program_uuid}/progress_details/ + **Example Request** - **GET Parameters** + GET api/dashboard/v1/programs/{program_uuid}/progress_details/ - A GET request must include the following parameters. + **Parameters** - * program_uuid: A string representation of uuid of the program. + * `program_uuid`: A string representation of the uuid of the program. - **GET Response Values** + **Response Values** If the request for information about the program is successful, an HTTP 200 "OK" response is returned. The HTTP 200 response has the following values. - * urls: Urls to enroll/purchase a course or view program record. + * `urls`: Urls to enroll/purchase a course or view program record. - * program_data: Holds meta information about the program. + * `program_data`: Holds meta information about the program. - * course_data: Learner's progress details for all courses in the program (in-progress/remaining/completed). + * `course_data`: Learner's progress details for all courses in the program (in-progress/remaining/completed). - * certificate_data: Details about learner's certificates status for all courses in the program and the + * `certificate_data`: Details about learner's certificates status for all courses in the program and the program itself. - * industry_pathways: Industry pathways for the program, comes under additional credit opportunities. + * `industry_pathways`: Industry pathways for the program, comes under additional credit opportunities. - * credit_pathways: Credit pathways for the program, comes under additional credit opportunities. + * `credit_pathways`: Credit pathways for the program, comes under additional credit opportunities. - **Example GET Response** + **Example Response** - { - "urls": { - "program_listing_url": "/dashboard/programs/", - "track_selection_url": "/course_modes/choose/", - "commerce_api_url": "/api/commerce/v1/baskets/", - "buy_button_url": "http://ecommerce.com/basket/add/?", - "program_record_url": "https://credentials.example.com/records/programs/121234235525242344" - }, - "program_data": { - "uuid": "a156a6e2-de91-4ce7-947a-888943e6b12a", - "title": "edX Demonstration Program", - "subtitle": "", - "type": "MicroMasters", - "status": "active", - "marketing_slug": "demo-program", - "marketing_url": "micromasters/demo-program", - "authoring_organizations": [], - "card_image_url": "http://edx.devstack.lms:18000/asset-v1:edX+DemoX+Demo_Course.jpg", - "is_program_eligible_for_one_click_purchase": false, - "pathway_ids": [ - 1, - 2 - ], - "is_learner_eligible_for_one_click_purchase": false, - "skus": ["AUD122342"], - }, - "course_data": { - "uuid": "a156a6e2-de91-4ce7-947a-888943e6b12a", - "completed": [], - "in_progress": [], - "not_started": [ + { + "urls": { + "program_listing_url": "/dashboard/programs/", + "track_selection_url": "/course_modes/choose/", + "commerce_api_url": "/api/commerce/v1/baskets/", + "buy_button_url": "http://example.com/basket/add/?", + "program_record_url": "https://example.com/records/programs/8675309" + }, + "program_data": { + "uuid": "a156a6e2-de91-4ce7-947a-888943e6b12a", + "title": "Demonstration Program", + "subtitle": "", + "type": "MicroMasters", + "status": "active", + "marketing_slug": "demo-program", + "marketing_url": "micromasters/demo-program", + "authoring_organizations": [], + "card_image_url": "http://example.com/asset-v1:DemoX+Demo_Course.jpg", + "is_program_eligible_for_one_click_purchase": false, + "pathway_ids": [ + 1, + 2 + ], + "is_learner_eligible_for_one_click_purchase": false, + "skus": ["AUD90210"], + }, + "course_data": { + "uuid": "a156a6e2-de91-4ce7-947a-888943e6b12a", + "completed": [], + "in_progress": [], + "not_started": [ + { + "key": "example+DemoX", + "uuid": "fe1a9ad4-a452-45cd-80e5-9babd3d43f96", + "title": "Demonstration Course", + "course_runs": [], + "entitlements": [], + "owners": [], + "image": "", + "short_description": "", + "type": "457f07ec-a78f-45b4-ba09-5fb176520d8a", + } + ], + }, + "certificate_data": [{ + "type": "course", + "title": "Demo Course", + 'url': "/certificates/8675309", + }], + "industry_pathways": [ { - "key": "edX+DemoX", - "uuid": "fe1a9ad4-a452-45cd-80e5-9babd3d43f96", - "title": "Demonstration Course", - "course_runs": [], - "entitlements": [], - "owners": [], - "image": "", - "short_description": "", - "type": "457f07ec-a78f-45b4-ba09-5fb176520d8a", + "id": 2, + "uuid": "1b8fadf1-f6aa-4282-94e3-325b922a027f", + "name": "Demo Industry Pathway", + "org_name": "example", + "email": "example@example.com", + "description": "Sample demo industry pathway", + "destination_url": "http://example.edu/online/pathways/example-methods", + "pathway_type": "industry", + "program_uuids": [ + "a156a6e2-de91-4ce7-947a-888943e6b12a" + ] } ], - }, - "certificate_data": [{ - "type": "course", - "title": "edX Demo Course", - 'url': "/certificates/6e57d3cce8e34cfcb60bd8e8b04r07e0", - }], - "industry_pathways": [ - { - "id": 2, - "uuid": "1b8fadf1-f6aa-4282-94e3-325b922a027f", - "name": "Demo Industry Pathway", - "org_name": "edX", - "email": "edx@edx.com", - "description": "Sample demo industry pathway", - "destination_url": "http://rit.edu/online/pathways/gtx-analytics-essential-tools-methods", - "pathway_type": "industry", - "program_uuids": [ - "a156a6e2-de91-4ce7-947a-888943e6b12a" - ] - } - ], - "credit_pathways": [ - { - "id": 1, - "uuid": "86b9701a-61e6-48a2-92eb-70a824521c1f", - "name": "Demo Credit Pathway", - "org_name": "edX", - "email": "edx@edx.com", - "description": "Sample demo credit pathway!", - "destination_url": "http://rit.edu/online/pathways/ritx-design-thinking", - "pathway_type": "credit", - "program_uuids": [ - "a156a6e2-de91-4ce7-947a-888943e6b12a" - ] - } - ] - } - """ - - permission_classes = (IsAuthenticated,) - - def get(self, request, program_uuid): + "credit_pathways": [ + { + "id": 1, + "uuid": "86b9701a-61e6-48a2-92eb-70a824521c1f", + "name": "Demo Credit Pathway", + "org_name": "example", + "email": "example@example.com", + "description": "Sample demo credit pathway!", + "destination_url": "http://example.edu/online/pathways/example-thinking", + "pathway_type": "credit", + "program_uuids": [ + "a156a6e2-de91-4ce7-947a-888943e6b12a" + ] + } + ] + } """ - Retrieves progress details of a user in a specified program. - - Args: - request (Request): Django request object. - program_uuid (string): URI element specifying uuid of the program. - - Return: - """ - user = request.user - site = request.site - program_data, course_data = get_program_and_course_data( - site, user, program_uuid - ) + user: "AnonymousUser | User" = request.user + site: "Site" = request.site + program_data, course_data = get_program_and_course_data(site, user, program_uuid) if not program_data: - return Response( - status=404, data={"error_code": "No program data available."} - ) + return Response(status=404, data={"error_code": "No program data available."}) certificate_data = get_certificates(user, program_data) program_data.pop("courses") @@ -345,9 +324,7 @@ class ProgramProgressDetailView(APIView): if not certificate_data: urls["program_record_url"] = None - industry_pathways, credit_pathways = get_industry_and_credit_pathways( - program_data, site - ) + industry_pathways, credit_pathways = get_industry_and_credit_pathways(program_data, site) return Response( { diff --git a/openedx/core/djangoapps/programs/utils.py b/openedx/core/djangoapps/programs/utils.py index 6d168640c1..31080ba466 100644 --- a/openedx/core/djangoapps/programs/utils.py +++ b/openedx/core/djangoapps/programs/utils.py @@ -211,7 +211,7 @@ class ProgramProgressMeter: return inverted_programs @cached_property - def engaged_programs(self): + def engaged_programs(self) -> list[dict | None]: """Derive a list of programs in which the given user is engaged. Returns: @@ -271,7 +271,7 @@ class ProgramProgressMeter: # An upgrade deadline of None means the course is always upgradeable. return any(not deadline or deadline and parse(deadline) > now for deadline in upgrade_deadlines) - def progress(self, programs=None, count_only=True): + def progress(self, programs: list[dict | None] | None = None, count_only: bool = True) -> list[dict | None]: """Gauge a user's progress towards program completion. Keyword Arguments: