feat: Add REST endpoints for problem response report generation that can be driven by MFEs. (#27313)

This commit is contained in:
Kshitij Sobti
2021-05-06 18:05:14 +00:00
committed by GitHub
parent 109f6b97f2
commit 161e3560dd
7 changed files with 3948 additions and 1193 deletions

View File

@@ -16,18 +16,136 @@ securityDefinitions:
security:
- Basic: []
paths:
/badges/v1/assertions/user/{username}/:
get:
operationId: badges_v1_assertions_user_read
summary: '**Use Cases**'
description: |-
Request a list of assertions for a user, optionally constrained to a course.
**Example Requests**
GET /api/badges/v1/assertions/user/{username}/
**Response Values**
Body comprised of a list of objects with the following fields:
* badge_class: The badge class the assertion was awarded for. Represented as an object
with the following fields:
* slug: The identifier for the badge class
* issuing_component: The software component responsible for issuing this badge.
* display_name: The display name of the badge.
* course_id: The course key of the course this badge is scoped to, or null if it isn't scoped to a course.
* description: A description of the award and its significance.
* criteria: A description of what is needed to obtain this award.
* image_url: A URL to the icon image used to represent this award.
* image_url: The baked assertion image derived from the badge_class icon-- contains metadata about the award
in its headers.
* assertion_url: The URL to the OpenBadges BadgeAssertion object, for verification by compatible tools
and software.
**Params**
* slug (optional): The identifier for a particular badge class to filter by.
* issuing_component (optional): The issuing component for a particular badge class to filter by
(requires slug to have been specified, or this will be ignored.) If slug is provided and this is not,
assumes the issuing_component should be empty.
* course_id (optional): Returns assertions that were awarded as part of a particular course. If slug is
provided, and this field is not specified, assumes that the target badge has an empty course_id field.
'*' may be used to get all badges with the specified slug, issuing_component combination across all courses.
**Returns**
* 200 on success, with a list of Badge Assertion objects.
* 403 if a user who does not have permission to masquerade as
another user specifies a username other than their own.
* 404 if the specified user does not exist
{
"count": 7,
"previous": null,
"num_pages": 1,
"results": [
{
"badge_class": {
"slug": "special_award",
"issuing_component": "openedx__course",
"display_name": "Very Special Award",
"course_id": "course-v1:edX+DemoX+Demo_Course",
"description": "Awarded for people who did something incredibly special",
"criteria": "Do something incredibly special.",
"image": "http://example.com/media/badge_classes/badges/special_xdpqpBv_9FYOZwN.png"
},
"image_url": "http://badges.example.com/media/issued/cd75b69fc1c979fcc1697c8403da2bdf.png",
"assertion_url": "http://badges.example.com/public/assertions/07020647-e772-44dd-98b7-d13d34335ca6"
},
...
]
}
parameters:
- name: page
in: query
description: A page number within the paginated result set.
required: false
type: integer
- name: page_size
in: query
description: Number of results to return per page.
required: false
type: integer
responses:
'200':
description: ''
schema:
required:
- count
- results
type: object
properties:
count:
type: integer
next:
type: string
format: uri
x-nullable: true
previous:
type: string
format: uri
x-nullable: true
results:
type: array
items:
$ref: '#/definitions/BadgeAssertion'
tags:
- badges
parameters:
- name: username
in: path
required: true
type: string
/bookmarks/v1/bookmarks/:
get:
operationId: bookmarks_v1_bookmarks_list
summary: Get a paginated list of bookmarks for a user.
description: "The list can be filtered by passing parameter \"course_id=<course_id>\"\
\nto only include bookmarks from a particular course.\n\nThe bookmarks are\
\ always sorted in descending order by creation date.\n\nEach page in the\
\ list contains 10 bookmarks by default. The page\nsize can be altered by\
\ passing parameter \"page_size=<page_size>\".\n\nTo include the optional\
\ fields pass the values in \"fields\" parameter\nas a comma separated list.\
\ Possible values are:\n\n* \"display_name\"\n* \"path\"\n\n**Example Requests**\n\
\nGET /api/bookmarks/v1/bookmarks/?course_id={course_id1}&fields=display_name,path"
description: |-
The list can be filtered by passing parameter "course_id=<course_id>"
to only include bookmarks from a particular course.
The bookmarks are always sorted in descending order by creation date.
Each page in the list contains 10 bookmarks by default. The page
size can be altered by passing parameter "page_size=<page_size>".
To include the optional fields pass the values in "fields" parameter
as a comma separated list. Possible values are:
* "display_name"
* "path"
**Example Requests**
GET /api/bookmarks/v1/bookmarks/?course_id={course_id1}&fields=display_name,path
parameters:
- name: page
in: query
@@ -55,11 +173,17 @@ paths:
post:
operationId: bookmarks_v1_bookmarks_create
summary: Create a new bookmark for a user.
description: "The POST request only needs to contain one parameter \"usage_id\"\
.\n\nHttp400 is returned if the format of the request is not correct,\nthe\
\ usage_id is invalid or a block corresponding to the usage_id\ncould not\
\ be found.\n\n**Example Requests**\n\nPOST /api/bookmarks/v1/bookmarks/\n\
Request data: {\"usage_id\": <usage-id>}"
description: |-
The POST request only needs to contain one parameter "usage_id".
Http400 is returned if the format of the request is not correct,
the usage_id is invalid or a block corresponding to the usage_id
could not be found.
**Example Requests**
POST /api/bookmarks/v1/bookmarks/
Request data: {"usage_id": <usage-id>}
parameters: []
responses:
'201':
@@ -71,7 +195,10 @@ paths:
get:
operationId: bookmarks_v1_bookmarks_read
summary: Get a specific bookmark for a user.
description: "**Example Requests**\n\nGET /api/bookmarks/v1/bookmarks/{username},{usage_id}?fields=display_name,path"
description: |-
**Example Requests**
GET /api/bookmarks/v1/bookmarks/{username},{usage_id}?fields=display_name,path
parameters: []
responses:
'200':
@@ -96,31 +223,209 @@ paths:
in: path
required: true
type: string
/bulk_enroll/v1/bulk_enroll:
post:
operationId: bulk_enroll_v1_bulk_enroll_create
summary: '**Use Case**'
description: |-
Enroll multiple users in one or more courses.
**Example Request**
POST /api/bulk_enroll/v1/bulk_enroll/ {
"auto_enroll": true,
"email_students": true,
"action": "enroll",
"courses": "course-v1:edX+Demo+123,course-v1:edX+Demo2+456",
"cohorts": "cohortA,cohortA",
"identifiers": "brandon@example.com,yamilah@example.com"
}
**POST Parameters**
A POST request can include the following parameters.
* auto_enroll: When set to `true`, students will be enrolled as soon
as they register.
* email_students: When set to `true`, students will be sent email
notifications upon enrollment.
* action: Can either be set to "enroll" or "unenroll". This determines the behavior
* cohorts: Optional. If provided, the number of items in the list should be equal to
the number of courses. first cohort coressponds with the first course and so on.
The learners will be added to the corresponding cohort.
**Response Values**
If the supplied course data is valid and the enrollments were
successful, an HTTP 200 "OK" response is returned.
The HTTP 200 response body contains a list of response data for each
enrollment. (See the `instructor.views.api.students_update_enrollment`
docstring for the specifics of the response data available for each
enrollment)
If a cohorts list is provided, additional 'cohort' keys will be added
to the 'before' and 'after' states.
parameters: []
responses:
'201':
description: ''
tags:
- bulk_enroll
parameters: []
/ccx/v0/ccx/:
get:
operationId: ccx_v0_ccx_list
summary: Gets a list of CCX Courses for a given Master Course.
description: Additional parameters are allowed for pagination purposes.
parameters:
- name: page
in: query
description: A page number within the paginated result set.
required: false
type: integer
- name: page_size
in: query
description: Number of results to return per page.
required: false
type: integer
responses:
'200':
description: ''
schema:
required:
- count
- results
type: object
properties:
count:
type: integer
next:
type: string
format: uri
x-nullable: true
previous:
type: string
format: uri
x-nullable: true
results:
type: array
items:
$ref: '#/definitions/CCXCourse'
tags:
- ccx
post:
operationId: ccx_v0_ccx_create
description: Creates a new CCX course for a given Master Course.
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/CCXCourse'
responses:
'201':
description: ''
schema:
$ref: '#/definitions/CCXCourse'
tags:
- ccx
parameters: []
/ccx/v0/ccx/{ccx_course_id}/:
get:
operationId: ccx_v0_ccx_read
description: Gets a CCX Course information.
parameters: []
responses:
'200':
description: ''
schema:
$ref: '#/definitions/CCXCourse'
tags:
- ccx
patch:
operationId: ccx_v0_ccx_partial_update
description: Modifies a CCX course.
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/CCXCourse'
responses:
'200':
description: ''
schema:
$ref: '#/definitions/CCXCourse'
tags:
- ccx
delete:
operationId: ccx_v0_ccx_delete
description: Deletes a CCX course.
parameters: []
responses:
'204':
description: ''
tags:
- ccx
parameters:
- name: ccx_course_id
in: path
required: true
type: string
/certificates/v0/certificates/{username}/:
get:
operationId: certificates_v0_certificates_read
summary: Get a paginated list of bookmarks for a user.
description: "**Use Case**\n\nGet the list of viewable course certificates for\
\ a specific user.\n\n**Example Request**\n\nGET /api/certificates/v0/certificates/{username}\n\
\n**GET Response Values**\n\n If the request for information about the\
\ user's certificates is successful,\n an HTTP 200 \"OK\" response is returned.\n\
\n The HTTP 200 response contains a list of dicts with the following keys/values.\n\
\n * username: A string representation of an user's username passed in\
\ the request.\n\n * course_id: A string representation of a Course ID.\n\
\n * course_display_name: A string representation of the Course name.\n\
\n * course_organization: A string representation of the organization associated\
\ with the Course.\n\n * certificate_type: A string representation of the\
\ certificate type.\n Can be honor|verified|professional\n\n * created_date:\
\ Date/time the certificate was created, in ISO-8661 format.\n\n * status:\
\ A string representation of the certificate status.\n\n * is_passing:\
\ True if the certificate has a passing status, False if not.\n\n * download_url:\
\ A string representation of the certificate url.\n\n * grade: A string\
\ representation of a float for the user's course grade.\n\n**Example GET\
\ Response**\n\n [{\n \"username\": \"bob\",\n \"course_id\"\
: \"edX/DemoX/Demo_Course\",\n \"certificate_type\": \"verified\",\n\
\ \"created_date\": \"2015-12-03T13:14:28+0000\",\n \"status\"\
: \"downloadable\",\n \"is_passing\": true,\n \"download_url\"\
: \"http://www.example.com/cert.pdf\",\n \"grade\": \"0.98\"\n }]"
description: |-
**Use Case**
Get the list of viewable course certificates for a specific user.
**Example Request**
GET /api/certificates/v0/certificates/{username}
**GET Response Values**
If the request for information about the user's certificates is successful,
an HTTP 200 "OK" response is returned.
The HTTP 200 response contains a list of dicts with the following keys/values.
* username: A string representation of an user's username passed in the request.
* course_id: A string representation of a Course ID.
* course_display_name: A string representation of the Course name.
* course_organization: A string representation of the organization associated with the Course.
* certificate_type: A string representation of the certificate type.
Can be honor|verified|professional
* created_date: Date/time the certificate was created, in ISO-8661 format.
* status: A string representation of the certificate status.
* is_passing: True if the certificate has a passing status, False if not.
* download_url: A string representation of the certificate url.
* grade: A string representation of a float for the user's course grade.
**Example GET Response**
[{
"username": "bob",
"course_id": "edX/DemoX/Demo_Course",
"certificate_type": "verified",
"created_date": "2015-12-03T13:14:28+0000",
"status": "downloadable",
"is_passing": true,
"download_url": "http://www.example.com/cert.pdf",
"grade": "0.98"
}]
parameters:
- name: username
in: path
@@ -267,9 +572,10 @@ paths:
/cohorts/v1/courses/{course_key_string}/users:
post:
operationId: cohorts_v1_courses_users_create
description: "View method that accepts an uploaded file (using key \"uploaded-file\"\
)\ncontaining cohort assignments for users. This method spawns a celery task\n\
to do the assignments, and a CSV file with results is provided via data downloads."
description: |-
View method that accepts an uploaded file (using key "uploaded-file")
containing cohort assignments for users. This method spawns a celery task
to do the assignments, and a CSV file with results is provided via data downloads.
parameters: []
responses:
'201':
@@ -426,13 +732,32 @@ paths:
post:
operationId: completion_v1_completion-batch_create
summary: Inserts a batch of completions.
description: "REST Endpoint Format:\n```\n{\n \"username\": \"username\",\n\
\ \"course_key\": \"course-key\",\n \"blocks\": {\n \"block_key1\": 0.0,\n\
\ \"block_key2\": 1.0,\n \"block_key3\": 1.0,\n }\n}\n```\n\n**Returns**\n\
\nA Response object, with an appropriate status code.\n\nIf successful, status\
\ code is 200.\n```\n{\n \"detail\" : _(\"ok\")\n}\n```\n\nOtherwise, a\
\ 400 or 404 may be returned, and the \"detail\" content will explain the\
\ error."
description: |-
REST Endpoint Format:
```
{
"username": "username",
"course_key": "course-key",
"blocks": {
"block_key1": 0.0,
"block_key2": 1.0,
"block_key3": 1.0,
}
}
```
**Returns**
A Response object, with an appropriate status code.
If successful, status code is 200.
```
{
"detail" : _("ok")
}
```
Otherwise, a 400 or 404 may be returned, and the "detail" content will explain the error.
parameters: []
responses:
'201':
@@ -467,17 +792,28 @@ paths:
: get:
operationId: course_experience_v1_course_deadlines_info_+]+api_course_experience_v1_course_deadlines_info_+]+(_|+)[_]+)_read
summary: '**Use Cases**'
description: "Request course deadline info for mobile\n\n**Example Requests**\n\
\n GET api/course_experience/v1/course_deadlines_info/{course_key}\n\n\
**Response Values**\n\n Body consists of the following fields:\n\n dates_banner_info:\
\ (obj)\n missed_deadlines: (bool) Whether the user has missed any\
\ graded content deadlines for the given course.\n missed_gated_content:\
\ (bool) Whether the user has missed any gated content for the given course.\n\
\ content_type_gating_enabled: (bool) Whether content type gating is\
\ enabled for this enrollment.\n verified_upgrade_link: (str) The URL\
\ to ecommerce IDA for purchasing the verified upgrade.\n\n**Returns**\n\n\
\ * 200 on success with above fields.\n * 401 if the user is not authenticated.\n\
\ * 404 if the course is not available or cannot be seen."
description: |-
Request course deadline info for mobile
**Example Requests**
GET api/course_experience/v1/course_deadlines_info/{course_key}
**Response Values**
Body consists of the following fields:
dates_banner_info: (obj)
missed_deadlines: (bool) Whether the user has missed any graded content deadlines for the given course.
missed_gated_content: (bool) Whether the user has missed any gated content for the given course.
content_type_gating_enabled: (bool) Whether content type gating is enabled for this enrollment.
verified_upgrade_link: (str) The URL to ecommerce IDA for purchasing the verified upgrade.
**Returns**
* 200 on success with above fields.
* 401 if the user is not authenticated.
* 404 if the course is not available or cannot be seen.
parameters: []
responses:
'200':
@@ -498,7 +834,17 @@ paths:
/course_experience/v1/reset_course_deadlines:
post:
operationId: course_experience_v1_reset_course_deadlines_create
description: ''
description: |-
Set the start_date of a schedule to today, which in turn will adjust due dates for
sequentials belonging to a self paced course
Request Parameters:
course_key: course key
research_event_data: any data that should be included in the research tracking event
Example: sending the location of where the reset deadlines banner (i.e. outline-tab)
IMPORTANT NOTE: If updates are happening to the logic here, ALSO UPDATE the `reset_course_deadlines`
function in common/djangoapps/util/views.py as well.
parameters: []
responses:
'201':
@@ -510,13 +856,20 @@ paths:
get:
operationId: course_goals_v0_course_goals_list
summary: API calls to create and update a course goal.
description: "Validates incoming data to ensure that course_key maps to an actual\n\
course and that the goal_key is a valid option.\n\n**Use Case**\n * Create\
\ a new goal for a user.\n * Update an existing goal for a user\n\n**Example\
\ Requests**\n POST /api/course_goals/v0/course_goals/\n Request\
\ data: {\"course_key\": <course-key>, \"goal_key\": \"<goal-key>\", \"user\"\
: \"<username>\"}\n\nReturns Http400 response if the course_key does not map\
\ to a known\ncourse or if the goal_key does not map to a valid goal key."
description: |-
Validates incoming data to ensure that course_key maps to an actual
course and that the goal_key is a valid option.
**Use Case**
* Create a new goal for a user.
* Update an existing goal for a user
**Example Requests**
POST /api/course_goals/v0/course_goals/
Request data: {"course_key": <course-key>, "goal_key": "<goal-key>", "user": "<username>"}
Returns Http400 response if the course_key does not map to a known
course or if the goal_key does not map to a valid goal key.
parameters:
- name: page
in: query
@@ -575,13 +928,20 @@ paths:
get:
operationId: course_goals_v0_course_goals_read
summary: API calls to create and update a course goal.
description: "Validates incoming data to ensure that course_key maps to an actual\n\
course and that the goal_key is a valid option.\n\n**Use Case**\n * Create\
\ a new goal for a user.\n * Update an existing goal for a user\n\n**Example\
\ Requests**\n POST /api/course_goals/v0/course_goals/\n Request\
\ data: {\"course_key\": <course-key>, \"goal_key\": \"<goal-key>\", \"user\"\
: \"<username>\"}\n\nReturns Http400 response if the course_key does not map\
\ to a known\ncourse or if the goal_key does not map to a valid goal key."
description: |-
Validates incoming data to ensure that course_key maps to an actual
course and that the goal_key is a valid option.
**Use Case**
* Create a new goal for a user.
* Update an existing goal for a user
**Example Requests**
POST /api/course_goals/v0/course_goals/
Request data: {"course_key": <course-key>, "goal_key": "<goal-key>", "user": "<username>"}
Returns Http400 response if the course_key does not map to a known
course or if the goal_key does not map to a valid goal key.
parameters: []
responses:
'200':
@@ -593,13 +953,20 @@ paths:
put:
operationId: course_goals_v0_course_goals_update
summary: API calls to create and update a course goal.
description: "Validates incoming data to ensure that course_key maps to an actual\n\
course and that the goal_key is a valid option.\n\n**Use Case**\n * Create\
\ a new goal for a user.\n * Update an existing goal for a user\n\n**Example\
\ Requests**\n POST /api/course_goals/v0/course_goals/\n Request\
\ data: {\"course_key\": <course-key>, \"goal_key\": \"<goal-key>\", \"user\"\
: \"<username>\"}\n\nReturns Http400 response if the course_key does not map\
\ to a known\ncourse or if the goal_key does not map to a valid goal key."
description: |-
Validates incoming data to ensure that course_key maps to an actual
course and that the goal_key is a valid option.
**Use Case**
* Create a new goal for a user.
* Update an existing goal for a user
**Example Requests**
POST /api/course_goals/v0/course_goals/
Request data: {"course_key": <course-key>, "goal_key": "<goal-key>", "user": "<username>"}
Returns Http400 response if the course_key does not map to a known
course or if the goal_key does not map to a valid goal key.
parameters:
- name: data
in: body
@@ -616,13 +983,20 @@ paths:
patch:
operationId: course_goals_v0_course_goals_partial_update
summary: API calls to create and update a course goal.
description: "Validates incoming data to ensure that course_key maps to an actual\n\
course and that the goal_key is a valid option.\n\n**Use Case**\n * Create\
\ a new goal for a user.\n * Update an existing goal for a user\n\n**Example\
\ Requests**\n POST /api/course_goals/v0/course_goals/\n Request\
\ data: {\"course_key\": <course-key>, \"goal_key\": \"<goal-key>\", \"user\"\
: \"<username>\"}\n\nReturns Http400 response if the course_key does not map\
\ to a known\ncourse or if the goal_key does not map to a valid goal key."
description: |-
Validates incoming data to ensure that course_key maps to an actual
course and that the goal_key is a valid option.
**Use Case**
* Create a new goal for a user.
* Update an existing goal for a user
**Example Requests**
POST /api/course_goals/v0/course_goals/
Request data: {"course_key": <course-key>, "goal_key": "<goal-key>", "user": "<username>"}
Returns Http400 response if the course_key does not map to a known
course or if the goal_key does not map to a valid goal key.
parameters:
- name: data
in: body
@@ -639,13 +1013,20 @@ paths:
delete:
operationId: course_goals_v0_course_goals_delete
summary: API calls to create and update a course goal.
description: "Validates incoming data to ensure that course_key maps to an actual\n\
course and that the goal_key is a valid option.\n\n**Use Case**\n * Create\
\ a new goal for a user.\n * Update an existing goal for a user\n\n**Example\
\ Requests**\n POST /api/course_goals/v0/course_goals/\n Request\
\ data: {\"course_key\": <course-key>, \"goal_key\": \"<goal-key>\", \"user\"\
: \"<username>\"}\n\nReturns Http400 response if the course_key does not map\
\ to a known\ncourse or if the goal_key does not map to a valid goal key."
description: |-
Validates incoming data to ensure that course_key maps to an actual
course and that the goal_key is a valid option.
**Use Case**
* Create a new goal for a user.
* Update an existing goal for a user
**Example Requests**
POST /api/course_goals/v0/course_goals/
Request data: {"course_key": <course-key>, "goal_key": "<goal-key>", "user": "<username>"}
Returns Http400 response if the course_key does not map to a known
course or if the goal_key does not map to a valid goal key.
parameters: []
responses:
'204':
@@ -662,22 +1043,39 @@ paths:
: get:
operationId: course_home_v1_course_metadata_+]+api_course_home_v1_course_metadata_+]+(_|+)[_]+)_read
summary: '**Use Cases**'
description: "Request Course metadata details for the Course Home MFE that every\
\ page needs.\n\n**Example Requests**\n\n GET api/course_home/v1/course_metadata/{course_key}\n\
\n**Response Values**\n\n Body consists of the following fields:\n\n \
\ course_id: (str) The Course's id (Course Run key)\n is_enrolled: (bool)\
\ Indicates if the user is enrolled in the course\n is_self_paced: (bool)\
\ Indicates if the course is self paced\n is_staff: (bool) Indicates if\
\ the user is staff\n original_user_is_staff: (bool) Indicates if the original\
\ user has staff access\n Used for when masquerading to distinguish\
\ between the original requesting user\n and the user being masqueraded\
\ as.\n number: (str) The Course's number\n org: (str) The Course's\
\ organization\n tabs: List of Course Tabs to display. They are serialized\
\ as:\n tab_id: (str) The tab's id\n title: (str) The title\
\ of the tab to display\n url: (str) The url to view the tab\n title:\
\ (str) The Course's display title\n\n**Returns**\n\n * 200 on success\
\ with above fields.\n * 404 if the course is not available or cannot be\
\ seen."
description: |-
Request Course metadata details for the Course Home MFE that every page needs.
**Example Requests**
GET api/course_home/v1/course_metadata/{course_key}
**Response Values**
Body consists of the following fields:
course_id: (str) The Course's id (Course Run key)
username: (str) The requesting (or masqueraded) user. Returns None for an
unauthenticated user.
is_enrolled: (bool) Indicates if the user is enrolled in the course
is_self_paced: (bool) Indicates if the course is self paced
is_staff: (bool) Indicates if the user is staff
original_user_is_staff: (bool) Indicates if the original user has staff access
Used for when masquerading to distinguish between the original requesting user
and the user being masqueraded as.
number: (str) The Course's number
org: (str) The Course's organization
tabs: List of Course Tabs to display. They are serialized as:
tab_id: (str) The tab's id
title: (str) The title of the tab to display
url: (str) The url to view the tab
title: (str) The Course's display title
celebrations: (dict) a dict of celebration data
**Returns**
* 200 on success with above fields.
* 404 if the course is not available or cannot be seen.
parameters: []
responses:
'200':
@@ -699,29 +1097,41 @@ paths:
: get:
operationId: course_home_v1_dates_+]+api_course_home_v1_dates_+]+(_|+)[_]+)_read
summary: '**Use Cases**'
description: "Request details for the Dates Tab\n\n**Example Requests**\n\n\
\ GET api/course_home/v1/dates/{course_key}\n\n**Response Values**\n\n\
\ Body consists of the following fields:\n\n course_date_blocks: List\
\ of serialized DateSummary objects. Each serialization has the following\
\ fields:\n complete: (bool) Meant to only be used by assignments.\
\ Indicates completeness for an\n assignment.\n date: (datetime)\
\ The date time corresponding for the event\n date_type: (str) The\
\ type of date (ex. course-start-date, assignment-due-date, etc.)\n \
\ description: (str) The description for the date event\n learner_has_access:\
\ (bool) Indicates if the learner has access to the date event\n link:\
\ (str) An absolute link to content related to the date event\n \
\ (ex. verified link or link to assignment)\n title: (str) The title\
\ of the date event\n dates_banner_info: (obj)\n content_type_gating_enabled:\
\ (bool) Whether content type gating is enabled for this enrollment.\n \
\ missed_deadlines: (bool) Indicates whether the user missed any graded\
\ content deadlines\n missed_gated_content: (bool) Indicates whether\
\ the user missed gated content\n verified_upgrade_link: (str) The\
\ link for upgrading to the Verified track in a course\n has_ended: (bool)\
\ Indicates whether course has ended\n learner_is_full_access: (bool) Indicates\
\ if the user is verified in the course\n user_timezone: (str) The user's\
\ preferred timezone\n\n**Returns**\n\n * 200 on success with above fields.\n\
\ * 401 if the user is not authenticated.\n * 404 if the course is not\
\ available or cannot be seen."
description: |-
Request details for the Dates Tab
**Example Requests**
GET api/course_home/v1/dates/{course_key}
**Response Values**
Body consists of the following fields:
course_date_blocks: List of serialized DateSummary objects. Each serialization has the following fields:
complete: (bool) Meant to only be used by assignments. Indicates completeness for an
assignment.
date: (datetime) The date time corresponding for the event
date_type: (str) The type of date (ex. course-start-date, assignment-due-date, etc.)
description: (str) The description for the date event
learner_has_access: (bool) Indicates if the learner has access to the date event
link: (str) An absolute link to content related to the date event
(ex. verified link or link to assignment)
title: (str) The title of the date event
dates_banner_info: (obj)
content_type_gating_enabled: (bool) Whether content type gating is enabled for this enrollment.
missed_deadlines: (bool) Indicates whether the user missed any graded content deadlines
missed_gated_content: (bool) Indicates whether the user missed gated content
verified_upgrade_link: (str) The link for upgrading to the Verified track in a course
has_ended: (bool) Indicates whether course has ended
learner_is_full_access: (bool) Indicates if the user is verified in the course
user_timezone: (str) The user's preferred timezone
**Returns**
* 200 on success with above fields.
* 401 if the user is not authenticated.
* 404 if the course is not available or cannot be seen.
parameters: []
responses:
'200':
@@ -754,54 +1164,83 @@ paths:
: get:
operationId: course_home_v1_outline_+]+api_course_home_v1_outline_+]+(_|+)[_]+)_read
summary: '**Use Cases**'
description: "Request details for the Outline Tab\n\n**Example Requests**\n\n\
\ GET api/course_home/v1/outline/{course_key}\n\n**Response Values**\n\n\
\ Body consists of the following fields:\n\n course_blocks:\n \
\ blocks: List of serialized Course Block objects. Each serialization has\
\ the following fields:\n id: (str) The usage ID of the block.\n\
\ type: (str) The type of block. Possible values the names of any\n\
\ XBlock type in the system, including custom blocks. Examples\
\ are\n course, chapter, sequential, vertical, html, problem,\
\ video, and\n discussion.\n display_name: (str)\
\ The display name of the block.\n lms_web_url: (str) The URL to\
\ the navigational container of the\n xBlock on the web LMS.\n\
\ children: (list) If the block has child blocks, a list of IDs\
\ of\n the child blocks.\n resume_block: (bool)\
\ Whether the block is the resume block\n course_goals:\n goal_options:\
\ (list) A list of goals where each goal is represented as a tuple (goal_key,\
\ goal_string)\n selected_goal:\n key: (str) The unique\
\ id given to the user's selected goal.\n text: (str) The display\
\ text for the user's selected goal.\n course_tools: List of serialized\
\ Course Tool objects. Each serialization has the following fields:\n \
\ analytics_id: (str) The unique id given to the tool.\n title:\
\ (str) The display title of the tool.\n url: (str) The link to access\
\ the tool.\n dates_banner_info: (obj)\n content_type_gating_enabled:\
\ (bool) Whether content type gating is enabled for this enrollment.\n \
\ missed_deadlines: (bool) Whether the user has missed any graded content\
\ deadlines for the given course.\n missed_gated_content: (bool) Whether\
\ the user has missed any gated content for the given course.\n verified_upgrade_link:\
\ (str) The URL to ecommerce IDA for purchasing the verified upgrade.\n \
\ dates_widget:\n course_date_blocks: List of serialized Course Dates\
\ objects. Each serialization has the following fields:\n complete:\
\ (bool) Meant to only be used by assignments. Indicates completeness for\
\ an\n assignment.\n date: (datetime) The date time\
\ corresponding for the event\n date_type: (str) The type of date\
\ (ex. course-start-date, assignment-due-date, etc.)\n description:\
\ (str) The description for the date event\n learner_has_access:\
\ (bool) Indicates if the learner has access to the date event\n \
\ link: (str) An absolute link to content related to the date event\n \
\ (ex. verified link or link to assignment)\n title:\
\ (str) The title of the date event\n dates_tab_link: (str) The URL\
\ to the Dates Tab\n user_timezone: (str) The timezone of the given\
\ user\n enroll_alert:\n can_enroll: (bool) Whether the user can\
\ enroll in the given course\n extra_text: (str)\n handouts_html:\
\ (str) Raw HTML for the handouts section of the course info\n has_ended:\
\ (bool) Indicates whether course has ended\n resume_course:\n has_visited_course:\
\ (bool) Whether the user has ever visited the course\n url: (str)\
\ The display name of the course block to resume\n welcome_message_html:\
\ (str) Raw HTML for the course updates banner\n\n**Returns**\n\n * 200\
\ on success with above fields.\n * 403 if the user is not authenticated.\n\
\ * 404 if the course is not available or cannot be seen."
description: |-
Request details for the Outline Tab
**Example Requests**
GET api/course_home/v1/outline/{course_key}
**Response Values**
Body consists of the following fields:
access_expiration: An object detailing when access to this course will expire
expiration_date: (str) When the access expires, in ISO 8601 notation
masquerading_expired_course: (bool) Whether this course is expired for the masqueraded user
upgrade_deadline: (str) Last chance to upgrade, in ISO 8601 notation (or None if can't upgrade anymore)
upgrade_url: (str) Upgrade linke (or None if can't upgrade anymore)
course_blocks:
blocks: List of serialized Course Block objects. Each serialization has the following fields:
id: (str) The usage ID of the block.
type: (str) The type of block. Possible values the names of any
XBlock type in the system, including custom blocks. Examples are
course, chapter, sequential, vertical, html, problem, video, and
discussion.
display_name: (str) The display name of the block.
lms_web_url: (str) The URL to the navigational container of the
xBlock on the web LMS.
children: (list) If the block has child blocks, a list of IDs of
the child blocks.
resume_block: (bool) Whether the block is the resume block
course_goals:
goal_options: (list) A list of goals where each goal is represented as a tuple (goal_key, goal_string)
selected_goal:
key: (str) The unique id given to the user's selected goal.
text: (str) The display text for the user's selected goal.
course_tools: List of serialized Course Tool objects. Each serialization has the following fields:
analytics_id: (str) The unique id given to the tool.
title: (str) The display title of the tool.
url: (str) The link to access the tool.
dates_banner_info: (obj)
content_type_gating_enabled: (bool) Whether content type gating is enabled for this enrollment.
missed_deadlines: (bool) Whether the user has missed any graded content deadlines for the given course.
missed_gated_content: (bool) Whether the user has missed any gated content for the given course.
verified_upgrade_link: (str) The URL to ecommerce IDA for purchasing the verified upgrade.
dates_widget:
course_date_blocks: List of serialized Course Dates objects. Each serialization has the following fields:
complete: (bool) Meant to only be used by assignments. Indicates completeness for an
assignment.
date: (datetime) The date time corresponding for the event
date_type: (str) The type of date (ex. course-start-date, assignment-due-date, etc.)
description: (str) The description for the date event
learner_has_access: (bool) Indicates if the learner has access to the date event
link: (str) An absolute link to content related to the date event
(ex. verified link or link to assignment)
title: (str) The title of the date event
dates_tab_link: (str) The URL to the Dates Tab
user_timezone: (str) The timezone of the given user
enroll_alert:
can_enroll: (bool) Whether the user can enroll in the given course
extra_text: (str)
handouts_html: (str) Raw HTML for the handouts section of the course info
has_ended: (bool) Indicates whether course has ended
offer: An object detailing upgrade discount information
code: (str) Checkout code
expiration_date: (str) Expiration of offer, in ISO 8601 notation
original_price: (str) Full upgrade price without checkout code; includes currency symbol
discounted_price: (str) Upgrade price with checkout code; includes currency symbol
percentage: (int) Amount of discount
upgrade_url: (str) Checkout URL
resume_course:
has_visited_course: (bool) Whether the user has ever visited the course
url: (str) The display name of the course block to resume
welcome_message_html: (str) Raw HTML for the course updates banner
**Returns**
* 200 on success with above fields.
* 404 if the course is not available or cannot be seen.
parameters: []
responses:
'200':
@@ -823,51 +1262,70 @@ paths:
: get:
operationId: course_home_v1_progress_+]+api_course_home_v1_progress_+]+(_|+)[_]+)_read
summary: '**Use Cases**'
description: "Request details for the Progress Tab\n\n**Example Requests**\n\
\n GET api/course_home/v1/progress/{course_key}\n\n**Response Values**\n\
\n Body consists of the following fields:\n\n certificate_data: Object\
\ containing information about the user's certificate status\n cert_web_view_url:\
\ (str) the url to view the certificate\n download_url: (str) the url\
\ to download the certificate\n is_downloadable: (bool) true if the\
\ status is downloadable and the download url is not None\n is_requestable:\
\ (bool) true if status is requesting and request_cert_url is not None\n \
\ msg: (str) message for the certificate status\n title: (str)\
\ title of the certificate status\n credit_course_requirements: An object\
\ containing the following fields\n dashboard_url: (str) the url to\
\ the user's dashboard\n eligibility_status: (str) the user's eligibility\
\ to receive a course credit\n requirements: object containing the\
\ following fields\n display_name: (str) the name of the requirement\
\ that should be displayed\n namespace: (str) the type that the\
\ requirement is\n min_grade: (float) the percentage formatted\
\ minimum grade needed for this requirement\n status: (str) the\
\ status of the requirement\n status_date: (str) the date the status\
\ was set\n credit_support_url: (str) the url to the support docs for purchasing\
\ a credit\n courseware_summary: List of serialized Chapters. each Chapter\
\ has the following fields:\n display_name: (str) a str of what the\
\ name of the Chapter is for displaying on the site\n subsections:\
\ List of serialized Subsections, each has the following fields:\n \
\ display_name: (str) a str of what the name of the Subsection is for\
\ displaying on the site\n due: (str) a DateTime string for when\
\ the Subsection is due\n format: (str) the format, if any, of\
\ the Subsection (Homework, Exam, etc)\n graded: (bool) whether\
\ or not the Subsection is graded\n graded_total: an object containing\
\ the following fields\n earned: (float) the amount of points\
\ the user earned\n possible: (float) the amount of points\
\ the user could have earned\n percent_graded: (float) the percentage\
\ of the points the user received for the subsection\n show_correctness:\
\ (str) a str representing whether to show the problem/practice scores based\
\ on due date\n show_grades: (bool) a bool for whether to show\
\ grades based on the access the user has\n url: (str) the absolute\
\ path url to the Subsection\n enrollment_mode: (str) a str representing\
\ the enrollment the user has ('audit', 'verified', ...)\n studio_url:\
\ (str) a str of the link to the grading in studio for the course\n user_timezone:\
\ (str) The user's preferred timezone\n verification_data: an object containing\n\
\ link: (str) the link to either start or retry verification\n \
\ status: (str) the status of the verification\n status_date: (str)\
\ the date time string of when the verification status was set\n\n\n\n**Returns**\n\
\n * 200 on success with above fields.\n * 302 if the user is not enrolled.\n\
\ * 403 if the user is not authenticated.\n * 404 if the course is not\
\ available or cannot be seen."
description: |-
Request details for the Progress Tab
**Example Requests**
GET api/course_home/v1/progress/{course_key}
**Response Values**
Body consists of the following fields:
end: (date) end date of the course
user_has_passing_grade: (bool) boolean on if the user has a passing grade in the course
has_scheduled_content: (bool) boolean on if the course has content scheduled with a release date in the future
certificate_data: Object containing information about the user's certificate status
cert_status: (str) the status of a user's certificate (full list of statuses are defined in
lms/djangoapps/certificates/models.py)
cert_web_view_url: (str) the url to view the certificate
download_url: (str) the url to download the certificate
completion_summary: Object containing unit completion counts with the following fields:
complete_count: (float) number of complete units
incomplete_count: (float) number of incomplete units
locked_count: (float) number of units where contains_gated_content is True
course_grade: Object containing the following fields:
is_passing: (bool) whether the user's grade is above the passing grade cutoff
letter_grade: (str) the user's letter grade based on the set grade range.
If user is passing, value may be 'A', 'B', 'C', 'D', 'Pass', otherwise none
percent: (float) the user's total graded percent in the course
section_scores: List of serialized Chapters. Each Chapter has the following fields:
display_name: (str) a str of what the name of the Chapter is for displaying on the site
subsections: List of serialized Subsections, each has the following fields:
assignment_type: (str) the format, if any, of the Subsection (Homework, Exam, etc)
display_name: (str) a str of what the name of the Subsection is for displaying on the site
has_graded_assignment: (bool) whether or not the Subsection is a graded assignment
num_points_earned: (int) the amount of points the user has earned for the given subsection
num_points_possible: (int) the total amount of points possible for the given subsection
percent_graded: (float) the percentage of total points the user has received a grade for in a given subsection
show_correctness: (str) a str representing whether to show the problem/practice scores based on due date
('always', 'never', 'past_due', values defined in
common/lib/xmodule/xmodule/modulestore/inheritance.py)
show_grades: (bool) a bool for whether to show grades based on the access the user has
url: (str) the absolute path url to the Subsection
enrollment_mode: (str) a str representing the enrollment the user has ('audit', 'verified', ...)
grading_policy:
assignment_policies: List of serialized assignment grading policy objects, each has the following fields:
num_droppable: (int) the number of lowest scored assignments that will not be counted towards the final grade
short_label: (str) the abbreviated name given to the assignment type
type: (str) the assignment type
weight: (float) the percent weight the given assigment type has on the overall grade
grade_range: an object containing the grade range cutoffs. The exact keys in the object can vary, but they
range from just 'Pass', to a combination of 'A', 'B', 'C', and 'D'. If a letter grade is present,
'Pass' is not included.
studio_url: (str) a str of the link to the grading in studio for the course
verification_data: an object containing
link: (str) the link to either start or retry verification
status: (str) the status of the verification
status_date: (str) the date time string of when the verification status was set
**Returns**
* 200 on success with above fields.
* 302 if the user is not enrolled.
* 401 if the user is not authenticated.
* 404 if the course is not available or cannot be seen.
parameters: []
responses:
'200':
@@ -900,28 +1358,46 @@ paths:
get:
operationId: course_modes_v1_courses_read
summary: View to list or create course modes for a course.
description: "**Use Case**\n\n List all course modes for a course, or create\
\ a new\n course mode.\n\n**Example Requests**\n\n GET /api/course_modes/v1/courses/{course_id}/\n\
\n Returns a list of all existing course modes for a course.\n\n \
\ POST /api/course_modes/v1/courses/{course_id}/\n\n Creates a new\
\ course mode in a course.\n\n**Response Values**\n\n For each HTTP verb\
\ below, an HTTP 404 \"Not Found\" response is returned if the\n requested\
\ course id does not exist.\n\n GET: If the request is successful, an HTTP\
\ 200 \"OK\" response is returned\n along with a list of course mode dictionaries\
\ within a course.\n The details are contained in a JSON dictionary as\
\ follows:\n\n * course_id: The course identifier.\n * mode_slug:\
\ The short name for the course mode.\n * mode_display_name: The verbose\
\ name for the course mode.\n * min_price: The minimum price for which\
\ a user can\n enroll in this mode.\n * currency: The currency\
\ of the listed prices.\n * expiration_datetime: The date and time after\
\ which\n users cannot enroll in the course in this mode (not required\
\ for POST).\n * expiration_datetime_is_explicit: Whether the expiration_datetime\
\ field was\n explicitly set (not required for POST).\n * description:\
\ A description of this mode (not required for POST).\n * sku: The SKU\
\ for this mode (for ecommerce purposes, not required for POST).\n *\
\ bulk_sku: The bulk SKU for this mode (for ecommerce purposes, not required\
\ for POST).\n\n POST: If the request is successful, an HTTP 201 \"Created\"\
\ response is returned."
description: |-
**Use Case**
List all course modes for a course, or create a new
course mode.
**Example Requests**
GET /api/course_modes/v1/courses/{course_id}/
Returns a list of all existing course modes for a course.
POST /api/course_modes/v1/courses/{course_id}/
Creates a new course mode in a course.
**Response Values**
For each HTTP verb below, an HTTP 404 "Not Found" response is returned if the
requested course id does not exist.
GET: If the request is successful, an HTTP 200 "OK" response is returned
along with a list of course mode dictionaries within a course.
The details are contained in a JSON dictionary as follows:
* course_id: The course identifier.
* mode_slug: The short name for the course mode.
* mode_display_name: The verbose name for the course mode.
* min_price: The minimum price for which a user can
enroll in this mode.
* currency: The currency of the listed prices.
* expiration_datetime: The date and time after which
users cannot enroll in the course in this mode (not required for POST).
* expiration_datetime_is_explicit: Whether the expiration_datetime field was
explicitly set (not required for POST).
* description: A description of this mode (not required for POST).
* sku: The SKU for this mode (for ecommerce purposes, not required for POST).
* bulk_sku: The bulk SKU for this mode (for ecommerce purposes, not required for POST).
POST: If the request is successful, an HTTP 201 "Created" response is returned.
parameters: []
responses:
'200':
@@ -935,28 +1411,46 @@ paths:
post:
operationId: course_modes_v1_courses_create
summary: View to list or create course modes for a course.
description: "**Use Case**\n\n List all course modes for a course, or create\
\ a new\n course mode.\n\n**Example Requests**\n\n GET /api/course_modes/v1/courses/{course_id}/\n\
\n Returns a list of all existing course modes for a course.\n\n \
\ POST /api/course_modes/v1/courses/{course_id}/\n\n Creates a new\
\ course mode in a course.\n\n**Response Values**\n\n For each HTTP verb\
\ below, an HTTP 404 \"Not Found\" response is returned if the\n requested\
\ course id does not exist.\n\n GET: If the request is successful, an HTTP\
\ 200 \"OK\" response is returned\n along with a list of course mode dictionaries\
\ within a course.\n The details are contained in a JSON dictionary as\
\ follows:\n\n * course_id: The course identifier.\n * mode_slug:\
\ The short name for the course mode.\n * mode_display_name: The verbose\
\ name for the course mode.\n * min_price: The minimum price for which\
\ a user can\n enroll in this mode.\n * currency: The currency\
\ of the listed prices.\n * expiration_datetime: The date and time after\
\ which\n users cannot enroll in the course in this mode (not required\
\ for POST).\n * expiration_datetime_is_explicit: Whether the expiration_datetime\
\ field was\n explicitly set (not required for POST).\n * description:\
\ A description of this mode (not required for POST).\n * sku: The SKU\
\ for this mode (for ecommerce purposes, not required for POST).\n *\
\ bulk_sku: The bulk SKU for this mode (for ecommerce purposes, not required\
\ for POST).\n\n POST: If the request is successful, an HTTP 201 \"Created\"\
\ response is returned."
description: |-
**Use Case**
List all course modes for a course, or create a new
course mode.
**Example Requests**
GET /api/course_modes/v1/courses/{course_id}/
Returns a list of all existing course modes for a course.
POST /api/course_modes/v1/courses/{course_id}/
Creates a new course mode in a course.
**Response Values**
For each HTTP verb below, an HTTP 404 "Not Found" response is returned if the
requested course id does not exist.
GET: If the request is successful, an HTTP 200 "OK" response is returned
along with a list of course mode dictionaries within a course.
The details are contained in a JSON dictionary as follows:
* course_id: The course identifier.
* mode_slug: The short name for the course mode.
* mode_display_name: The verbose name for the course mode.
* min_price: The minimum price for which a user can
enroll in this mode.
* currency: The currency of the listed prices.
* expiration_datetime: The date and time after which
users cannot enroll in the course in this mode (not required for POST).
* expiration_datetime_is_explicit: Whether the expiration_datetime field was
explicitly set (not required for POST).
* description: A description of this mode (not required for POST).
* sku: The SKU for this mode (for ecommerce purposes, not required for POST).
* bulk_sku: The bulk SKU for this mode (for ecommerce purposes, not required for POST).
POST: If the request is successful, an HTTP 201 "Created" response is returned.
parameters:
- name: data
in: body
@@ -979,35 +1473,54 @@ paths:
get:
operationId: course_modes_v1_courses_read
summary: View to retrieve, update, or delete a specific course mode for a course.
description: "**Use Case**\n\n Get or update course mode details for a specific\
\ course mode on a course.\n Or you may delete a specific course mode from\
\ a course.\n\n**Example Requests**\n\n GET /api/course_modes/v1/courses/{course_id}/{mode_slug}\n\
\n Returns details on an existing course mode for a course.\n\n \
\ PATCH /api/course_modes/v1/courses/{course_id}/{mode_slug}\n\n Updates\
\ (via merge) details of an existing course mode for a course.\n\n DELETE\
\ /api/course_modes/v1/courses/{course_id}/{mode_slug}\n\n Deletes\
\ an existing course mode for a course.\n\n**Response Values**\n\n For\
\ each HTTP verb below, an HTTP 404 \"Not Found\" response is returned if\
\ the\n requested course id does not exist, or the mode slug does not exist\
\ within the course.\n\n GET: If the request is successful, an HTTP 200\
\ \"OK\" response is returned\n along with a details for a single course\
\ mode within a course. The details are contained\n in a JSON dictionary\
\ as follows:\n\n * course_id: The course identifier.\n * mode_slug:\
\ The short name for the course mode.\n * mode_display_name: The verbose\
\ name for the course mode.\n * min_price: The minimum price for which\
\ a user can\n enroll in this mode.\n * currency: The currency\
\ of the listed prices.\n * expiration_datetime: The date and time after\
\ which\n users cannot enroll in the course in this mode (not required\
\ for PATCH).\n * expiration_datetime_is_explicit: Whether the expiration_datetime\
\ field was\n explicitly set (not required for PATCH).\n * description:\
\ A description of this mode (not required for PATCH).\n * sku: The SKU\
\ for this mode (for ecommerce purposes, not required for PATCH).\n *\
\ bulk_sku: The bulk SKU for this mode (for ecommerce purposes, not required\
\ for PATCH).\n\n PATCH: If the request is successful, an HTTP 204 \"No\
\ Content\" response is returned.\n If \"application/merge-patch+json\"\
\ is not the specified content type,\n a 415 \"Unsupported Media Type\"\
\ response is returned.\n\n DELETE: If the request is successful, an HTTP\
\ 204 \"No Content\" response is returned."
description: |-
**Use Case**
Get or update course mode details for a specific course mode on a course.
Or you may delete a specific course mode from a course.
**Example Requests**
GET /api/course_modes/v1/courses/{course_id}/{mode_slug}
Returns details on an existing course mode for a course.
PATCH /api/course_modes/v1/courses/{course_id}/{mode_slug}
Updates (via merge) details of an existing course mode for a course.
DELETE /api/course_modes/v1/courses/{course_id}/{mode_slug}
Deletes an existing course mode for a course.
**Response Values**
For each HTTP verb below, an HTTP 404 "Not Found" response is returned if the
requested course id does not exist, or the mode slug does not exist within the course.
GET: If the request is successful, an HTTP 200 "OK" response is returned
along with a details for a single course mode within a course. The details are contained
in a JSON dictionary as follows:
* course_id: The course identifier.
* mode_slug: The short name for the course mode.
* mode_display_name: The verbose name for the course mode.
* min_price: The minimum price for which a user can
enroll in this mode.
* currency: The currency of the listed prices.
* expiration_datetime: The date and time after which
users cannot enroll in the course in this mode (not required for PATCH).
* expiration_datetime_is_explicit: Whether the expiration_datetime field was
explicitly set (not required for PATCH).
* description: A description of this mode (not required for PATCH).
* sku: The SKU for this mode (for ecommerce purposes, not required for PATCH).
* bulk_sku: The bulk SKU for this mode (for ecommerce purposes, not required for PATCH).
PATCH: If the request is successful, an HTTP 204 "No Content" response is returned.
If "application/merge-patch+json" is not the specified content type,
a 415 "Unsupported Media Type" response is returned.
DELETE: If the request is successful, an HTTP 204 "No Content" response is returned.
parameters: []
responses:
'200':
@@ -1039,35 +1552,54 @@ paths:
delete:
operationId: course_modes_v1_courses_delete
summary: View to retrieve, update, or delete a specific course mode for a course.
description: "**Use Case**\n\n Get or update course mode details for a specific\
\ course mode on a course.\n Or you may delete a specific course mode from\
\ a course.\n\n**Example Requests**\n\n GET /api/course_modes/v1/courses/{course_id}/{mode_slug}\n\
\n Returns details on an existing course mode for a course.\n\n \
\ PATCH /api/course_modes/v1/courses/{course_id}/{mode_slug}\n\n Updates\
\ (via merge) details of an existing course mode for a course.\n\n DELETE\
\ /api/course_modes/v1/courses/{course_id}/{mode_slug}\n\n Deletes\
\ an existing course mode for a course.\n\n**Response Values**\n\n For\
\ each HTTP verb below, an HTTP 404 \"Not Found\" response is returned if\
\ the\n requested course id does not exist, or the mode slug does not exist\
\ within the course.\n\n GET: If the request is successful, an HTTP 200\
\ \"OK\" response is returned\n along with a details for a single course\
\ mode within a course. The details are contained\n in a JSON dictionary\
\ as follows:\n\n * course_id: The course identifier.\n * mode_slug:\
\ The short name for the course mode.\n * mode_display_name: The verbose\
\ name for the course mode.\n * min_price: The minimum price for which\
\ a user can\n enroll in this mode.\n * currency: The currency\
\ of the listed prices.\n * expiration_datetime: The date and time after\
\ which\n users cannot enroll in the course in this mode (not required\
\ for PATCH).\n * expiration_datetime_is_explicit: Whether the expiration_datetime\
\ field was\n explicitly set (not required for PATCH).\n * description:\
\ A description of this mode (not required for PATCH).\n * sku: The SKU\
\ for this mode (for ecommerce purposes, not required for PATCH).\n *\
\ bulk_sku: The bulk SKU for this mode (for ecommerce purposes, not required\
\ for PATCH).\n\n PATCH: If the request is successful, an HTTP 204 \"No\
\ Content\" response is returned.\n If \"application/merge-patch+json\"\
\ is not the specified content type,\n a 415 \"Unsupported Media Type\"\
\ response is returned.\n\n DELETE: If the request is successful, an HTTP\
\ 204 \"No Content\" response is returned."
description: |-
**Use Case**
Get or update course mode details for a specific course mode on a course.
Or you may delete a specific course mode from a course.
**Example Requests**
GET /api/course_modes/v1/courses/{course_id}/{mode_slug}
Returns details on an existing course mode for a course.
PATCH /api/course_modes/v1/courses/{course_id}/{mode_slug}
Updates (via merge) details of an existing course mode for a course.
DELETE /api/course_modes/v1/courses/{course_id}/{mode_slug}
Deletes an existing course mode for a course.
**Response Values**
For each HTTP verb below, an HTTP 404 "Not Found" response is returned if the
requested course id does not exist, or the mode slug does not exist within the course.
GET: If the request is successful, an HTTP 200 "OK" response is returned
along with a details for a single course mode within a course. The details are contained
in a JSON dictionary as follows:
* course_id: The course identifier.
* mode_slug: The short name for the course mode.
* mode_display_name: The verbose name for the course mode.
* min_price: The minimum price for which a user can
enroll in this mode.
* currency: The currency of the listed prices.
* expiration_datetime: The date and time after which
users cannot enroll in the course in this mode (not required for PATCH).
* expiration_datetime_is_explicit: Whether the expiration_datetime field was
explicitly set (not required for PATCH).
* description: A description of this mode (not required for PATCH).
* sku: The SKU for this mode (for ecommerce purposes, not required for PATCH).
* bulk_sku: The bulk SKU for this mode (for ecommerce purposes, not required for PATCH).
PATCH: If the request is successful, an HTTP 204 "No Content" response is returned.
If "application/merge-patch+json" is not the specified content type,
a 415 "Unsupported Media Type" response is returned.
DELETE: If the request is successful, an HTTP 204 "No Content" response is returned.
parameters: []
responses:
'204':
@@ -1089,22 +1621,41 @@ paths:
get:
operationId: courses_v1_blocks_list
summary: '**Use Case**'
description: "Returns the blocks in the course according to the requesting user's\n\
\ access level.\n\n**Example requests**:\n\n GET /api/courses/v1/blocks/?course_id=<course_id>\n\
\ GET /api/courses/v1/blocks/?course_id=<course_id>\n &username=anjali\n\
\ &depth=all\n &requested_fields=graded,format,student_view_multi_device,lti_url\n\
\ &block_counts=video\n &student_view_data=video\n &block_types_filter=problem,html\n\
\n**Parameters**:\n\n This view redirects to /api/courses/v1/blocks/<root_usage_key>/\
\ for the\n root usage key of the course specified by course_id. The view\
\ accepts\n all parameters accepted by :class:`BlocksView`, plus the following\n\
\ required parameter\n\n * course_id: (string, required) The ID of the\
\ course whose block data\n we want to return\n\n**Response Values**\n\
\n Responses are identical to those returned by :class:`BlocksView` when\n\
\ passed the root_usage_key of the requested course.\n\n If the course_id\
\ is not supplied, a 400: Bad Request is returned, with\n a message indicating\
\ that course_id is required.\n\n If an invalid course_id is supplied,\
\ a 400: Bad Request is returned,\n with a message indicating that the\
\ course_id is not valid."
description: |-
Returns the blocks in the course according to the requesting user's
access level.
**Example requests**:
GET /api/courses/v1/blocks/?course_id=<course_id>
GET /api/courses/v1/blocks/?course_id=<course_id>
&username=anjali
&depth=all
&requested_fields=graded,format,student_view_multi_device,lti_url
&block_counts=video
&student_view_data=video
&block_types_filter=problem,html
**Parameters**:
This view redirects to /api/courses/v1/blocks/<root_usage_key>/ for the
root usage key of the course specified by course_id. The view accepts
all parameters accepted by :class:`BlocksView`, plus the following
required parameter
* course_id: (string, required) The ID of the course whose block data
we want to return
**Response Values**
Responses are identical to those returned by :class:`BlocksView` when
passed the root_usage_key of the requested course.
If the course_id is not supplied, a 400: Bad Request is returned, with
a message indicating that course_id is required.
If an invalid course_id is supplied, a 400: Bad Request is returned,
with a message indicating that the course_id is not valid.
parameters:
- name: page
in: query
@@ -1126,100 +1677,180 @@ paths:
: get:
operationId: courses_v1_blocks_courses_v1_blocks__[_]+_[_]+_[_]+_[@]+(:@[_read
summary: '**Use Case**'
description: "Returns the blocks within the requested block tree according to\
\ the\n requesting user's access level.\n\n**Example requests**:\n\n \
\ GET /api/courses/v1/blocks/<root_block_usage_id>/?depth=all\n GET /api/courses/v1/blocks/<usage_id>/?\n\
\ username=anjali\n &depth=all\n &requested_fields=graded,format,student_view_multi_device,lti_url,due\n\
\ &block_counts=video\n &student_view_data=video\n &block_types_filter=problem,html\n\
\n**Parameters**:\n\n * all_blocks: (boolean) Provide a value of \"true\"\
\ to return all\n blocks. Returns all blocks only if the requesting user\
\ has course\n staff permissions. Blocks that are visible only to specific\
\ learners\n (for example, based on group membership or randomized content)\
\ are\n all included. If all_blocks is not specified, you must specify\
\ the\n username for the user whose course blocks are requested.\n\n\
\ * username: (string) Required, unless ``all_blocks`` is specified.\n\
\ Specify the username for the user whose course blocks are requested.\n\
\ A blank/empty username can be used to request the blocks accessible\n\
\ to anonymous users (for public courses). Only users with course staff\n\
\ permissions can specify other users' usernames. If a username is\n\
\ specified, results include blocks that are visible to that user,\n\
\ including those based on group or cohort membership or randomized\n\
\ content assigned to that user.\n\n Example: username=anjali\n\
\ username=''\n username\n\n * student_view_data:\
\ (list) Indicates for which block types to return\n student_view_data.\n\
\n Example: student_view_data=video\n\n * block_counts: (list) Indicates\
\ for which block types to return the\n aggregate count of the blocks.\n\
\n Example: block_counts=video,problem\n\n * requested_fields: (list)\
\ Indicates which additional fields to return\n for each block. For\
\ a list of available fields see under `Response\n Values -> blocks`,\
\ below.\n\n The following fields are always returned: id, type, display_name\n\
\n Example: requested_fields=graded,format,student_view_multi_device\n\
\n * depth: (integer or all) Indicates how deep to traverse into the blocks\n\
\ hierarchy. A value of all means the entire hierarchy.\n\n Default\
\ is 0\n\n Example: depth=all\n\n * nav_depth: (integer)\n\n \
\ WARNING: nav_depth is not supported, and may be removed at any time.\n\n\
\ Indicates how far deep to traverse into the\n course hierarchy\
\ before bundling all the descendants.\n\n Default is 3 since typical\
\ navigational views of the course show a\n maximum of chapter->sequential->vertical.\n\
\n Example: nav_depth=3\n\n * return_type (string) Indicates in what\
\ data type to return the\n blocks.\n\n Default is dict. Supported\
\ values are: dict, list\n\n Example: return_type=dict\n\n * block_types_filter:\
\ (list) Requested types of blocks used to filter the final result\n \
\ of returned blocks. Possible values include sequential, vertical, html,\
\ problem,\n video, and discussion.\n\n Example: block_types_filter=vertical,html\n\
\n**Response Values**\n\n The following fields are returned with a successful\
\ response.\n\n * root: The ID of the root node of the requested course\
\ block\n structure.\n\n * blocks: A dictionary or list, based on\
\ the value of the\n \"return_type\" parameter. Maps block usage IDs\
\ to a collection of\n information about each block. Each block contains\
\ the following\n fields.\n\n * id: (string) The usage ID of the\
\ block.\n\n * type: (string) The type of block. Possible values the\
\ names of any\n XBlock type in the system, including custom blocks.\
\ Examples are\n course, chapter, sequential, vertical, html, problem,\
\ video, and\n discussion.\n\n * display_name: (string) The display\
\ name of the block.\n\n * children: (list) If the block has child blocks,\
\ a list of IDs of\n the child blocks. Returned only if \"children\"\
\ is included in the\n \"requested_fields\" parameter.\n\n * completion:\
\ (float or None) The level of completion of the block.\n Its value\
\ can vary between 0.0 and 1.0 or be equal to None\n if block is not\
\ completable. Returned only if \"completion\"\n is included in the\
\ \"requested_fields\" parameter.\n\n * block_counts: (dict) For each\
\ block type specified in the\n block_counts parameter to the endpoint,\
\ the aggregate number of\n blocks of that type for this block and\
\ all of its descendants.\n\n * graded (boolean) Whether or not the block\
\ or any of its descendants\n is graded. Returned only if \"graded\"\
\ is included in the\n \"requested_fields\" parameter.\n\n * format:\
\ (string) The assignment type of the block. Possible values\n can\
\ be \"Homework\", \"Lab\", \"Midterm Exam\", and \"Final Exam\".\n \
\ Returned only if \"format\" is included in the \"requested_fields\"\n \
\ parameter.\n\n * student_view_data: (dict) The JSON data for\
\ this block.\n Returned only if the \"student_view_data\" input parameter\
\ contains\n this block's type.\n\n * student_view_url: (string)\
\ The URL to retrieve the HTML rendering\n of this block's student\
\ view. The HTML could include CSS and\n Javascript code. This field\
\ can be used in combination with the\n student_view_multi_device field\
\ to decide whether to display this\n content to the user.\n\n \
\ This URL can be used as a fallback if the student_view_data for\n \
\ this block type is not supported by the client or the block.\n\n \
\ * student_view_multi_device: (boolean) Whether or not the HTML of\n \
\ the student view that is rendered at \"student_view_url\" supports\n\
\ responsive web layouts, touch-based inputs, and interactive state\n\
\ management for a variety of device sizes and types, including\n \
\ mobile and touch devices. Returned only if\n \"student_view_multi_device\"\
\ is included in the \"requested_fields\"\n parameter.\n\n * lms_web_url:\
\ (string) The URL to the navigational container of the\n xBlock on\
\ the web LMS. This URL can be used as a further fallback\n if the\
\ student_view_url and the student_view_data fields are not\n supported.\n\
\n * lti_url: The block URL for an LTI consumer. Returned only if the\n\
\ \"ENABLE_LTI_PROVIDER\" Django settign is set to \"True\".\n\n \
\ * due: The due date of the block. Returned only if \"due\" is included\n\
\ in the \"requested_fields\" parameter.\n\n * show_correctness:\
\ Whether to show scores/correctness to learners for the current sequence\
\ or problem.\n Returned only if \"show_correctness\" is included in\
\ the \"requested_fields\" parameter.\n\n * Additional XBlock fields\
\ can be included in the response if they are\n configured via the\
\ COURSE_BLOCKS_API_EXTRA_FIELDS Django setting and\n requested via\
\ the \"requested_fields\" parameter."
description: |-
Returns the blocks within the requested block tree according to the
requesting user's access level.
**Example requests**:
GET /api/courses/v1/blocks/<root_block_usage_id>/?depth=all
GET /api/courses/v1/blocks/<usage_id>/?
username=anjali
&depth=all
&requested_fields=graded,format,student_view_multi_device,lti_url,due
&block_counts=video
&student_view_data=video
&block_types_filter=problem,html
**Parameters**:
* all_blocks: (boolean) Provide a value of "true" to return all
blocks. Returns all blocks only if the requesting user has course
staff permissions. Blocks that are visible only to specific learners
(for example, based on group membership or randomized content) are
all included. If all_blocks is not specified, you must specify the
username for the user whose course blocks are requested.
* username: (string) Required, unless ``all_blocks`` is specified.
Specify the username for the user whose course blocks are requested.
A blank/empty username can be used to request the blocks accessible
to anonymous users (for public courses). Only users with course staff
permissions can specify other users' usernames. If a username is
specified, results include blocks that are visible to that user,
including those based on group or cohort membership or randomized
content assigned to that user.
Example: username=anjali
username=''
username
* student_view_data: (list) Indicates for which block types to return
student_view_data.
Example: student_view_data=video
* block_counts: (list) Indicates for which block types to return the
aggregate count of the blocks.
Example: block_counts=video,problem
* requested_fields: (list) Indicates which additional fields to return
for each block. For a list of available fields see under `Response
Values -> blocks`, below.
The following fields are always returned: id, type, display_name
Example: requested_fields=graded,format,student_view_multi_device
* depth: (integer or all) Indicates how deep to traverse into the blocks
hierarchy. A value of all means the entire hierarchy.
Default is 0
Example: depth=all
* nav_depth: (integer)
WARNING: nav_depth is not supported, and may be removed at any time.
Indicates how far deep to traverse into the
course hierarchy before bundling all the descendants.
Default is 3 since typical navigational views of the course show a
maximum of chapter->sequential->vertical.
Example: nav_depth=3
* return_type (string) Indicates in what data type to return the
blocks.
Default is dict. Supported values are: dict, list
Example: return_type=dict
* block_types_filter: (list) Requested types of blocks used to filter the final result
of returned blocks. Possible values include sequential, vertical, html, problem,
video, and discussion.
Example: block_types_filter=vertical,html
**Response Values**
The following fields are returned with a successful response.
* root: The ID of the root node of the requested course block
structure.
* blocks: A dictionary or list, based on the value of the
"return_type" parameter. Maps block usage IDs to a collection of
information about each block. Each block contains the following
fields.
* id: (string) The usage ID of the block.
* type: (string) The type of block. Possible values the names of any
XBlock type in the system, including custom blocks. Examples are
course, chapter, sequential, vertical, html, problem, video, and
discussion.
* display_name: (string) The display name of the block.
* children: (list) If the block has child blocks, a list of IDs of
the child blocks. Returned only if "children" is included in the
"requested_fields" parameter.
* completion: (float or None) The level of completion of the block.
Its value can vary between 0.0 and 1.0 or be equal to None
if block is not completable. Returned only if "completion"
is included in the "requested_fields" parameter.
* block_counts: (dict) For each block type specified in the
block_counts parameter to the endpoint, the aggregate number of
blocks of that type for this block and all of its descendants.
* graded (boolean) Whether or not the block or any of its descendants
is graded. Returned only if "graded" is included in the
"requested_fields" parameter.
* format: (string) The assignment type of the block. Possible values
can be "Homework", "Lab", "Midterm Exam", and "Final Exam".
Returned only if "format" is included in the "requested_fields"
parameter.
* student_view_data: (dict) The JSON data for this block.
Returned only if the "student_view_data" input parameter contains
this block's type.
* student_view_url: (string) The URL to retrieve the HTML rendering
of this block's student view. The HTML could include CSS and
Javascript code. This field can be used in combination with the
student_view_multi_device field to decide whether to display this
content to the user.
This URL can be used as a fallback if the student_view_data for
this block type is not supported by the client or the block.
* student_view_multi_device: (boolean) Whether or not the HTML of
the student view that is rendered at "student_view_url" supports
responsive web layouts, touch-based inputs, and interactive state
management for a variety of device sizes and types, including
mobile and touch devices. Returned only if
"student_view_multi_device" is included in the "requested_fields"
parameter.
* lms_web_url: (string) The URL to the navigational container of the
xBlock on the web. This URL can be used as a further fallback
if the student_view_url and the student_view_data fields are not
supported. Will direct to either the "New" (micro-frontend) or
"Legacy" (Django-template-rendered) frontend experience depending
on which experience is active.
* legacy_web_url: (string) Like `lms_web_url`, but always directs to
the "Legacy" frontend experience. Should only be used for
transitional purposes; will be removed as part of DEPR-109.
* lti_url: The block URL for an LTI consumer. Returned only if the
"ENABLE_LTI_PROVIDER" Django settign is set to "True".
* due: The due date of the block. Returned only if "due" is included
in the "requested_fields" parameter.
* show_correctness: Whether to show scores/correctness to learners for the current sequence or problem.
Returned only if "show_correctness" is included in the "requested_fields" parameter.
* Additional XBlock fields can be included in the response if they are
configured via the COURSE_BLOCKS_API_EXTRA_FIELDS Django setting and
requested via the "requested_fields" parameter.
parameters:
- name: page
in: query
@@ -1249,26 +1880,54 @@ paths:
get:
operationId: courses_v1_course_ids_list
summary: '**Use Cases**'
description: "Request a list of course IDs for all courses the specified user\
\ can\n access based on the provided parameters.\n\n**Example Requests**\n\
\n GET /api/courses/v1/courses_ids/\n\n**Response Values**\n\n Body\
\ comprises a list of course ids and pagination details.\n\n**Parameters**\n\
\n username (optional):\n The username of the specified user whose\
\ visible courses we\n want to see.\n\n role (required):\n \
\ Course ids are filtered such that only those for which the\n user\
\ has the specified role are returned. Role can be \"staff\"\n or \"\
instructor\".\n Case-insensitive.\n\n**Returns**\n\n * 200 on success,\
\ with a list of course ids and pagination details\n * 400 if an invalid\
\ parameter was sent or the username was not provided\n for an authenticated\
\ request.\n * 403 if a user who does not have permission to masquerade\
\ as\n another user who specifies a username other than their own.\n\
\ * 404 if the specified user does not exist, or the requesting user does\n\
\ not have permission to view their courses.\n\n Example response:\n\
\n {\n \"results\":\n [\n \
\ \"course-v1:edX+DemoX+Demo_Course\"\n ],\n \
\ \"pagination\": {\n \"previous\": null,\n \
\ \"num_pages\": 1,\n \"next\": null,\n \"\
count\": 1\n }\n }"
description: |-
Request a list of course IDs for all courses the specified user can
access based on the provided parameters.
**Example Requests**
GET /api/courses/v1/courses_ids/
**Response Values**
Body comprises a list of course ids and pagination details.
**Parameters**
username (optional):
The username of the specified user whose visible courses we
want to see.
role (required):
Course ids are filtered such that only those for which the
user has the specified role are returned. Role can be "staff"
or "instructor".
Case-insensitive.
**Returns**
* 200 on success, with a list of course ids and pagination details
* 400 if an invalid parameter was sent or the username was not provided
for an authenticated request.
* 403 if a user who does not have permission to masquerade as
another user who specifies a username other than their own.
* 404 if the specified user does not exist, or the requesting user does
not have permission to view their courses.
Example response:
{
"results":
[
"course-v1:edX+DemoX+Demo_Course"
],
"pagination": {
"previous": null,
"num_pages": 1,
"next": null,
"count": 1
}
}
parameters:
- name: page
in: query
@@ -1310,36 +1969,68 @@ paths:
get:
operationId: courses_v1_courses_list
summary: '**Use Cases**'
description: "Request information on all courses visible to the specified user.\n\
\n**Example Requests**\n\n GET /api/courses/v1/courses/\n\n**Response Values**\n\
\n Body comprises a list of objects as returned by `CourseDetailView`.\n\
\n**Parameters**\n\n search_term (optional):\n Search term to filter\
\ courses (used by ElasticSearch).\n\n username (optional):\n The\
\ username of the specified user whose visible courses we\n want to\
\ see. The username is not required only if the API is\n requested\
\ by an Anonymous user.\n\n org (optional):\n If specified, visible\
\ `CourseOverview` objects are filtered\n such that only those belonging\
\ to the organization with the\n provided org code (e.g., \"HarvardX\"\
) are returned.\n Case-insensitive.\n\n**Returns**\n\n * 200 on\
\ success, with a list of course discovery objects as returned\n by `CourseDetailView`.\n\
\ * 400 if an invalid parameter was sent or the username was not provided\n\
\ for an authenticated request.\n * 403 if a user who does not have\
\ permission to masquerade as\n another user specifies a username other\
\ than their own.\n * 404 if the specified user does not exist, or the\
\ requesting user does\n not have permission to view their courses.\n\
\n Example response:\n\n [\n {\n \"blocks_url\"\
: \"/api/courses/v1/blocks/?course_id=edX%2Fexample%2F2012_Fall\",\n \
\ \"media\": {\n \"course_image\": {\n \"\
uri\": \"/c4x/edX/example/asset/just_a_test.jpg\",\n \"name\"\
: \"Course Image\"\n }\n },\n \"description\"\
: \"An example course.\",\n \"end\": \"2015-09-19T18:00:00Z\",\n\
\ \"enrollment_end\": \"2015-07-15T00:00:00Z\",\n \"\
enrollment_start\": \"2015-06-15T00:00:00Z\",\n \"course_id\":\
\ \"edX/example/2012_Fall\",\n \"name\": \"Example Course\",\n\
\ \"number\": \"example\",\n \"org\": \"edX\",\n \
\ \"start\": \"2015-07-17T12:00:00Z\",\n \"start_display\"\
: \"July 17, 2015\",\n \"start_type\": \"timestamp\"\n \
\ }\n ]"
description: |-
Request information on all courses visible to the specified user.
**Example Requests**
GET /api/courses/v1/courses/
**Response Values**
Body comprises a list of objects as returned by `CourseDetailView`.
**Parameters**
search_term (optional):
Search term to filter courses (used by ElasticSearch).
username (optional):
The username of the specified user whose visible courses we
want to see. The username is not required only if the API is
requested by an Anonymous user.
org (optional):
If specified, visible `CourseOverview` objects are filtered
such that only those belonging to the organization with the
provided org code (e.g., "HarvardX") are returned.
Case-insensitive.
**Returns**
* 200 on success, with a list of course discovery objects as returned
by `CourseDetailView`.
* 400 if an invalid parameter was sent or the username was not provided
for an authenticated request.
* 403 if a user who does not have permission to masquerade as
another user specifies a username other than their own.
* 404 if the specified user does not exist, or the requesting user does
not have permission to view their courses.
Example response:
[
{
"blocks_url": "/api/courses/v1/blocks/?course_id=edX%2Fexample%2F2012_Fall",
"media": {
"course_image": {
"uri": "/c4x/edX/example/asset/just_a_test.jpg",
"name": "Course Image"
}
},
"description": "An example course.",
"end": "2015-09-19T18:00:00Z",
"enrollment_end": "2015-07-15T00:00:00Z",
"enrollment_start": "2015-06-15T00:00:00Z",
"course_id": "edX/example/2012_Fall",
"name": "Example Course",
"number": "example",
"org": "edX",
"start": "2015-07-17T12:00:00Z",
"start_display": "July 17, 2015",
"start_type": "timestamp"
}
]
parameters:
- name: page
in: query
@@ -1381,51 +2072,88 @@ paths:
: get:
operationId: courses_v1_courses_+]+api_courses_v1_courses_+]+(_|+)[_]+)_read
summary: '**Use Cases**'
description: "Request details for a course\n\n**Example Requests**\n\n GET\
\ /api/courses/v1/courses/{course_key}/\n\n**Response Values**\n\n Body\
\ consists of the following fields:\n\n * effort: A textual description\
\ of the weekly hours of effort expected\n in the course.\n * end:\
\ Date the course ends, in ISO 8601 notation\n * enrollment_end: Date enrollment\
\ ends, in ISO 8601 notation\n * enrollment_start: Date enrollment begins,\
\ in ISO 8601 notation\n * id: A unique identifier of the course; a serialized\
\ representation\n of the opaque key identifying the course.\n *\
\ media: An object that contains named media items. Included here:\n \
\ * course_image: An image to show for the course. Represented\n \
\ as an object with the following fields:\n * uri: The location\
\ of the image\n * name: Name of the course\n * number: Catalog number\
\ of the course\n * org: Name of the organization that owns the course\n\
\ * overview: A possibly verbose HTML textual description of the course.\n\
\ Note: this field is only included in the Course Detail view, not\n\
\ the Course List view.\n * short_description: A textual description\
\ of the course\n * start: Date the course begins, in ISO 8601 notation\n\
\ * start_display: Readably formatted start of the course\n * start_type:\
\ Hint describing how `start_display` is set. One of:\n * `\"string\"\
`: manually set by the course author\n * `\"timestamp\"`: generated\
\ from the `start` timestamp\n * `\"empty\"`: no start date is specified\n\
\ * pacing: Course pacing. Possible values: instructor, self\n\n Deprecated\
\ fields:\n\n * blocks_url: Used to fetch the course blocks\n * course_id:\
\ Course key (use 'id' instead)\n\n**Parameters:**\n\n username (optional):\n\
\ The username of the specified user for whom the course data\n \
\ is being accessed. The username is not only required if the API is\n\
\ requested by an Anonymous user.\n\n**Returns**\n\n * 200 on success\
\ with above fields.\n * 400 if an invalid parameter was sent or the username\
\ was not provided\n for an authenticated request.\n * 403 if a user\
\ who does not have permission to masquerade as\n another user specifies\
\ a username other than their own.\n * 404 if the course is not available\
\ or cannot be seen.\n\n Example response:\n\n {\n \"\
blocks_url\": \"/api/courses/v1/blocks/?course_id=edX%2Fexample%2F2012_Fall\"\
,\n \"media\": {\n \"course_image\": {\n \
\ \"uri\": \"/c4x/edX/example/asset/just_a_test.jpg\",\n \
\ \"name\": \"Course Image\"\n }\n \
\ },\n \"description\": \"An example course.\",\n \"\
end\": \"2015-09-19T18:00:00Z\",\n \"enrollment_end\": \"2015-07-15T00:00:00Z\"\
,\n \"enrollment_start\": \"2015-06-15T00:00:00Z\",\n \
\ \"course_id\": \"edX/example/2012_Fall\",\n \"name\": \"Example\
\ Course\",\n \"number\": \"example\",\n \"org\": \"\
edX\",\n \"overview: \"<p>A verbose description of the course.</p>\"\
\n \"start\": \"2015-07-17T12:00:00Z\",\n \"start_display\"\
: \"July 17, 2015\",\n \"start_type\": \"timestamp\",\n \
\ \"pacing\": \"instructor\"\n }"
description: |-
Request details for a course
**Example Requests**
GET /api/courses/v1/courses/{course_key}/
**Response Values**
Body consists of the following fields:
* effort: A textual description of the weekly hours of effort expected
in the course.
* end: Date the course ends, in ISO 8601 notation
* enrollment_end: Date enrollment ends, in ISO 8601 notation
* enrollment_start: Date enrollment begins, in ISO 8601 notation
* id: A unique identifier of the course; a serialized representation
of the opaque key identifying the course.
* media: An object that contains named media items. Included here:
* course_image: An image to show for the course. Represented
as an object with the following fields:
* uri: The location of the image
* name: Name of the course
* number: Catalog number of the course
* org: Name of the organization that owns the course
* overview: A possibly verbose HTML textual description of the course.
Note: this field is only included in the Course Detail view, not
the Course List view.
* short_description: A textual description of the course
* start: Date the course begins, in ISO 8601 notation
* start_display: Readably formatted start of the course
* start_type: Hint describing how `start_display` is set. One of:
* `"string"`: manually set by the course author
* `"timestamp"`: generated from the `start` timestamp
* `"empty"`: no start date is specified
* pacing: Course pacing. Possible values: instructor, self
Deprecated fields:
* blocks_url: Used to fetch the course blocks
* course_id: Course key (use 'id' instead)
**Parameters:**
username (optional):
The username of the specified user for whom the course data
is being accessed. The username is not only required if the API is
requested by an Anonymous user.
**Returns**
* 200 on success with above fields.
* 400 if an invalid parameter was sent or the username was not provided
for an authenticated request.
* 403 if a user who does not have permission to masquerade as
another user specifies a username other than their own.
* 404 if the course is not available or cannot be seen.
Example response:
{
"blocks_url": "/api/courses/v1/blocks/?course_id=edX%2Fexample%2F2012_Fall",
"media": {
"course_image": {
"uri": "/c4x/edX/example/asset/just_a_test.jpg",
"name": "Course Image"
}
},
"description": "An example course.",
"end": "2015-09-19T18:00:00Z",
"enrollment_end": "2015-07-15T00:00:00Z",
"enrollment_start": "2015-06-15T00:00:00Z",
"course_id": "edX/example/2012_Fall",
"name": "Example Course",
"number": "example",
"org": "edX",
"overview: "<p>A verbose description of the course.</p>"
"start": "2015-07-17T12:00:00Z",
"start_display": "July 17, 2015",
"start_type": "timestamp",
"pacing": "instructor"
}
parameters: []
responses:
'200':
@@ -1447,22 +2175,41 @@ paths:
get:
operationId: courses_v2_blocks_list
summary: '**Use Case**'
description: "Returns the blocks in the course according to the requesting user's\n\
\ access level.\n\n**Example requests**:\n\n GET /api/courses/v1/blocks/?course_id=<course_id>\n\
\ GET /api/courses/v1/blocks/?course_id=<course_id>\n &username=anjali\n\
\ &depth=all\n &requested_fields=graded,format,student_view_multi_device,lti_url\n\
\ &block_counts=video\n &student_view_data=video\n &block_types_filter=problem,html\n\
\n**Parameters**:\n\n This view redirects to /api/courses/v1/blocks/<root_usage_key>/\
\ for the\n root usage key of the course specified by course_id. The view\
\ accepts\n all parameters accepted by :class:`BlocksView`, plus the following\n\
\ required parameter\n\n * course_id: (string, required) The ID of the\
\ course whose block data\n we want to return\n\n**Response Values**\n\
\n Responses are identical to those returned by :class:`BlocksView` when\n\
\ passed the root_usage_key of the requested course.\n\n If the course_id\
\ is not supplied, a 400: Bad Request is returned, with\n a message indicating\
\ that course_id is required.\n\n If an invalid course_id is supplied,\
\ a 400: Bad Request is returned,\n with a message indicating that the\
\ course_id is not valid."
description: |-
Returns the blocks in the course according to the requesting user's
access level.
**Example requests**:
GET /api/courses/v1/blocks/?course_id=<course_id>
GET /api/courses/v1/blocks/?course_id=<course_id>
&username=anjali
&depth=all
&requested_fields=graded,format,student_view_multi_device,lti_url
&block_counts=video
&student_view_data=video
&block_types_filter=problem,html
**Parameters**:
This view redirects to /api/courses/v1/blocks/<root_usage_key>/ for the
root usage key of the course specified by course_id. The view accepts
all parameters accepted by :class:`BlocksView`, plus the following
required parameter
* course_id: (string, required) The ID of the course whose block data
we want to return
**Response Values**
Responses are identical to those returned by :class:`BlocksView` when
passed the root_usage_key of the requested course.
If the course_id is not supplied, a 400: Bad Request is returned, with
a message indicating that course_id is required.
If an invalid course_id is supplied, a 400: Bad Request is returned,
with a message indicating that the course_id is not valid.
parameters:
- name: page
in: query
@@ -1484,100 +2231,180 @@ paths:
: get:
operationId: courses_v2_blocks_courses_v2_blocks__[_]+_[_]+_[_]+_[@]+(:@[_read
summary: '**Use Case**'
description: "Returns the blocks within the requested block tree according to\
\ the\n requesting user's access level.\n\n**Example requests**:\n\n \
\ GET /api/courses/v1/blocks/<root_block_usage_id>/?depth=all\n GET /api/courses/v1/blocks/<usage_id>/?\n\
\ username=anjali\n &depth=all\n &requested_fields=graded,format,student_view_multi_device,lti_url,due\n\
\ &block_counts=video\n &student_view_data=video\n &block_types_filter=problem,html\n\
\n**Parameters**:\n\n * all_blocks: (boolean) Provide a value of \"true\"\
\ to return all\n blocks. Returns all blocks only if the requesting user\
\ has course\n staff permissions. Blocks that are visible only to specific\
\ learners\n (for example, based on group membership or randomized content)\
\ are\n all included. If all_blocks is not specified, you must specify\
\ the\n username for the user whose course blocks are requested.\n\n\
\ * username: (string) Required, unless ``all_blocks`` is specified.\n\
\ Specify the username for the user whose course blocks are requested.\n\
\ A blank/empty username can be used to request the blocks accessible\n\
\ to anonymous users (for public courses). Only users with course staff\n\
\ permissions can specify other users' usernames. If a username is\n\
\ specified, results include blocks that are visible to that user,\n\
\ including those based on group or cohort membership or randomized\n\
\ content assigned to that user.\n\n Example: username=anjali\n\
\ username=''\n username\n\n * student_view_data:\
\ (list) Indicates for which block types to return\n student_view_data.\n\
\n Example: student_view_data=video\n\n * block_counts: (list) Indicates\
\ for which block types to return the\n aggregate count of the blocks.\n\
\n Example: block_counts=video,problem\n\n * requested_fields: (list)\
\ Indicates which additional fields to return\n for each block. For\
\ a list of available fields see under `Response\n Values -> blocks`,\
\ below.\n\n The following fields are always returned: id, type, display_name\n\
\n Example: requested_fields=graded,format,student_view_multi_device\n\
\n * depth: (integer or all) Indicates how deep to traverse into the blocks\n\
\ hierarchy. A value of all means the entire hierarchy.\n\n Default\
\ is 0\n\n Example: depth=all\n\n * nav_depth: (integer)\n\n \
\ WARNING: nav_depth is not supported, and may be removed at any time.\n\n\
\ Indicates how far deep to traverse into the\n course hierarchy\
\ before bundling all the descendants.\n\n Default is 3 since typical\
\ navigational views of the course show a\n maximum of chapter->sequential->vertical.\n\
\n Example: nav_depth=3\n\n * return_type (string) Indicates in what\
\ data type to return the\n blocks.\n\n Default is dict. Supported\
\ values are: dict, list\n\n Example: return_type=dict\n\n * block_types_filter:\
\ (list) Requested types of blocks used to filter the final result\n \
\ of returned blocks. Possible values include sequential, vertical, html,\
\ problem,\n video, and discussion.\n\n Example: block_types_filter=vertical,html\n\
\n**Response Values**\n\n The following fields are returned with a successful\
\ response.\n\n * root: The ID of the root node of the requested course\
\ block\n structure.\n\n * blocks: A dictionary or list, based on\
\ the value of the\n \"return_type\" parameter. Maps block usage IDs\
\ to a collection of\n information about each block. Each block contains\
\ the following\n fields.\n\n * id: (string) The usage ID of the\
\ block.\n\n * type: (string) The type of block. Possible values the\
\ names of any\n XBlock type in the system, including custom blocks.\
\ Examples are\n course, chapter, sequential, vertical, html, problem,\
\ video, and\n discussion.\n\n * display_name: (string) The display\
\ name of the block.\n\n * children: (list) If the block has child blocks,\
\ a list of IDs of\n the child blocks. Returned only if \"children\"\
\ is included in the\n \"requested_fields\" parameter.\n\n * completion:\
\ (float or None) The level of completion of the block.\n Its value\
\ can vary between 0.0 and 1.0 or be equal to None\n if block is not\
\ completable. Returned only if \"completion\"\n is included in the\
\ \"requested_fields\" parameter.\n\n * block_counts: (dict) For each\
\ block type specified in the\n block_counts parameter to the endpoint,\
\ the aggregate number of\n blocks of that type for this block and\
\ all of its descendants.\n\n * graded (boolean) Whether or not the block\
\ or any of its descendants\n is graded. Returned only if \"graded\"\
\ is included in the\n \"requested_fields\" parameter.\n\n * format:\
\ (string) The assignment type of the block. Possible values\n can\
\ be \"Homework\", \"Lab\", \"Midterm Exam\", and \"Final Exam\".\n \
\ Returned only if \"format\" is included in the \"requested_fields\"\n \
\ parameter.\n\n * student_view_data: (dict) The JSON data for\
\ this block.\n Returned only if the \"student_view_data\" input parameter\
\ contains\n this block's type.\n\n * student_view_url: (string)\
\ The URL to retrieve the HTML rendering\n of this block's student\
\ view. The HTML could include CSS and\n Javascript code. This field\
\ can be used in combination with the\n student_view_multi_device field\
\ to decide whether to display this\n content to the user.\n\n \
\ This URL can be used as a fallback if the student_view_data for\n \
\ this block type is not supported by the client or the block.\n\n \
\ * student_view_multi_device: (boolean) Whether or not the HTML of\n \
\ the student view that is rendered at \"student_view_url\" supports\n\
\ responsive web layouts, touch-based inputs, and interactive state\n\
\ management for a variety of device sizes and types, including\n \
\ mobile and touch devices. Returned only if\n \"student_view_multi_device\"\
\ is included in the \"requested_fields\"\n parameter.\n\n * lms_web_url:\
\ (string) The URL to the navigational container of the\n xBlock on\
\ the web LMS. This URL can be used as a further fallback\n if the\
\ student_view_url and the student_view_data fields are not\n supported.\n\
\n * lti_url: The block URL for an LTI consumer. Returned only if the\n\
\ \"ENABLE_LTI_PROVIDER\" Django settign is set to \"True\".\n\n \
\ * due: The due date of the block. Returned only if \"due\" is included\n\
\ in the \"requested_fields\" parameter.\n\n * show_correctness:\
\ Whether to show scores/correctness to learners for the current sequence\
\ or problem.\n Returned only if \"show_correctness\" is included in\
\ the \"requested_fields\" parameter.\n\n * Additional XBlock fields\
\ can be included in the response if they are\n configured via the\
\ COURSE_BLOCKS_API_EXTRA_FIELDS Django setting and\n requested via\
\ the \"requested_fields\" parameter."
description: |-
Returns the blocks within the requested block tree according to the
requesting user's access level.
**Example requests**:
GET /api/courses/v1/blocks/<root_block_usage_id>/?depth=all
GET /api/courses/v1/blocks/<usage_id>/?
username=anjali
&depth=all
&requested_fields=graded,format,student_view_multi_device,lti_url,due
&block_counts=video
&student_view_data=video
&block_types_filter=problem,html
**Parameters**:
* all_blocks: (boolean) Provide a value of "true" to return all
blocks. Returns all blocks only if the requesting user has course
staff permissions. Blocks that are visible only to specific learners
(for example, based on group membership or randomized content) are
all included. If all_blocks is not specified, you must specify the
username for the user whose course blocks are requested.
* username: (string) Required, unless ``all_blocks`` is specified.
Specify the username for the user whose course blocks are requested.
A blank/empty username can be used to request the blocks accessible
to anonymous users (for public courses). Only users with course staff
permissions can specify other users' usernames. If a username is
specified, results include blocks that are visible to that user,
including those based on group or cohort membership or randomized
content assigned to that user.
Example: username=anjali
username=''
username
* student_view_data: (list) Indicates for which block types to return
student_view_data.
Example: student_view_data=video
* block_counts: (list) Indicates for which block types to return the
aggregate count of the blocks.
Example: block_counts=video,problem
* requested_fields: (list) Indicates which additional fields to return
for each block. For a list of available fields see under `Response
Values -> blocks`, below.
The following fields are always returned: id, type, display_name
Example: requested_fields=graded,format,student_view_multi_device
* depth: (integer or all) Indicates how deep to traverse into the blocks
hierarchy. A value of all means the entire hierarchy.
Default is 0
Example: depth=all
* nav_depth: (integer)
WARNING: nav_depth is not supported, and may be removed at any time.
Indicates how far deep to traverse into the
course hierarchy before bundling all the descendants.
Default is 3 since typical navigational views of the course show a
maximum of chapter->sequential->vertical.
Example: nav_depth=3
* return_type (string) Indicates in what data type to return the
blocks.
Default is dict. Supported values are: dict, list
Example: return_type=dict
* block_types_filter: (list) Requested types of blocks used to filter the final result
of returned blocks. Possible values include sequential, vertical, html, problem,
video, and discussion.
Example: block_types_filter=vertical,html
**Response Values**
The following fields are returned with a successful response.
* root: The ID of the root node of the requested course block
structure.
* blocks: A dictionary or list, based on the value of the
"return_type" parameter. Maps block usage IDs to a collection of
information about each block. Each block contains the following
fields.
* id: (string) The usage ID of the block.
* type: (string) The type of block. Possible values the names of any
XBlock type in the system, including custom blocks. Examples are
course, chapter, sequential, vertical, html, problem, video, and
discussion.
* display_name: (string) The display name of the block.
* children: (list) If the block has child blocks, a list of IDs of
the child blocks. Returned only if "children" is included in the
"requested_fields" parameter.
* completion: (float or None) The level of completion of the block.
Its value can vary between 0.0 and 1.0 or be equal to None
if block is not completable. Returned only if "completion"
is included in the "requested_fields" parameter.
* block_counts: (dict) For each block type specified in the
block_counts parameter to the endpoint, the aggregate number of
blocks of that type for this block and all of its descendants.
* graded (boolean) Whether or not the block or any of its descendants
is graded. Returned only if "graded" is included in the
"requested_fields" parameter.
* format: (string) The assignment type of the block. Possible values
can be "Homework", "Lab", "Midterm Exam", and "Final Exam".
Returned only if "format" is included in the "requested_fields"
parameter.
* student_view_data: (dict) The JSON data for this block.
Returned only if the "student_view_data" input parameter contains
this block's type.
* student_view_url: (string) The URL to retrieve the HTML rendering
of this block's student view. The HTML could include CSS and
Javascript code. This field can be used in combination with the
student_view_multi_device field to decide whether to display this
content to the user.
This URL can be used as a fallback if the student_view_data for
this block type is not supported by the client or the block.
* student_view_multi_device: (boolean) Whether or not the HTML of
the student view that is rendered at "student_view_url" supports
responsive web layouts, touch-based inputs, and interactive state
management for a variety of device sizes and types, including
mobile and touch devices. Returned only if
"student_view_multi_device" is included in the "requested_fields"
parameter.
* lms_web_url: (string) The URL to the navigational container of the
xBlock on the web. This URL can be used as a further fallback
if the student_view_url and the student_view_data fields are not
supported. Will direct to either the "New" (micro-frontend) or
"Legacy" (Django-template-rendered) frontend experience depending
on which experience is active.
* legacy_web_url: (string) Like `lms_web_url`, but always directs to
the "Legacy" frontend experience. Should only be used for
transitional purposes; will be removed as part of DEPR-109.
* lti_url: The block URL for an LTI consumer. Returned only if the
"ENABLE_LTI_PROVIDER" Django settign is set to "True".
* due: The due date of the block. Returned only if "due" is included
in the "requested_fields" parameter.
* show_correctness: Whether to show scores/correctness to learners for the current sequence or problem.
Returned only if "show_correctness" is included in the "requested_fields" parameter.
* Additional XBlock fields can be included in the response if they are
configured via the COURSE_BLOCKS_API_EXTRA_FIELDS Django setting and
requested via the "requested_fields" parameter.
parameters:
- name: page
in: query
@@ -1626,47 +2453,92 @@ paths:
: get:
operationId: courseware_course_+]+api_courseware_course_+]+(_|+)[_]+)_read
summary: '**Use Cases**'
description: "Request details for a course\n\n**Example Requests**\n\n GET\
\ /api/courseware/course/{course_key}\n\n**Response Values**\n\n Body consists\
\ of the following fields:\n\n * effort: A textual description of the weekly\
\ hours of effort expected\n in the course.\n * end: Date the course\
\ ends, in ISO 8601 notation\n * enrollment_end: Date enrollment ends,\
\ in ISO 8601 notation\n * enrollment_start: Date enrollment begins, in\
\ ISO 8601 notation\n * id: A unique identifier of the course; a serialized\
\ representation\n of the opaque key identifying the course.\n *\
\ media: An object that contains named media items. Included here:\n \
\ * course_image: An image to show for the course. Represented\n \
\ as an object with the following fields:\n * uri: The location\
\ of the image\n * name: Name of the course\n * number: Catalog number\
\ of the course\n * org: Name of the organization that owns the course\n\
\ * short_description: A textual description of the course\n * start:\
\ Date the course begins, in ISO 8601 notation\n * start_display: Readably\
\ formatted start of the course\n * start_type: Hint describing how `start_display`\
\ is set. One of:\n * `\"string\"`: manually set by the course author\n\
\ * `\"timestamp\"`: generated from the `start` timestamp\n \
\ * `\"empty\"`: no start date is specified\n * pacing: Course pacing.\
\ Possible values: instructor, self\n * tabs: Course tabs\n * enrollment:\
\ Enrollment status of authenticated user\n * mode: `audit`, `verified`,\
\ etc\n * is_active: boolean\n * can_load_course: Whether the user\
\ can view the course (AccessResponse object)\n * is_staff: Whether the\
\ effective user has staff access to the course\n * original_user_is_staff:\
\ Whether the original user has staff access to the course\n * user_has_passing_grade:\
\ Whether or not the effective user's grade is equal to or above the courses\
\ minimum\n passing grade\n * course_exit_page_is_active: Flag for\
\ the learning mfe on whether or not the course exit page should display\n\
\ * certificate_data: data regarding the effective user's certificate for\
\ the given course\n * verify_identity_url: URL for a learner to verify\
\ their identity. Only returned for learners enrolled in a\n verified\
\ mode. Will update to reverify URL if necessary.\n * linkedin_add_to_profile_url:\
\ URL to add the effective user's certificate to a LinkedIn Profile.\n\n**Parameters:**\n\
\n requested_fields (optional) comma separated list:\n If set, then\
\ only those fields will be returned.\n username (optional) username to\
\ masquerade as (if requesting user is staff)\n\n**Returns**\n\n * 200\
\ on success with above fields.\n * 400 if an invalid parameter was sent\
\ or the username was not provided\n for an authenticated request.\n\
\ * 403 if a user who does not have permission to masquerade as\n \
\ another user specifies a username other than their own.\n * 404 if the\
\ course is not available or cannot be seen."
description: |-
Request details for a course
**Example Requests**
GET /api/courseware/course/{course_key}
**Response Values**
Body consists of the following fields:
* access_expiration: An object detailing when access to this course will expire
* expiration_date: (str) When the access expires, in ISO 8601 notation
* masquerading_expired_course: (bool) Whether this course is expired for the masqueraded user
* upgrade_deadline: (str) Last chance to upgrade, in ISO 8601 notation (or None if can't upgrade anymore)
* upgrade_url: (str) Upgrade linke (or None if can't upgrade anymore)
* effort: A textual description of the weekly hours of effort expected
in the course.
* end: Date the course ends, in ISO 8601 notation
* enrollment: Enrollment status of authenticated user
* mode: `audit`, `verified`, etc
* is_active: boolean
* enrollment_end: Date enrollment ends, in ISO 8601 notation
* enrollment_start: Date enrollment begins, in ISO 8601 notation
* id: A unique identifier of the course; a serialized representation
of the opaque key identifying the course.
* media: An object that contains named media items. Included here:
* course_image: An image to show for the course. Represented
as an object with the following fields:
* uri: The location of the image
* name: Name of the course
* number: Catalog number of the course
* offer: An object detailing upgrade discount information
* code: (str) Checkout code
* expiration_date: (str) Expiration of offer, in ISO 8601 notation
* original_price: (str) Full upgrade price without checkout code; includes currency symbol
* discounted_price: (str) Upgrade price with checkout code; includes currency symbol
* percentage: (int) Amount of discount
* upgrade_url: (str) Checkout URL
* org: Name of the organization that owns the course
* related_programs: A list of objects that contains program data related to the given course including:
* progress: An object containing program progress:
* complete: (int) Number of complete courses in the program (a course is completed if the user has
earned a certificate for any of the nested course runs)
* in_progress: (int) Number of courses in the program that are in progress (a course is in progress if
the user has enrolled in any of the nested course runs)
* not_started: (int) Number of courses in the program that have not been started
* slug: (str) The program type
* title: (str) The title of the program
* url: (str) The link to the program's landing page
* uuid: (str) A unique identifier of the program
* short_description: A textual description of the course
* start: Date the course begins, in ISO 8601 notation
* start_display: Readably formatted start of the course
* start_type: Hint describing how `start_display` is set. One of:
* `"string"`: manually set by the course author
* `"timestamp"`: generated from the `start` timestamp
* `"empty"`: no start date is specified
* pacing: Course pacing. Possible values: instructor, self
* tabs: Course tabs
* user_timezone: User's chosen timezone setting (or null for browser default)
* can_load_course: Whether the user can view the course (AccessResponse object)
* is_staff: Whether the effective user has staff access to the course
* original_user_is_staff: Whether the original user has staff access to the course
* user_has_passing_grade: Whether or not the effective user's grade is equal to or above the courses minimum
passing grade
* course_exit_page_is_active: Flag for the learning mfe on whether or not the course exit page should display
* certificate_data: data regarding the effective user's certificate for the given course
* verify_identity_url: URL for a learner to verify their identity. Only returned for learners enrolled in a
verified mode. Will update to reverify URL if necessary.
* linkedin_add_to_profile_url: URL to add the effective user's certificate to a LinkedIn Profile.
**Parameters:**
requested_fields (optional) comma separated list:
If set, then only those fields will be returned.
username (optional) username to masquerade as (if requesting user is staff)
**Returns**
* 200 on success with above fields.
* 400 if an invalid parameter was sent or the username was not provided
for an authenticated request.
* 403 if a user who does not have permission to masquerade as
another user specifies a username other than their own.
* 404 if the course is not available or cannot be seen.
parameters: []
responses:
'200':
@@ -1971,8 +2843,9 @@ paths:
/discussion/v1/comments/:
get:
operationId: discussion_v1_comments_list
description: "Implements the GET method for the list endpoint as described in\
\ the\nclass docstring."
description: |-
Implements the GET method for the list endpoint as described in the
class docstring.
parameters: []
responses:
'200':
@@ -1984,8 +2857,9 @@ paths:
- discussion
post:
operationId: discussion_v1_comments_create
description: "Implements the POST method for the list endpoint as described\
\ in the\nclass docstring."
description: |-
Implements the POST method for the list endpoint as described in the
class docstring.
parameters: []
responses:
'201':
@@ -2011,8 +2885,9 @@ paths:
- discussion
patch:
operationId: discussion_v1_comments_partial_update
description: "Implements the PATCH method for the instance endpoint as described\
\ in\nthe class docstring."
description: |-
Implements the PATCH method for the instance endpoint as described in
the class docstring.
parameters: []
responses:
'200':
@@ -2024,8 +2899,9 @@ paths:
- discussion
delete:
operationId: discussion_v1_comments_delete
description: "Implements the DELETE method for the instance endpoint as described\
\ in\nthe class docstring"
description: |-
Implements the DELETE method for the instance endpoint as described in
the class docstring
parameters: []
responses:
'204':
@@ -2139,8 +3015,9 @@ paths:
/discussion/v1/threads/:
get:
operationId: discussion_v1_threads_list
description: "Implements the GET method for the list endpoint as described in\
\ the\nclass docstring."
description: |-
Implements the GET method for the list endpoint as described in the
class docstring.
parameters: []
responses:
'200':
@@ -2152,8 +3029,9 @@ paths:
- discussion
post:
operationId: discussion_v1_threads_create
description: "Implements the POST method for the list endpoint as described\
\ in the\nclass docstring."
description: |-
Implements the POST method for the list endpoint as described in the
class docstring.
parameters: []
responses:
'201':
@@ -2179,8 +3057,9 @@ paths:
- discussion
patch:
operationId: discussion_v1_threads_partial_update
description: "Implements the PATCH method for the instance endpoint as described\
\ in\nthe class docstring."
description: |-
Implements the PATCH method for the instance endpoint as described in
the class docstring.
parameters: []
responses:
'200':
@@ -2192,8 +3071,9 @@ paths:
- discussion
delete:
operationId: discussion_v1_threads_delete
description: "Implements the DELETE method for the instance endpoint as described\
\ in\nthe class docstring"
description: |-
Implements the DELETE method for the instance endpoint as described in
the class docstring
parameters: []
responses:
'204':
@@ -2267,8 +3147,9 @@ paths:
/edx_proctoring/v1/proctored_exam/allowance:
get:
operationId: edx_proctoring_v1_proctored_exam_allowance_list
description: "HTTP GET handler. Get all allowances for a course.\nCourse and\
\ Global staff can view both timed and proctored exam allowances."
description: |-
HTTP GET handler. Get all allowances for a course.
Course and Global staff can view both timed and proctored exam allowances.
parameters: []
responses:
'200':
@@ -2314,11 +3195,10 @@ paths:
tags:
- edx_proctoring
parameters: []
/edx_proctoring/v1/proctored_exam/attempt/course_id/{course_id}:
/edx_proctoring/v1/proctored_exam/attempt/grouped/course_id/{course_id}:
get:
operationId: edx_proctoring_v1_proctored_exam_attempt_course_id_read
description: "HTTP GET Handler. Returns the status of the exam attempt.\nCourse\
\ and Global staff can view both timed and proctored exam attempts."
operationId: edx_proctoring_v1_proctored_exam_attempt_grouped_course_id_read
description: HTTP GET Handler.
parameters: []
responses:
'200':
@@ -2330,11 +3210,10 @@ paths:
in: path
required: true
type: string
/edx_proctoring/v1/proctored_exam/attempt/course_id/{course_id}/search/{search_by}:
/edx_proctoring/v1/proctored_exam/attempt/grouped/course_id/{course_id}/search/{search_by}:
get:
operationId: edx_proctoring_v1_proctored_exam_attempt_course_id_search_read
description: "HTTP GET Handler. Returns the status of the exam attempt.\nCourse\
\ and Global staff can view both timed and proctored exam attempts."
operationId: edx_proctoring_v1_proctored_exam_attempt_grouped_course_id_search_read
description: HTTP GET Handler.
parameters: []
responses:
'200':
@@ -2362,7 +3241,7 @@ paths:
- edx_proctoring
put:
operationId: edx_proctoring_v1_proctored_exam_attempt_update
description: HTTP POST handler. To stop an exam.
description: HTTP PUT handler to update exam attempt status based on an action.
parameters: []
responses:
'200':
@@ -2386,7 +3265,7 @@ paths:
/edx_proctoring/v1/proctored_exam/attempt/{attempt_id}/review_status:
put:
operationId: edx_proctoring_v1_proctored_exam_attempt_review_status_update
description: Update the is_status_acknowledge flag for the specific attempt
description: Update the is_status_acknowledged flag for the specific attempt
parameters: []
responses:
'200':
@@ -2416,8 +3295,9 @@ paths:
/edx_proctoring/v1/proctored_exam/attempt/{external_id}/reviewed:
post:
operationId: edx_proctoring_v1_proctored_exam_attempt_reviewed_create
description: "Called when 3rd party proctoring service has finished its review\
\ of\nan attempt."
description: |-
Called when 3rd party proctoring service has finished its review of
an attempt.
parameters: []
responses:
'201':
@@ -2432,8 +3312,11 @@ paths:
/edx_proctoring/v1/proctored_exam/exam:
get:
operationId: edx_proctoring_v1_proctored_exam_exam_list
description: "HTTP GET handler.\n Scenarios:\n by exam_id: calls get_exam_by_id()\n\
\ by course_id, content_id: get_exam_by_content_id()"
description: |-
HTTP GET handler.
Scenarios:
by exam_id: calls get_exam_by_id()
by course_id, content_id: get_exam_by_content_id()
parameters: []
responses:
'200':
@@ -2451,7 +3334,9 @@ paths:
- edx_proctoring
put:
operationId: edx_proctoring_v1_proctored_exam_exam_update
description: "HTTP PUT handler. To update an exam.\ncalls the update_exam"
description: |-
HTTP PUT handler. To update an exam.
calls the update_exam
parameters: []
responses:
'200':
@@ -2462,8 +3347,11 @@ paths:
/edx_proctoring/v1/proctored_exam/exam/course_id/{course_id}:
get:
operationId: edx_proctoring_v1_proctored_exam_exam_course_id_read
description: "HTTP GET handler.\n Scenarios:\n by exam_id: calls get_exam_by_id()\n\
\ by course_id, content_id: get_exam_by_content_id()"
description: |-
HTTP GET handler.
Scenarios:
by exam_id: calls get_exam_by_id()
by course_id, content_id: get_exam_by_content_id()
parameters: []
responses:
'200':
@@ -2481,7 +3369,9 @@ paths:
- edx_proctoring
put:
operationId: edx_proctoring_v1_proctored_exam_exam_course_id_update
description: "HTTP PUT handler. To update an exam.\ncalls the update_exam"
description: |-
HTTP PUT handler. To update an exam.
calls the update_exam
parameters: []
responses:
'200':
@@ -2496,8 +3386,11 @@ paths:
/edx_proctoring/v1/proctored_exam/exam/course_id/{course_id}/content_id/{content_id}:
get:
operationId: edx_proctoring_v1_proctored_exam_exam_course_id_content_id_read
description: "HTTP GET handler.\n Scenarios:\n by exam_id: calls get_exam_by_id()\n\
\ by course_id, content_id: get_exam_by_content_id()"
description: |-
HTTP GET handler.
Scenarios:
by exam_id: calls get_exam_by_id()
by course_id, content_id: get_exam_by_content_id()
parameters: []
responses:
'200':
@@ -2515,7 +3408,9 @@ paths:
- edx_proctoring
put:
operationId: edx_proctoring_v1_proctored_exam_exam_course_id_content_id_update
description: "HTTP PUT handler. To update an exam.\ncalls the update_exam"
description: |-
HTTP PUT handler. To update an exam.
calls the update_exam
parameters: []
responses:
'200':
@@ -2534,8 +3429,11 @@ paths:
/edx_proctoring/v1/proctored_exam/exam/exam_id/{exam_id}:
get:
operationId: edx_proctoring_v1_proctored_exam_exam_exam_id_read
description: "HTTP GET handler.\n Scenarios:\n by exam_id: calls get_exam_by_id()\n\
\ by course_id, content_id: get_exam_by_content_id()"
description: |-
HTTP GET handler.
Scenarios:
by exam_id: calls get_exam_by_id()
by course_id, content_id: get_exam_by_content_id()
parameters: []
responses:
'200':
@@ -2553,7 +3451,9 @@ paths:
- edx_proctoring
put:
operationId: edx_proctoring_v1_proctored_exam_exam_exam_id_update
description: "HTTP PUT handler. To update an exam.\ncalls the update_exam"
description: |-
HTTP PUT handler. To update an exam.
calls the update_exam
parameters: []
responses:
'200':
@@ -2565,11 +3465,32 @@ paths:
in: path
required: true
type: string
/edx_proctoring/v1/proctored_exam/exam_id/{exam_id}/user_id/{user_id}/reset_attempts:
delete:
operationId: edx_proctoring_v1_proctored_exam_exam_id_user_id_reset_attempts_delete
description: HTTP DELETE handler, deletes all attempts for a given exam and
username
parameters: []
responses:
'204':
description: ''
tags:
- edx_proctoring
parameters:
- name: exam_id
in: path
required: true
type: string
- name: user_id
in: path
required: true
type: string
/edx_proctoring/v1/proctored_exam/{course_id}/allowance:
get:
operationId: edx_proctoring_v1_proctored_exam_allowance_list
description: "HTTP GET handler. Get all allowances for a course.\nCourse and\
\ Global staff can view both timed and proctored exam allowances."
description: |-
HTTP GET handler. Get all allowances for a course.
Course and Global staff can view both timed and proctored exam allowances.
parameters: []
responses:
'200':
@@ -2602,8 +3523,9 @@ paths:
/edx_proctoring/v1/retire_backend_user/{user_id}/:
post:
operationId: edx_proctoring_v1_retire_backend_user_create
description: "Deletes all user data for the particular user_id\nfrom all configured\
\ backends"
description: |-
Deletes all user data for the particular user_id
from all configured backends
parameters: []
responses:
'201':
@@ -2630,6 +3552,32 @@ paths:
in: path
required: true
type: string
/edx_proctoring/v1/user_onboarding/status:
get:
operationId: edx_proctoring_v1_user_onboarding_status_list
description: HTTP GET handler. Returns the learner's onboarding status.
parameters: []
responses:
'200':
description: ''
tags:
- edx_proctoring
parameters: []
/edx_proctoring/v1/user_onboarding/status/course_id/{course_id}:
get:
operationId: edx_proctoring_v1_user_onboarding_status_course_id_read
description: HTTP GET handler.
parameters: []
responses:
'200':
description: ''
tags:
- edx_proctoring
parameters:
- name: course_id
in: path
required: true
type: string
/edxnotes/v1/retire_user/:
post:
operationId: edxnotes_v1_retire_user_create
@@ -2641,6 +3589,17 @@ paths:
tags:
- edxnotes
parameters: []
/embargo/v1/course_access/:
get:
operationId: embargo_v1_course_access_list
description: GET /api/embargo/v1/course_access/
parameters: []
responses:
'200':
description: ''
tags:
- embargo
parameters: []
/enrollment/v1/course/{course_id}:
get:
operationId: enrollment_v1_course_read
@@ -2661,17 +3620,20 @@ paths:
get:
operationId: enrollment_v1_enrollment_list
summary: Gets a list of all course enrollments for a user.
description: "Returns a list for the currently logged in user, or for the user\
\ named by the 'user' GET\nparameter. If the username does not match that\
\ of the currently logged in user, only\ncourses for which the currently logged\
\ in user has the Staff or Admin role are listed.\nAs a result, a course team\
\ member can find out which of their own courses a particular\nlearner is\
\ enrolled in.\n\nOnly the Staff or Admin role (granted on the Django administrative\
\ console as the staff\nor instructor permission) in individual courses gives\
\ the requesting user access to\nenrollment data. Permissions granted at the\
\ organizational level do not give a user\naccess to enrollment data for all\
\ of that organization's courses.\n\nUsers who have the global staff permission\
\ can access all enrollment data for all\ncourses."
description: |-
Returns a list for the currently logged in user, or for the user named by the 'user' GET
parameter. If the username does not match that of the currently logged in user, only
courses for which the currently logged in user has the Staff or Admin role are listed.
As a result, a course team member can find out which of their own courses a particular
learner is enrolled in.
Only the Staff or Admin role (granted on the Django administrative console as the staff
or instructor permission) in individual courses gives the requesting user access to
enrollment data. Permissions granted at the organizational level do not give a user
access to enrollment data for all of that organization's courses.
Users who have the global staff permission can access all enrollment data for all
courses.
parameters: []
responses:
'200':
@@ -2681,9 +3643,9 @@ paths:
post:
operationId: enrollment_v1_enrollment_create
summary: Enrolls the currently logged-in user in a course.
description: "Server-to-server calls may deactivate or modify the mode of existing\
\ enrollments. All other requests\ngo through `add_enrollment()`, which allows\
\ creation of new and reactivation of old enrollments."
description: |-
Server-to-server calls may deactivate or modify the mode of existing enrollments. All other requests
go through `add_enrollment()`, which allows creation of new and reactivation of old enrollments.
parameters: []
responses:
'201':
@@ -2695,9 +3657,9 @@ paths:
get:
operationId: enrollment_v1_enrollment_read
summary: Create, read, or update enrollment information for a user.
description: "HTTP Endpoint for all CRUD operations for a user course enrollment.\
\ Allows creation, reading, and\nupdates of the current enrollment for a particular\
\ course."
description: |-
HTTP Endpoint for all CRUD operations for a user course enrollment. Allows creation, reading, and
updates of the current enrollment for a particular course.
parameters: []
responses:
'200':
@@ -2713,9 +3675,9 @@ paths:
get:
operationId: enrollment_v1_enrollment_read
summary: Create, read, or update enrollment information for a user.
description: "HTTP Endpoint for all CRUD operations for a user course enrollment.\
\ Allows creation, reading, and\nupdates of the current enrollment for a particular\
\ course."
description: |-
HTTP Endpoint for all CRUD operations for a user course enrollment. Allows creation, reading, and
updates of the current enrollment for a particular course.
parameters: []
responses:
'200':
@@ -2735,35 +3697,66 @@ paths:
get:
operationId: enrollment_v1_enrollments_list
summary: '**Use Cases**'
description: "Get a list of all course enrollments, optionally filtered by a\
\ course ID or list of usernames.\n\n**Example Requests**\n\n GET /api/enrollment/v1/enrollments\n\
\n GET /api/enrollment/v1/enrollments?course_id={course_id}\n\n GET\
\ /api/enrollment/v1/enrollments?username={username},{username},{username}\n\
\n GET /api/enrollment/v1/enrollments?course_id={course_id}&username={username}\n\
\n**Query Parameters for GET**\n\n * course_id: Filters the result to course\
\ enrollments for the course corresponding to the\n given course ID.\
\ The value must be URL encoded. Optional.\n\n * username: List of comma-separated\
\ usernames. Filters the result to the course enrollments\n of the given\
\ users. Optional.\n\n * page_size: Number of results to return per page.\
\ Optional.\n\n * page: Page number to retrieve. Optional.\n\n**Response\
\ Values**\n\n If the request for information about the course enrollments\
\ is successful, an HTTP 200 \"OK\" response\n is returned.\n\n The\
\ HTTP 200 response has the following values.\n\n * results: A list of\
\ the course enrollments matching the request.\n\n * created: Date\
\ and time when the course enrollment was created.\n\n * mode: Mode\
\ for the course enrollment.\n\n * is_active: Whether the course enrollment\
\ is active or not.\n\n * user: Username of the user in the course\
\ enrollment.\n\n * course_id: Course ID of the course in the course\
\ enrollment.\n\n * next: The URL to the next page of results, or null\
\ if this is the\n last page.\n\n * previous: The URL to the next\
\ page of results, or null if this\n is the first page.\n\n If the\
\ user is not logged in, a 401 error is returned.\n\n If the user is not\
\ global staff, a 403 error is returned.\n\n If the specified course_id\
\ is not valid or any of the specified usernames\n are not valid, a 400\
\ error is returned.\n\n If the specified course_id does not correspond\
\ to a valid course or if all the specified\n usernames do not correspond\
\ to valid users, an HTTP 200 \"OK\" response is returned with an\n empty\
\ 'results' field."
description: |-
Get a list of all course enrollments, optionally filtered by a course ID or list of usernames.
**Example Requests**
GET /api/enrollment/v1/enrollments
GET /api/enrollment/v1/enrollments?course_id={course_id}
GET /api/enrollment/v1/enrollments?username={username},{username},{username}
GET /api/enrollment/v1/enrollments?course_id={course_id}&username={username}
**Query Parameters for GET**
* course_id: Filters the result to course enrollments for the course corresponding to the
given course ID. The value must be URL encoded. Optional.
* username: List of comma-separated usernames. Filters the result to the course enrollments
of the given users. Optional.
* page_size: Number of results to return per page. Optional.
* page: Page number to retrieve. Optional.
**Response Values**
If the request for information about the course enrollments is successful, an HTTP 200 "OK" response
is returned.
The HTTP 200 response has the following values.
* results: A list of the course enrollments matching the request.
* created: Date and time when the course enrollment was created.
* mode: Mode for the course enrollment.
* is_active: Whether the course enrollment is active or not.
* user: Username of the user in the course enrollment.
* course_id: Course ID of the course in the course enrollment.
* next: The URL to the next page of results, or null if this is the
last page.
* previous: The URL to the next page of results, or null if this
is the first page.
If the user is not logged in, a 401 error is returned.
If the user is not global staff, a 403 error is returned.
If the specified course_id is not valid or any of the specified usernames
are not valid, a 400 error is returned.
If the specified course_id does not correspond to a valid course or if all the specified
usernames do not correspond to valid users, an HTTP 200 "OK" response is returned with an
empty 'results' field.
parameters:
- name: cursor
in: query
@@ -2819,8 +3812,9 @@ paths:
/entitlements/v1/entitlements/:
get:
operationId: entitlements_v1_entitlements_list
description: "Override the list method to expire records that are past the\n\
policy and requested via the API before returning those records."
description: |-
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
@@ -2887,8 +3881,9 @@ paths:
/entitlements/v1/entitlements/{uuid}/:
get:
operationId: entitlements_v1_entitlements_read
description: "Override the retrieve method to expire a record that is past the\n\
policy and is requested via the API before returning that record."
description: |-
Override the retrieve method to expire a record that is past the
policy and is requested via the API before returning that record.
parameters: []
responses:
'200':
@@ -2947,12 +3942,15 @@ paths:
/entitlements/v1/entitlements/{uuid}/enrollments:
post:
operationId: entitlements_v1_entitlements_enrollments_create
description: "On POST this method will be called and will handle enrolling a\
\ user in the\nprovided course_run_id from the data. This is called on a specific\
\ entitlement\nUUID so the course_run_id has to correspond to the Course that\
\ is assigned to\nthe Entitlement.\n\nWhen this API is called for a user who\
\ is already enrolled in a run that User\nwill be unenrolled from their current\
\ run and enrolled in the new run if it is\navailable."
description: |-
On POST this method will be called and will handle enrolling a user in the
provided course_run_id from the data. This is called on a specific entitlement
UUID so the course_run_id has to correspond to the Course that is assigned to
the Entitlement.
When this API is called for a user who is already enrolled in a run that User
will be unenrolled from their current run and enrolled in the new run if it is
available.
parameters: []
responses:
'201':
@@ -2963,8 +3961,9 @@ paths:
operationId: entitlements_v1_entitlements_enrollments_delete
summary: On DELETE call to this API we will unenroll the course enrollment for
the provided uuid
description: "If is_refund parameter is provided then unenroll the user, set\
\ Entitlement expiration, and issue\na refund"
description: |-
If is_refund parameter is provided then unenroll the user, set Entitlement expiration, and issue
a refund
parameters: []
responses:
'204':
@@ -3316,8 +4315,9 @@ paths:
/grades/v1/gradebook/{course_id}/:
get:
operationId: grades_v1_gradebook_read
description: "Checks for course author access for the given course by the requesting\
\ user.\nCalls the view function if has access, otherwise raises a 403."
description: |-
Checks for course author access for the given course by the requesting user.
Calls the view function if has access, otherwise raises a 403.
parameters: []
responses:
'200':
@@ -3332,8 +4332,9 @@ paths:
/grades/v1/gradebook/{course_id}/bulk-update:
post:
operationId: grades_v1_gradebook_bulk-update_create
description: "Checks for course author access for the given course by the requesting\
\ user.\nCalls the view function if has access, otherwise raises a 403."
description: |-
Checks for course author access for the given course by the requesting user.
Calls the view function if has access, otherwise raises a 403.
parameters: []
responses:
'201':
@@ -3348,8 +4349,9 @@ paths:
/grades/v1/gradebook/{course_id}/grading-info:
get:
operationId: grades_v1_gradebook_grading-info_list
description: "Checks for course author access for the given course by the requesting\
\ user.\nCalls the view function if has access, otherwise raises a 403."
description: |-
Checks for course author access for the given course by the requesting user.
Calls the view function if has access, otherwise raises a 403.
parameters:
- name: page
in: query
@@ -3375,14 +4377,25 @@ paths:
get:
operationId: grades_v1_policy_courses_read
summary: '**Use Case**'
description: "Get the course grading policy.\n\n**Example requests**:\n\n \
\ GET /api/grades/v1/policy/courses/{course_id}/\n\n**Response Values**\n\
\n * assignment_type: The type of the assignment, as configured by course\n\
\ staff. For example, course staff might make the assignment types Homework,\n\
\ Quiz, and Exam.\n\n * count: The number of assignments of the type.\n\
\n * dropped: Number of assignments of the type that are dropped.\n\n \
\ * weight: The weight, or effect, of the assignment type on the learner's\n\
\ final grade."
description: |-
Get the course grading policy.
**Example requests**:
GET /api/grades/v1/policy/courses/{course_id}/
**Response Values**
* assignment_type: The type of the assignment, as configured by course
staff. For example, course staff might make the assignment types Homework,
Quiz, and Exam.
* count: The number of assignments of the type.
* dropped: Number of assignments of the type that are dropped.
* weight: The weight, or effect, of the assignment type on the learner's
final grade.
parameters:
- name: page
in: query
@@ -3407,8 +4420,9 @@ paths:
/grades/v1/subsection/{subsection_id}/:
get:
operationId: grades_v1_subsection_read
description: "Returns subection grade data, override grade data and a history\
\ of changes made to\na specific users specific subsection grade."
description: |-
Returns subection grade data, override grade data and a history of changes made to
a specific users specific subsection grade.
parameters: []
responses:
'200':
@@ -3420,6 +4434,213 @@ paths:
in: path
required: true
type: string
/instructor/v1/reports/{course_id}:
get:
operationId: instructor_v1_reports_read
summary: List report CSV files that are available for download for this course.
description: |-
**Use Cases**
Lists reports available for download
**Example Requests**:
GET /api/instructor/v1/reports/{course_id}
**Response Values**
```json
{
"downloads": [
{
"url": "https://1.mock.url",
"link": "<a href="https://1.mock.url">mock_file_name_1</a>",
"name": "mock_file_name_1"
}
]
}
```
The report name will depend on the type of report generated. For example a
problem responses report for an entire course might be called:
edX_DemoX_Demo_Course_student_state_from_block-v1_edX+DemoX+Demo_Course+type@course+block@course_2021-04-30-0918.csv
parameters:
- name: course_id
in: path
description: ID for the course whose reports need to be listed.
type: string
required: true
- name: report_name
in: query
description: Filter results to only return details of for the report with
the specified name.
type: string
responses:
'200':
description: ''
schema:
$ref: '#/definitions/ReportDownloadsList'
'401':
description: The requesting user is not authenticated.
'403':
description: The requesting user lacks access to the course.
'404':
description: The requested course does not exist.
tags:
- instructor
parameters:
- name: course_id
in: path
required: true
type: string
/instructor/v1/reports/{course_id}/generate/problem_responses:
post:
operationId: instructor_v1_reports_generate_problem_responses_create
summary: Initiate generation of a CSV file containing all student answers
description: |-
to a given problem.
**Example requests**
POST /api/instructor/v1/reports/{course_id}/generate/problem_responses {
"problem_locations": [
"{usage_key1}",
"{usage_key2}",
"{usage_key3}"
]
}
POST /api/instructor/v1/reports/{course_id}/generate/problem_responses {
"problem_locations": ["{usage_key}"],
"problem_types_filter": ["problem"]
}
**POST Parameters**
A POST request can include the following parameters:
* problem_location: A list of usage keys for the blocks to include in
the report. If the location is a block that contains other blocks,
(such as the course, section, subsection, or unit blocks) then all
blocks under that block will be included in the report.
* problem_types_filter: Optional. A comma-separated list of block types
to include in the report. If set, only blocks of the specified types
will be included in the report.
To get data on all the poll and survey blocks in a course, you could
POST the usage key of the course for `problem_location`, and
"poll, survey" as the value for `problem_types_filter`.
**Example Response:**
If initiation is successful (or generation task is already running):
```json
{
"status": "The problem responses report is being created. ...",
"task_id": "4e49522f-31d9-431a-9cff-dd2a2bf4c85a"
}
```
Responds with BadRequest if any of the provided problem locations are faulty.
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/ProblemResponseReportPostParams'
- name: course_id
in: path
description: ID of the course for which report is to be generate.
type: string
required: true
responses:
'200':
description: ''
schema:
$ref: '#/definitions/ProblemResponsesReportStatus'
'400':
description: The provided parameters were invalid. Make sure you've provided
at least one valid usage key for `problem_locations`.
'401':
description: The requesting user is not authenticated.
'403':
description: The requesting user lacks access to the course.
tags:
- instructor
parameters:
- name: course_id
in: path
required: true
type: string
/instructor/v1/tasks/{course_id}:
get:
operationId: instructor_v1_tasks_read
summary: List instructor tasks filtered by `course_id`.
description: |-
**Use Cases**
Lists currently running instructor tasks
**Parameters**
- With no arguments, lists running tasks.
- `problem_location_str` lists task history for problem
- `problem_location_str` and `unique_student_identifier` lists task
history for problem AND student (intersection)
**Example Requests**:
GET /courses/{course_id}/instructor/api/v0/tasks
**Response Values**
```json
{
"tasks": [
{
"status": "Incomplete",
"task_type": "grade_problems",
"task_id": "2519ff31-22d9-4a62-91e2-55495895b355",
"created": "2019-01-15T18:00:15.902470+00:00",
"task_input": "{}",
"duration_sec": "unknown",
"task_message": "No status information available",
"requester": "staff",
"task_state": "PROGRESS"
}
]
}
```
parameters:
- name: course_id
in: path
description: ID for the course whose tasks need to be listed.
type: string
required: true
- name: problem_location_str
in: query
description: Filter instructor tasks to this problem location.
type: string
- name: unique_student_identifier
in: query
description: Filter tasks to a singe problem and a single student. Must
be used in combination with `problem_location_str`.
type: string
responses:
'200':
description: ''
schema:
$ref: '#/definitions/InstructorTasksList'
'401':
description: The requesting user is not authenticated.
'403':
description: The requesting user lacks access to the course.
'404':
description: The requested course does not exist.
tags:
- instructor
parameters:
- name: course_id
in: path
required: true
type: string
/learning_sequences/v1/course_outline/{course_key_str}:
get:
operationId: learning_sequences_v1_course_outline_read
@@ -3436,12 +4657,497 @@ paths:
in: path
required: true
type: string
/lti_consumer/v1/lti/{lti_config_id}/lti-ags:
get:
operationId: lti_consumer_v1_lti_lti-ags_list
summary: LineItem endpoint implementation from LTI Advantage.
description: 'See full documentation at:'
parameters: []
responses:
'200':
description: ''
schema:
type: array
items:
$ref: '#/definitions/LtiAgsLineItem'
consumes:
- application/vnd.ims.lis.v2.lineitem+json
produces:
- application/vnd.ims.lis.v2.lineitemcontainer+json
- application/vnd.ims.lis.v2.lineitem+json
tags:
- lti_consumer
post:
operationId: lti_consumer_v1_lti_lti-ags_create
summary: LineItem endpoint implementation from LTI Advantage.
description: 'See full documentation at:'
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/LtiAgsLineItem'
responses:
'201':
description: ''
schema:
$ref: '#/definitions/LtiAgsLineItem'
consumes:
- application/vnd.ims.lis.v2.lineitem+json
produces:
- application/vnd.ims.lis.v2.lineitemcontainer+json
- application/vnd.ims.lis.v2.lineitem+json
tags:
- lti_consumer
parameters:
- name: lti_config_id
in: path
required: true
type: string
/lti_consumer/v1/lti/{lti_config_id}/lti-ags/{id}:
get:
operationId: lti_consumer_v1_lti_lti-ags_read
summary: LineItem endpoint implementation from LTI Advantage.
description: 'See full documentation at:'
parameters: []
responses:
'200':
description: ''
schema:
$ref: '#/definitions/LtiAgsLineItem'
consumes:
- application/vnd.ims.lis.v2.lineitem+json
produces:
- application/vnd.ims.lis.v2.lineitemcontainer+json
- application/vnd.ims.lis.v2.lineitem+json
tags:
- lti_consumer
put:
operationId: lti_consumer_v1_lti_lti-ags_update
summary: LineItem endpoint implementation from LTI Advantage.
description: 'See full documentation at:'
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/LtiAgsLineItem'
responses:
'200':
description: ''
schema:
$ref: '#/definitions/LtiAgsLineItem'
consumes:
- application/vnd.ims.lis.v2.lineitem+json
produces:
- application/vnd.ims.lis.v2.lineitemcontainer+json
- application/vnd.ims.lis.v2.lineitem+json
tags:
- lti_consumer
patch:
operationId: lti_consumer_v1_lti_lti-ags_partial_update
summary: LineItem endpoint implementation from LTI Advantage.
description: 'See full documentation at:'
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/LtiAgsLineItem'
responses:
'200':
description: ''
schema:
$ref: '#/definitions/LtiAgsLineItem'
consumes:
- application/vnd.ims.lis.v2.lineitem+json
produces:
- application/vnd.ims.lis.v2.lineitemcontainer+json
- application/vnd.ims.lis.v2.lineitem+json
tags:
- lti_consumer
delete:
operationId: lti_consumer_v1_lti_lti-ags_delete
summary: LineItem endpoint implementation from LTI Advantage.
description: 'See full documentation at:'
parameters: []
responses:
'204':
description: ''
consumes:
- application/vnd.ims.lis.v2.lineitem+json
produces:
- application/vnd.ims.lis.v2.lineitemcontainer+json
- application/vnd.ims.lis.v2.lineitem+json
tags:
- lti_consumer
parameters:
- name: id
in: path
required: true
type: string
- name: lti_config_id
in: path
required: true
type: string
/lti_consumer/v1/lti/{lti_config_id}/lti-ags/{id}/results/{user_id}:
get:
operationId: lti_consumer_v1_lti_lti-ags_results
summary: Return a Result list for an LtiAgsLineItem
description: |-
URL Parameters:
* user_id (string): String external user id representation.
Query Parameters:
* limit (integer): The maximum number of records to return. Records are
sorted with most recent timestamp first
parameters: []
responses:
'200':
description: ''
schema:
$ref: '#/definitions/LtiAgsLineItem'
consumes:
- application/vnd.ims.lis.v2.lineitem+json
produces:
- application/vnd.ims.lis.v2.resultcontainer+json
tags:
- lti_consumer
parameters:
- name: id
in: path
required: true
type: string
- name: lti_config_id
in: path
required: true
type: string
- name: user_id
in: path
required: true
type: string
/lti_consumer/v1/lti/{lti_config_id}/lti-ags/{id}/scores:
post:
operationId: lti_consumer_v1_lti_lti-ags_scores
description: Create a Score record for an LtiAgsLineItem
parameters:
- name: data
in: body
required: true
schema:
$ref: '#/definitions/LtiAgsLineItem'
responses:
'201':
description: ''
schema:
$ref: '#/definitions/LtiAgsLineItem'
consumes:
- application/vnd.ims.lis.v1.score+json
produces:
- application/vnd.ims.lis.v1.score+json
tags:
- lti_consumer
parameters:
- name: id
in: path
required: true
type: string
- name: lti_config_id
in: path
required: true
type: string
/mfe_context:
get:
operationId: mfe_context_list
description: |-
Returns the context for third party auth providers, user country code
and the currently running pipeline.
parameters: []
responses:
'200':
description: ''
tags:
- mfe_context
parameters: []
/mobile/{api_version}/course_info/{course_id}/handouts:
get:
operationId: mobile_course_info_handouts_list
summary: '**Use Case**'
description: |-
Get the HTML for course handouts.
**Example Request**
GET /api/mobile/v0.5/course_info/{course_id}/handouts
**Response Values**
If the request is successful, the request returns an HTTP 200 "OK"
response along with the following value.
* handouts_html: The HTML for course handouts.
parameters:
- name: page
in: query
description: A page number within the paginated result set.
required: false
type: integer
- name: page_size
in: query
description: Number of results to return per page.
required: false
type: integer
responses:
'200':
description: ''
tags:
- mobile
parameters:
- name: api_version
in: path
required: true
type: string
- name: course_id
in: path
required: true
type: string
/mobile/{api_version}/course_info/{course_id}/updates:
get:
operationId: mobile_course_info_updates_list
summary: '**Use Case**'
description: |-
Get the content for course updates.
**Example Request**
GET /api/mobile/v0.5/course_info/{course_id}/updates
**Response Values**
If the request is successful, the request returns an HTTP 200 "OK"
response along with an array of course updates. Each course update
contains the following values.
* content: The content, as an HTML string, of the course update.
* date: The date of the course update.
* id: The unique identifier of the update.
* status: Whether the update is visible or not.
parameters:
- name: page
in: query
description: A page number within the paginated result set.
required: false
type: integer
- name: page_size
in: query
description: Number of results to return per page.
required: false
type: integer
responses:
'200':
description: ''
tags:
- mobile
parameters:
- name: api_version
in: path
required: true
type: string
- name: course_id
in: path
required: true
type: string
/mobile/{api_version}/my_user_info:
get:
operationId: mobile_my_user_info_list
description: Redirect to the currently-logged-in user's info page
parameters: []
responses:
'200':
description: ''
tags:
- mobile
parameters:
- name: api_version
in: path
required: true
type: string
/mobile/{api_version}/users/{username}:
get:
operationId: mobile_users_read
summary: '**Use Case**'
description: |-
Get information about the specified user and access other resources
the user has permissions for.
Users are redirected to this endpoint after they sign in.
You can use the **course_enrollments** value in the response to get a
list of courses the user is enrolled in.
**Example Request**
GET /api/mobile/{version}/users/{username}
**Response Values**
If the request is successful, the request returns an HTTP 200 "OK" response.
The HTTP 200 response has the following values.
* course_enrollments: The URI to list the courses the currently signed
in user is enrolled in.
* email: The email address of the currently signed in user.
* id: The ID of the user.
* name: The full name of the currently signed in user.
* username: The username of the currently signed in user.
parameters: []
responses:
'200':
description: ''
schema:
$ref: '#/definitions/mobile_api.User'
tags:
- mobile
parameters:
- name: api_version
in: path
required: true
type: string
- name: username
in: path
description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_
only.
required: true
type: string
pattern: ^[\w.@+-]+$
/mobile/{api_version}/users/{username}/course_enrollments/:
get:
operationId: mobile_users_course_enrollments_list
summary: '**Use Case**'
description: |-
Get information about the courses that the currently signed in user is
enrolled in.
v1 differs from v0.5 version by returning ALL enrollments for
a user rather than only the enrollments the user has access to (that haven't expired).
An additional attribute "expiration" has been added to the response, which lists the date
when access to the course will expire or null if it doesn't expire.
**Example Request**
GET /api/mobile/v1/users/{username}/course_enrollments/
**Response Values**
If the request for information about the user is successful, the
request returns an HTTP 200 "OK" response.
The HTTP 200 response has the following values.
* expiration: The course expiration date for given user course pair
or null if the course does not expire.
* certificate: Information about the user's earned certificate in the
course.
* course: A collection of the following data about the course.
* courseware_access: A JSON representation with access information for the course,
including any access errors.
* course_about: The URL to the course about page.
* course_sharing_utm_parameters: Encoded UTM parameters to be included in course sharing url
* course_handouts: The URI to get data for course handouts.
* course_image: The path to the course image.
* course_updates: The URI to get data for course updates.
* discussion_url: The URI to access data for course discussions if
it is enabled, otherwise null.
* end: The end date of the course.
* id: The unique ID of the course.
* name: The name of the course.
* number: The course number.
* org: The organization that created the course.
* start: The date and time when the course starts.
* start_display:
If start_type is a string, then the advertised_start date for the course.
If start_type is a timestamp, then a formatted date for the start of the course.
If start_type is empty, then the value is None and it indicates that the course has not yet started.
* start_type: One of either "string", "timestamp", or "empty"
* subscription_id: A unique "clean" (alphanumeric with '_') ID of
the course.
* video_outline: The URI to get the list of all videos that the user
can access in the course.
* created: The date the course was created.
* is_active: Whether the course is currently active. Possible values
are true or false.
* mode: The type of certificate registration for this course (honor or
certified).
* url: URL to the downloadable version of the certificate, if exists.
parameters: []
responses:
'200':
description: ''
schema:
type: array
items:
$ref: '#/definitions/CourseEnrollment'
tags:
- mobile
parameters:
- name: api_version
in: path
required: true
type: string
- name: username
in: path
required: true
type: string
? /mobile/{api_version}/users/{username}/course_status_info/(P{course_id}[/+]+{var}[/+]+api/mobile/{api_version}/users/{username}/course_status_info/(P{course_id}[/+]+(/|+)[/+]+{var}[/]+)
: get:
operationId: mobile_users_course_status_info_+]+api_mobile_users_course_status_info_+]+(_|+)[_]+)_list
description: Get the ID of the module that the specified user last visited in
the specified course.
parameters: []
responses:
'200':
description: ''
tags:
- mobile
patch:
operationId: mobile_users_course_status_info_+]+api_mobile_users_course_status_info_+]+(_|+)[_]+)_partial_update
description: Update the ID of the module that the specified user last visited
in the specified course.
parameters: []
responses:
'200':
description: ''
tags:
- mobile
parameters:
- name: api_version
in: path
required: true
type: string
- name: course_id
in: path
required: true
type: string
- name: username
in: path
required: true
type: string
- name: var
in: path
required: true
type: string
/organizations/v0/organizations/:
get:
operationId: organizations_v0_organizations_list
description: "Organization view to:\n - fetch list organization data or single\
\ organization using organization short name.\n - create or update an organization\
\ via the PUT endpoint."
description: |-
Organization view to:
- list organization data (GET .../)
- retrieve single organization (GET .../<short_name>)
- create or update an organization via the PUT endpoint (PUT .../<short_name>)
parameters:
- name: page
in: query
@@ -3482,9 +5188,11 @@ paths:
/organizations/v0/organizations/{short_name}/:
get:
operationId: organizations_v0_organizations_read
description: "Organization view to:\n - fetch list organization data or single\
\ organization using organization short name.\n - create or update an organization\
\ via the PUT endpoint."
description: |-
Organization view to:
- list organization data (GET .../)
- retrieve single organization (GET .../<short_name>)
- create or update an organization via the PUT endpoint (PUT .../<short_name>)
parameters: []
responses:
'200':
@@ -3495,7 +5203,13 @@ paths:
- organizations
put:
operationId: organizations_v0_organizations_update
description: We perform both Update and Create action via the PUT method.
summary: We perform both Update and Create action via the PUT method.
description: |-
The 'active' field may not be specified via the HTTP API, since it
is always assumed to be True. So:
(1) new organizations created through the API are always Active, and
(2) existing organizations updated through the API always end up Active,
regardless of whether or not they were previously active.
parameters:
- name: data
in: body
@@ -3529,8 +5243,9 @@ paths:
parameters:
- name: short_name
in: path
description: Please do not use spaces or special characters. Only allowed
special characters are period (.), hyphen (-) and underscore (_).
description: Unique, short string identifier for organization. Please do not
use spaces or special characters. Only allowed special characters are period
(.), hyphen (-) and underscore (_).
required: true
type: string
/profile_images/v1/{username}/remove:
@@ -3739,8 +5454,9 @@ paths:
/program_enrollments/v1/programs/{program_uuid}/overview/:
get:
operationId: program_enrollments_v1_programs_overview_read
description: "A view for getting data associated with a user's course enrollments\n\
as part of a program enrollment."
description: |-
A view for getting data associated with a user's course enrollments
as part of a program enrollment.
parameters: []
responses:
'200':
@@ -3759,41 +5475,66 @@ paths:
operationId: program_enrollments_v1_users_programs_courses_list
summary: Get an overview of each of a user's course enrollments associated with
a program.
description: "This endpoint exists to get an overview of each course-run enrollment\n\
that a user has for course-runs within a given program.\nFields included are\
\ the title, upcoming due dates, etc.\nThis API endpoint is intended for use\
\ with the\n[Program Learner Portal MFE](https://github.com/edx/frontend-app-learner-portal-programs).\n\
\nIt is important to note that the set of enrollments that this endpoint returns\n\
is different than a user's set of *program-course-run enrollments*.\nSpecifically,\
\ this endpoint may include course runs that are *within*\nthe specified program\
\ but were not *enrolled in* via the specified program.\n\n**Example Response:**\n\
```json\n{\n \"next\": null,\n \"previous\": null,\n \"results\"\
: [\n {\n \"course_run_id\": \"edX+AnimalsX+Aardvarks\"\
,\n \"display_name\": \"Astonishing Aardvarks\",\n \"\
course_run_url\": \"https://courses.edx.org/courses/course-v1:edX+AnimalsX+Aardvarks/course/\"\
,\n \"start_date\": \"2017-02-05T05:00:00Z\",\n \"end_date\"\
: \"2018-02-05T05:00:00Z\",\n \"course_run_status\": \"completed\"\
\n \"emails_enabled\": true,\n \"due_dates\": [\n \
\ {\n \"name\": \"Introduction: What even\
\ is an aardvark?\",\n \"url\": \"https://courses.edx.org/courses/course-v1:edX+AnimalsX+Aardvarks/jump_to/\n\
\ block-v1:edX+AnimalsX+Aardvarks+type@chapter+block@1414ffd5143b4b508f739b563ab468b7\"\
,\n \"date\": \"2017-05-01T05:00:00Z\"\n \
\ },\n {\n \"name\": \"Quiz: Aardvark or\
\ Anteater?\",\n \"url\": \"https://courses.edx.org/courses/course-v1:edX+AnimalsX+Aardvarks/jump_to/\n\
\ block-v1:edX+AnimalsX+Aardvarks+type@sequential+block@edx_introduction\"\
,\n \"date\": \"2017-03-05T00:00:00Z\"\n \
\ }\n ],\n \"micromasters_title\": \"Animals\",\n \
\ \"certificate_download_url\": \"https://courses.edx.org/certificates/123\"\
\n },\n {\n \"course_run_id\": \"edX+AnimalsX+Baboons\"\
,\n \"display_name\": \"Breathtaking Baboons\",\n \"\
course_run_url\": \"https://courses.edx.org/courses/course-v1:edX+AnimalsX+Baboons/course/\"\
,\n \"start_date\": \"2018-02-05T05:00:00Z\",\n \"end_date\"\
: null,\n \"course_run_status\": \"in_progress\"\n \"\
emails_enabled\": false,\n \"due_dates\": [],\n \"micromasters_title\"\
: \"Animals\",\n \"certificate_download_url\": \"https://courses.edx.org/certificates/123\"\
,\n \"resume_course_run_url\": \"https://courses.edx.org/courses/course-v1:edX+AnimalsX+Baboons/jump_to/\n\
\ block-v1:edX+AnimalsX+Baboons+type@sequential+block@edx_introduction\"\
\n }\n ]\n}\n```"
description: |-
This endpoint exists to get an overview of each course-run enrollment
that a user has for course-runs within a given program.
Fields included are the title, upcoming due dates, etc.
This API endpoint is intended for use with the
[Program Learner Portal MFE](https://github.com/edx/frontend-app-learner-portal-programs).
It is important to note that the set of enrollments that this endpoint returns
is different than a user's set of *program-course-run enrollments*.
Specifically, this endpoint may include course runs that are *within*
the specified program but were not *enrolled in* via the specified program.
**Example Response:**
```json
{
"next": null,
"previous": null,
"results": [
{
"course_run_id": "edX+AnimalsX+Aardvarks",
"display_name": "Astonishing Aardvarks",
"course_run_url": "https://courses.edx.org/courses/course-v1:edX+AnimalsX+Aardvarks/course/",
"start_date": "2017-02-05T05:00:00Z",
"end_date": "2018-02-05T05:00:00Z",
"course_run_status": "completed"
"emails_enabled": true,
"due_dates": [
{
"name": "Introduction: What even is an aardvark?",
"url": "https://courses.edx.org/courses/course-v1:edX+AnimalsX+Aardvarks/jump_to/
block-v1:edX+AnimalsX+Aardvarks+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
"date": "2017-05-01T05:00:00Z"
},
{
"name": "Quiz: Aardvark or Anteater?",
"url": "https://courses.edx.org/courses/course-v1:edX+AnimalsX+Aardvarks/jump_to/
block-v1:edX+AnimalsX+Aardvarks+type@sequential+block@edx_introduction",
"date": "2017-03-05T00:00:00Z"
}
],
"micromasters_title": "Animals",
"certificate_download_url": "https://courses.edx.org/certificates/123"
},
{
"course_run_id": "edX+AnimalsX+Baboons",
"display_name": "Breathtaking Baboons",
"course_run_url": "https://courses.edx.org/courses/course-v1:edX+AnimalsX+Baboons/course/",
"start_date": "2018-02-05T05:00:00Z",
"end_date": null,
"course_run_status": "in_progress"
"emails_enabled": false,
"due_dates": [],
"micromasters_title": "Animals",
"certificate_download_url": "https://courses.edx.org/certificates/123",
"resume_course_run_url": "https://courses.edx.org/courses/course-v1:edX+AnimalsX+Baboons/jump_to/
block-v1:edX+AnimalsX+Baboons+type@sequential+block@edx_introduction"
}
]
}
```
parameters:
- name: cursor
in: query
@@ -4064,10 +5805,18 @@ paths:
get:
operationId: third_party_auth_v0_providers_user_status_list
summary: GET /api/third_party_auth/v0/providers/user_status/
description: "**GET Response Values**\n```\n{\n \"accepts_logins\": true,\n\
\ \"name\": \"Google\",\n \"disconnect_url\": \"/auth/disconnect/google-oauth2/?\"\
,\n \"connect_url\": \"/auth/login/google-oauth2/?auth_entry=account_settings&next=%2Faccount%2Fsettings\"\
,\n \"connected\": false,\n \"id\": \"oa2-google-oauth2\"\n}\n```"
description: |-
**GET Response Values**
```
{
"accepts_logins": true,
"name": "Google",
"disconnect_url": "/auth/disconnect/google-oauth2/?",
"connect_url": "/auth/login/google-oauth2/?auth_entry=account_settings&next=%2Faccount%2Fsettings",
"connected": false,
"id": "oa2-google-oauth2"
}
```
parameters: []
responses:
'200':
@@ -4079,39 +5828,73 @@ paths:
get:
operationId: third_party_auth_v0_providers_users_list
summary: Map between the third party auth account IDs (remote_id) and EdX username.
description: "This API is intended to be a server-to-server endpoint. An on-campus\
\ middleware or system should consume this.\n\n**Use Case**\n\n Get a paginated\
\ list of mappings between edX users and remote user IDs for all users currently\n\
\ linked to the given backend.\n\n The list can be filtered by edx username\
\ or third party ids. The filter is limited by the max length of URL.\n \
\ It is suggested to query no more than 50 usernames or remote_ids in each\
\ request to stay within above\n limitation\n\n The page size can be\
\ changed by specifying `page_size` parameter in the request.\n\n**Example\
\ Requests**\n\n GET /api/third_party_auth/v0/providers/{provider_id}/users\n\
\n GET /api/third_party_auth/v0/providers/{provider_id}/users?username={username1},{username2}\n\
\n GET /api/third_party_auth/v0/providers/{provider_id}/users?username={username1}&usernames={username2}\n\
\n GET /api/third_party_auth/v0/providers/{provider_id}/users?remote_id={remote_id1},{remote_id2}\n\
\n GET /api/third_party_auth/v0/providers/{provider_id}/users?remote_id={remote_id1}&remote_id={remote_id2}\n\
\n GET /api/third_party_auth/v0/providers/{provider_id}/users?username={username1}&remote_id={remote_id1}\n\
\n**URL Parameters**\n\n * provider_id: The unique identifier of third_party_auth\
\ provider (e.g. \"saml-ubc\", \"oa2-google\", etc.\n This is not the\
\ same thing as the backend_name.). (Optional/future: We may also want to\
\ allow\n this to be an 'external domain' like 'ssl:MIT' so that this\
\ API can also search the legacy\n ExternalAuthMap table used by Standford/MIT)\n\
\n**Query Parameters**\n\n * remote_ids: Optional. List of comma separated\
\ remote (third party) user IDs to filter the result set.\n e.g. ?remote_ids=8721384623\n\
\n * usernames: Optional. List of comma separated edX usernames to filter\
\ the result set.\n e.g. ?usernames=bob123,jane456\n\n * page, page_size:\
\ Optional. Used for paging the result set, especially when getting\n \
\ an unfiltered list.\n\n**Response Values**\n\n If the request for information\
\ about the user is successful, an HTTP 200 \"OK\" response\n is returned.\n\
\n The HTTP 200 response has the following values:\n\n * count: The\
\ number of mappings for the backend.\n\n * next: The URI to the next page\
\ of the mappings.\n\n * previous: The URI to the previous page of the\
\ mappings.\n\n * num_pages: The number of pages listing the mappings.\n\
\n * results: A list of mappings returned. Each collection in the list\n\
\ contains these fields.\n\n * username: The edx username\n\n\
\ * remote_id: The Id from third party auth provider"
description: |-
This API is intended to be a server-to-server endpoint. An on-campus middleware or system should consume this.
**Use Case**
Get a paginated list of mappings between edX users and remote user IDs for all users currently
linked to the given backend.
The list can be filtered by edx username or third party ids. The filter is limited by the max length of URL.
It is suggested to query no more than 50 usernames or remote_ids in each request to stay within above
limitation
The page size can be changed by specifying `page_size` parameter in the request.
**Example Requests**
GET /api/third_party_auth/v0/providers/{provider_id}/users
GET /api/third_party_auth/v0/providers/{provider_id}/users?username={username1},{username2}
GET /api/third_party_auth/v0/providers/{provider_id}/users?username={username1}&usernames={username2}
GET /api/third_party_auth/v0/providers/{provider_id}/users?remote_id={remote_id1},{remote_id2}
GET /api/third_party_auth/v0/providers/{provider_id}/users?remote_id={remote_id1}&remote_id={remote_id2}
GET /api/third_party_auth/v0/providers/{provider_id}/users?username={username1}&remote_id={remote_id1}
**URL Parameters**
* provider_id: The unique identifier of third_party_auth provider (e.g. "saml-ubc", "oa2-google", etc.
This is not the same thing as the backend_name.). (Optional/future: We may also want to allow
this to be an 'external domain' like 'ssl:MIT' so that this API can also search the legacy
ExternalAuthMap table used by Standford/MIT)
**Query Parameters**
* remote_ids: Optional. List of comma separated remote (third party) user IDs to filter the result set.
e.g. ?remote_ids=8721384623
* usernames: Optional. List of comma separated edX usernames to filter the result set.
e.g. ?usernames=bob123,jane456
* page, page_size: Optional. Used for paging the result set, especially when getting
an unfiltered list.
**Response Values**
If the request for information about the user is successful, an HTTP 200 "OK" response
is returned.
The HTTP 200 response has the following values:
* count: The number of mappings for the backend.
* next: The URI to the next page of the mappings.
* previous: The URI to the previous page of the mappings.
* num_pages: The number of pages listing the mappings.
* results: A list of mappings returned. Each collection in the list
contains these fields.
* username: The edx username
* remote_id: The Id from third party auth provider
parameters:
- name: page
in: query
@@ -4188,8 +5971,9 @@ paths:
/third_party_auth_context:
get:
operationId: third_party_auth_context_list
description: Returns the context for third party auth providers and the currently
running pipeline.
description: |-
Returns the context for third party auth providers, user country code
and the currently running pipeline.
parameters: []
responses:
'200':
@@ -4200,7 +5984,7 @@ paths:
/toggles/v0/state/:
get:
operationId: toggles_v0_state_list
description: An endpoint for displaying the state of toggles in edx-platform.
description: Expose toggle state report dict as a view.
parameters: []
responses:
'200':
@@ -4221,8 +6005,15 @@ paths:
post:
operationId: user_v1_account_login_session_create
summary: Log in a user.
description: "See `login_user` for details.\n\nExample Usage:\n\n POST /api/user/v1/login_session\n\
\ with POST params `email`, `password`.\n\n 200 {'success': true}"
description: |-
See `login_user` for details.
Example Usage:
POST /api/user/v1/login_session
with POST params `email`, `password`.
200 {'success': true}
parameters: []
responses:
'201':
@@ -4242,6 +6033,17 @@ paths:
tags:
- user
parameters: []
/user/v1/account/password_reset/token/validate/:
post:
operationId: user_v1_account_password_reset_token_validate_create
description: HTTP end-point to validate password reset token.
parameters: []
responses:
'201':
description: ''
tags:
- user
parameters: []
/user/v1/account/registration/:
get:
operationId: user_v1_account_registration_list
@@ -4255,9 +6057,11 @@ paths:
post:
operationId: user_v1_account_registration_create
summary: Create the user's account.
description: "You must send all required form fields with the request.\n\nYou\
\ can optionally send a \"course_id\" param to indicate in analytics\nevents\
\ that the user registered while enrolling in a particular course."
description: |-
You must send all required form fields with the request.
You can optionally send a "course_id" param to indicate in analytics
events that the user registered while enrolling in a particular course.
parameters: []
responses:
'201':
@@ -4268,13 +6072,15 @@ paths:
/user/v1/accounts:
get:
operationId: user_v1_accounts_list
description: "GET /api/user/v1/accounts?username={username1,username2}\nGET\
\ /api/user/v1/accounts?email={user_email}"
description: |-
GET /api/user/v1/accounts?username={username1},{username2}
GET /api/user/v1/accounts?email={user_email1},{user_email2}
parameters: []
responses:
'200':
description: ''
consumes:
- application/json
- application/merge-patch+json
tags:
- user
@@ -4283,8 +6089,9 @@ paths:
post:
operationId: user_v1_accounts_deactivate_logout_create
summary: POST /api/user/v1/accounts/deactivate_logout/
description: "Marks the user as having no password set for deactivation purposes,\n\
and logs the user out."
description: |-
Marks the user as having no password set for deactivation purposes,
and logs the user out.
parameters: []
responses:
'201':
@@ -4295,17 +6102,39 @@ paths:
/user/v1/accounts/replace_usernames/:
post:
operationId: user_v1_accounts_replace_usernames_create
description: "POST /api/user/v1/accounts/replace_usernames/\n```\n{\n \"\
username_mappings\": [\n {\"current_username_1\": \"desired_username_1\"\
},\n {\"current_username_2\": \"desired_username_2\"}\n ]\n}\n```\n\
\n**POST Parameters**\n\nA POST request must include the following parameter.\n\
\n* username_mappings: Required. A list of objects that map the current username\
\ (key)\n to the desired username (value)\n\n**POST Response Values**\n\n\
As long as data validation passes, the request will return a 200 with a new\
\ mapping\nof old usernames (key) to new username (value)\n\n```\n{\n \"\
successful_replacements\": [\n {\"old_username_1\": \"new_username_1\"\
}\n ],\n \"failed_replacements\": [\n {\"old_username_2\": \"\
new_username_2\"}\n ]\n}\n```"
description: |-
POST /api/user/v1/accounts/replace_usernames/
```
{
"username_mappings": [
{"current_username_1": "desired_username_1"},
{"current_username_2": "desired_username_2"}
]
}
```
**POST Parameters**
A POST request must include the following parameter.
* username_mappings: Required. A list of objects that map the current username (key)
to the desired username (value)
**POST Response Values**
As long as data validation passes, the request will return a 200 with a new mapping
of old usernames (key) to new username (value)
```
{
"successful_replacements": [
{"old_username_1": "new_username_1"}
],
"failed_replacements": [
{"old_username_2": "new_username_2"}
]
}
```
parameters: []
responses:
'201':
@@ -4317,9 +6146,16 @@ paths:
post:
operationId: user_v1_accounts_post
summary: POST /api/user/v1/accounts/retire/
description: "```\n{\n 'username': 'user_to_retire'\n}\n```\n\nRetires the\
\ user with the given username. This includes\nretiring this username, the\
\ associated email address, and\nany other PII associated with this user."
description: |-
```
{
'username': 'user_to_retire'
}
```
Retires the user with the given username. This includes
retiring this username, the associated email address, and
any other PII associated with this user.
parameters: []
responses:
'201':
@@ -4331,8 +6167,14 @@ paths:
post:
operationId: user_v1_accounts_post
summary: POST /api/user/v1/accounts/retire_misc/
description: "```\n{\n 'username': 'user_to_retire'\n}\n```\n\nRetires the\
\ user with the given username in the LMS."
description: |-
```
{
'username': 'user_to_retire'
}
```
Retires the user with the given username in the LMS.
parameters: []
responses:
'201':
@@ -4344,8 +6186,14 @@ paths:
post:
operationId: user_v1_accounts_cleanup
summary: POST /api/user/v1/accounts/retirement_cleanup/
description: "```\n{\n 'usernames': ['user1', 'user2', ...]\n}\n```\n\nDeletes\
\ a batch of retirement requests by username."
description: |-
```
{
'usernames': ['user1', 'user2', ...]
}
```
Deletes a batch of retirement requests by username.
parameters: []
responses:
'201':
@@ -4357,9 +6205,10 @@ paths:
post:
operationId: user_v1_accounts_retirement_partner_report_create
summary: POST /api/user/v1/accounts/retirement_partner_report/
description: "Returns the list of UserRetirementPartnerReportingStatus users\n\
that are not already being processed and updates their status\nto indicate\
\ they are currently being processed."
description: |-
Returns the list of UserRetirementPartnerReportingStatus users
that are not already being processed and updates their status
to indicate they are currently being processed.
parameters: []
responses:
'201':
@@ -4369,9 +6218,15 @@ paths:
put:
operationId: user_v1_accounts_retirement_partner_report_update
summary: PUT /api/user/v1/accounts/retirement_partner_report/
description: "```\n{\n 'username': 'user_to_retire'\n}\n```\n\nCreates a\
\ UserRetirementPartnerReportingStatus object for the given user\nas part\
\ of the retirement pipeline."
description: |-
```
{
'username': 'user_to_retire'
}
```
Creates a UserRetirementPartnerReportingStatus object for the given user
as part of the retirement pipeline.
parameters: []
responses:
'200':
@@ -4383,9 +6238,11 @@ paths:
post:
operationId: user_v1_accounts_retirement_partner_cleanup
summary: POST /api/user/v1/accounts/retirement_partner_report_cleanup/
description: "[{'original_username': 'user1'}, {'original_username': 'user2'},\
\ ...]\n\nDeletes UserRetirementPartnerReportingStatus objects for a list\
\ of users\nthat have been reported on."
description: |-
[{'original_username': 'user1'}, {'original_username': 'user2'}, ...]
Deletes UserRetirementPartnerReportingStatus objects for a list of users
that have been reported on.
parameters: []
responses:
'201':
@@ -4396,10 +6253,12 @@ paths:
/user/v1/accounts/retirement_queue/:
get:
operationId: user_v1_accounts_retirement_queue
summary: "GET /api/user/v1/accounts/retirement_queue/\n{'cool_off_days': 7,\
\ 'states': ['PENDING', 'COMPLETE']}"
description: "Returns the list of RetirementStatus users in the given states\
\ that were\ncreated in the retirement queue at least `cool_off_days` ago."
summary: |-
GET /api/user/v1/accounts/retirement_queue/
{'cool_off_days': 7, 'states': ['PENDING', 'COMPLETE']}
description: |-
Returns the list of RetirementStatus users in the given states that were
created in the retirement queue at least `cool_off_days` ago.
parameters: []
responses:
'200':
@@ -4410,11 +6269,14 @@ paths:
/user/v1/accounts/retirements_by_status_and_date/:
get:
operationId: user_v1_accounts_retirements_by_status_and_date
summary: "GET /api/user/v1/accounts/retirements_by_status_and_date/\n?start_date=2018-09-05&end_date=2018-09-07&state=COMPLETE"
description: "Returns a list of UserRetirementStatusSerializer serialized\n\
RetirementStatus rows in the given state that were created in the\nretirement\
\ queue between the dates given. Date range is inclusive,\nso to get one day\
\ you would set both dates to that day."
summary: |-
GET /api/user/v1/accounts/retirements_by_status_and_date/
?start_date=2018-09-05&end_date=2018-09-07&state=COMPLETE
description: |-
Returns a list of UserRetirementStatusSerializer serialized
RetirementStatus rows in the given state that were created in the
retirement queue between the dates given. Date range is inclusive,
so to get one day you would set both dates to that day.
parameters: []
responses:
'200':
@@ -4422,17 +6284,45 @@ paths:
tags:
- user
parameters: []
/user/v1/accounts/search_emails:
post:
operationId: user_v1_accounts_search_emails
description: |-
POST /api/user/v1/accounts/search_emails
Content Type: "application/json"
{
"emails": ["edx@example.com", "staff@example.com"]
}
parameters: []
responses:
'201':
description: ''
consumes:
- application/json
- application/merge-patch+json
tags:
- user
parameters: []
/user/v1/accounts/update_retirement_status/:
patch:
operationId: user_v1_accounts_update_retirement_status_partial_update
summary: PATCH /api/user/v1/accounts/update_retirement_status/
description: "```\n{\n 'username': 'user_to_retire',\n 'new_state': 'LOCKING_COMPLETE',\n\
\ 'response': 'User account locked and logged out.'\n}\n```\n\nUpdates\
\ the RetirementStatus row for the given user to the new\nstatus, and append\
\ any messages to the message log.\n\nNote that this implementation DOES NOT\
\ use the \"merge patch\"\nimplementation seen in AccountViewSet. Slumber,\
\ the project\nwe use to power edx-rest-api-client, does not currently support\n\
it. The content type for this request is 'application/json'."
description: |-
```
{
'username': 'user_to_retire',
'new_state': 'LOCKING_COMPLETE',
'response': 'User account locked and logged out.'
}
```
Updates the RetirementStatus row for the given user to the new
status, and append any messages to the message log.
Note that this implementation DOES NOT use the "merge patch"
implementation seen in AccountViewSet. Slumber, the project
we use to power edx-rest-api-client, does not currently support
it. The content type for this request is 'application/json'.
parameters: []
responses:
'200':
@@ -4449,6 +6339,7 @@ paths:
'200':
description: ''
consumes:
- application/json
- application/merge-patch+json
tags:
- user
@@ -4462,6 +6353,7 @@ paths:
'200':
description: ''
consumes:
- application/json
- application/merge-patch+json
tags:
- user
@@ -4519,8 +6411,10 @@ paths:
/user/v1/accounts/{username}/retirement_status/:
get:
operationId: user_v1_accounts_retirement_status_read
description: "GET /api/user/v1/accounts/{username}/retirement_status/\nReturns\
\ the RetirementStatus of a given user, or 404 if that row\ndoesn't exist."
description: |-
GET /api/user/v1/accounts/{username}/retirement_status/
Returns the RetirementStatus of a given user, or 404 if that row
doesn't exist.
parameters: []
responses:
'200':
@@ -4534,8 +6428,8 @@ paths:
type: string
/user/v1/accounts/{username}/verification_status/:
get:
operationId: user_v1_accounts_verification_status_read
description: IDVerificationStatus detail endpoint.
operationId: user_v1_accounts_verification_status_list
description: IDVerification Status endpoint
parameters: []
responses:
'200':
@@ -4621,6 +6515,7 @@ paths:
'200':
description: ''
consumes:
- application/json
- application/merge-patch+json
tags:
- user
@@ -4629,8 +6524,9 @@ paths:
post:
operationId: user_v1_preferences_email_opt_in_create
summary: Post function for updating the email opt in preference.
description: "Allows the modification or creation of the email opt in preference\
\ at an\norganizational level."
description: |-
Allows the modification or creation of the email opt in preference at an
organizational level.
parameters: []
responses:
'201':
@@ -4642,17 +6538,28 @@ paths:
get:
operationId: user_v1_preferences_time_zones_list
summary: '**Use Cases**'
description: "Retrieves a list of all time zones, by default, or common time\
\ zones for country, if given\n\n The country is passed in as its ISO 3166-1\
\ Alpha-2 country code as an\n optional 'country_code' argument. The country\
\ code is also case-insensitive.\n\n**Example Requests**\n\n GET /api/user/v1/preferences/time_zones/\n\
\n GET /api/user/v1/preferences/time_zones/?country_code=FR\n\n**Example\
\ GET Response**\n\n If the request is successful, an HTTP 200 \"OK\" response\
\ is returned along with a\n list of time zone dictionaries for all time\
\ zones or just for time zones commonly\n used in a country, if given.\n\
\n Each time zone dictionary contains the following values.\n\n \
\ * time_zone: The name of the time zone.\n * description: The display\
\ version of the time zone"
description: |-
Retrieves a list of all time zones, by default, or common time zones for country, if given
The country is passed in as its ISO 3166-1 Alpha-2 country code as an
optional 'country_code' argument. The country code is also case-insensitive.
**Example Requests**
GET /api/user/v1/preferences/time_zones/
GET /api/user/v1/preferences/time_zones/?country_code=FR
**Example GET Response**
If the request is successful, an HTTP 200 "OK" response is returned along with a
list of time zone dictionaries for all time zones or just for time zones commonly
used in a country, if given.
Each time zone dictionary contains the following values.
* time_zone: The name of the time zone.
* description: The display version of the time zone
parameters: []
responses:
'200':
@@ -4906,13 +6813,22 @@ paths:
post:
operationId: user_v1_validation_registration_create
summary: POST /api/user/v1/validation/registration/
description: "Expects request of the form\n```\n{\n \"name\": \"Dan the Validator\"\
,\n \"username\": \"mslm\",\n \"email\": \"mslm@gmail.com\",\n \"\
confirm_email\": \"mslm@gmail.com\",\n \"password\": \"password123\",\n\
\ \"country\": \"PK\"\n}\n```\nwhere each key is the appropriate form field\
\ name and the value is\nuser input. One may enter individual inputs if needed.\
\ Some inputs\ncan get extra verification checks if entered along with others,\n\
like when the password may not equal the username."
description: |-
Expects request of the form
```
{
"name": "Dan the Validator",
"username": "mslm",
"email": "mslm@gmail.com",
"confirm_email": "mslm@gmail.com",
"password": "password123",
"country": "PK"
}
```
where each key is the appropriate form field name and the value is
user input. One may enter individual inputs if needed. Some inputs
can get extra verification checks if entered along with others,
like when the password may not equal the username.
parameters: []
responses:
'201':
@@ -4933,9 +6849,11 @@ paths:
post:
operationId: user_v2_account_registration_create
summary: Create the user's account.
description: "You must send all required form fields with the request.\n\nYou\
\ can optionally send a \"course_id\" param to indicate in analytics\nevents\
\ that the user registered while enrolling in a particular course."
description: |-
You must send all required form fields with the request.
You can optionally send a "course_id" param to indicate in analytics
events that the user registered while enrolling in a particular course.
parameters: []
responses:
'201':
@@ -5005,18 +6923,34 @@ paths:
operationId: val_v0_videos_missing-hls_create
summary: 'Retrieve video IDs that are missing HLS profiles. This endpoint supports
2 types of input data:'
description: "1. If we want a batch of video ids which are missing HLS profile\
\ irrespective of their courses, the request\n data should be in following\
\ format:\n {\n 'batch_size': 50,\n 'offset':\
\ 0\n }\n And response will be in following format:\n {\n\
\ 'videos': ['video_id1', 'video_id2', 'video_id3', ... , video_id50],\n\
\ 'total': 300,\n 'offset': 50,\n 'batch_size':\
\ 50\n }\n\n2. If we want all the videos which are missing HLS profiles\
\ in a set of specific courses, the request data\n should be in following\
\ format:\n {\n 'courses': [\n 'course_id1',\n\
\ 'course_id2',\n ...\n ]\n \
\ }\n And response will be in following format:\n {\n \
\ 'videos': ['video_id1', 'video_id2', 'video_id3', ...]\n }"
description: |-
1. If we want a batch of video ids which are missing HLS profile irrespective of their courses, the request
data should be in following format:
{
'batch_size': 50,
'offset': 0
}
And response will be in following format:
{
'videos': ['video_id1', 'video_id2', 'video_id3', ... , video_id50],
'total': 300,
'offset': 50,
'batch_size': 50
}
2. If we want all the videos which are missing HLS profiles in a set of specific courses, the request data
should be in following format:
{
'courses': [
'course_id1',
'course_id2',
...
]
}
And response will be in following format:
{
'videos': ['video_id1', 'video_id2', 'video_id3', ...]
}
parameters: []
responses:
'201':
@@ -5026,10 +6960,19 @@ paths:
put:
operationId: val_v0_videos_missing-hls_update
summary: Update a single profile for a given video.
description: "Example request data:\n ```\n {\n 'edx_video_id':\
\ '1234'\n 'profile': 'hls',\n 'encode_data': {\n \
\ 'url': 'foo.com/qwe.m3u8'\n 'file_size': 34\n 'bitrate':\
\ 12\n }\n }\n ```"
description: |-
Example request data:
```
{
'edx_video_id': '1234'
'profile': 'hls',
'encode_data': {
'url': 'foo.com/qwe.m3u8'
'file_size': 34
'bitrate': 12
}
}
```
parameters: []
responses:
'200':
@@ -5134,9 +7077,9 @@ paths:
get:
operationId: xblock_v2_xblocks_read
summary: Get metadata about the specified block.
description: "Accepts an \"include\" query parameter which must be a comma separated\
\ list of keys to include. Valid keys are\n\"index_dictionary\" and \"student_view_data\"\
."
description: |-
Accepts an "include" query parameter which must be a comma separated list of keys to include. Valid keys are
"index_dictionary" and "student_view_data".
parameters: []
responses:
'200':
@@ -5151,8 +7094,9 @@ paths:
/xblock/v2/xblocks/{usage_key_str}/handler_url/{handler_name}/:
get:
operationId: xblock_v2_xblocks_handler_url_read
summary: "Get an absolute URL which can be used (without any authentication)\
\ to call\nthe given XBlock handler."
summary: |-
Get an absolute URL which can be used (without any authentication) to call
the given XBlock handler.
description: The URL will expire but is guaranteed to be valid for a minimum
of 2 days.
parameters: []
@@ -5190,6 +7134,115 @@ paths:
required: true
type: string
definitions:
BadgeClass:
required:
- slug
- display_name
- description
- criteria
type: object
properties:
slug:
title: Slug
type: string
format: slug
pattern: ^[-a-zA-Z0-9_]+$
maxLength: 255
minLength: 1
issuing_component:
title: Issuing component
type: string
format: slug
pattern: ^[-a-zA-Z0-9_]+$
default: ''
maxLength: 50
display_name:
title: Display name
type: string
maxLength: 255
minLength: 1
course_id:
title: Course id
type: string
maxLength: 255
description:
title: Description
type: string
minLength: 1
criteria:
title: Criteria
type: string
minLength: 1
image_url:
title: Image url
type: string
readOnly: true
format: uri
BadgeAssertion:
required:
- image_url
- assertion_url
type: object
properties:
badge_class:
$ref: '#/definitions/BadgeClass'
image_url:
title: Image url
type: string
format: uri
maxLength: 200
minLength: 1
assertion_url:
title: Assertion url
type: string
format: uri
maxLength: 200
minLength: 1
created:
title: Created
type: string
format: date-time
readOnly: true
CCXCourse:
required:
- master_course_id
- display_name
- coach_email
- start
- due
- max_students_allowed
type: object
properties:
ccx_course_id:
title: Ccx course id
type: string
readOnly: true
master_course_id:
title: Master course id
type: string
minLength: 1
display_name:
title: Display name
type: string
minLength: 1
coach_email:
title: Coach email
type: string
format: email
minLength: 1
start:
title: Start
type: string
due:
title: Due
type: string
max_students_allowed:
title: Max students allowed
type: integer
course_modules:
title: Course modules
type: string
readOnly: true
CohortUsersAPI:
required:
- username
@@ -5328,6 +7381,7 @@ definitions:
CourseHomeMetadata:
required:
- course_id
- username
- is_enrolled
- is_self_paced
- is_staff
@@ -5336,12 +7390,18 @@ definitions:
- original_user_is_staff
- tabs
- title
- can_load_courseware
- celebrations
type: object
properties:
course_id:
title: Course id
type: string
minLength: 1
username:
title: Username
type: string
minLength: 1
is_enrolled:
title: Is enrolled
type: boolean
@@ -5370,6 +7430,15 @@ definitions:
title: Title
type: string
minLength: 1
can_load_courseware:
title: Can load courseware
type: boolean
celebrations:
title: Celebrations
type: object
additionalProperties:
type: string
x-nullable: true
DateSummary:
required:
- complete
@@ -5388,6 +7457,7 @@ definitions:
complete:
title: Complete
type: boolean
x-nullable: true
date:
title: Date
type: string
@@ -5420,6 +7490,10 @@ definitions:
title: Extra info
type: string
minLength: 1
first_component_block_id:
title: First component block id
type: string
readOnly: true
DatesTab:
required:
- course_date_blocks
@@ -5447,7 +7521,6 @@ definitions:
type: string
minLength: 1
CourseBlock:
title: Course blocks
type: object
properties:
blocks:
@@ -5455,7 +7528,6 @@ definitions:
type: string
readOnly: true
CourseGoals:
title: Course goals
required:
- goal_options
- selected_goal
@@ -5465,11 +7537,13 @@ definitions:
type: array
items:
type: string
x-nullable: true
selected_goal:
title: Selected goal
type: object
additionalProperties:
type: string
x-nullable: true
CourseTool:
required:
- analytics_id
@@ -5489,7 +7563,6 @@ definitions:
type: string
readOnly: true
DatesWidget:
title: Dates widget
required:
- course_date_blocks
- dates_tab_link
@@ -5509,7 +7582,6 @@ definitions:
type: string
minLength: 1
EnrollAlert:
title: Enroll alert
required:
- can_enroll
- extra_text
@@ -5523,7 +7595,6 @@ definitions:
type: string
minLength: 1
ResumeCourse:
title: Resume course
required:
- has_visited_course
- url
@@ -5539,15 +7610,15 @@ definitions:
minLength: 1
OutlineTab:
required:
- access_expiration
- course_blocks
- course_expired_html
- course_goals
- course_tools
- dates_widget
- enroll_alert
- handouts_html
- has_ended
- offer_html
- offer
- resume_course
- welcome_message_html
type: object
@@ -5556,12 +7627,22 @@ definitions:
title: Dates banner info
type: string
readOnly: true
can_show_upgrade_sock:
title: Can show upgrade sock
type: string
readOnly: true
verified_mode:
title: Verified mode
type: string
readOnly: true
access_expiration:
title: Access expiration
type: object
additionalProperties:
type: string
x-nullable: true
course_blocks:
$ref: '#/definitions/CourseBlock'
course_expired_html:
title: Course expired html
type: string
minLength: 1
course_goals:
$ref: '#/definitions/CourseGoals'
course_tools:
@@ -5579,10 +7660,12 @@ definitions:
has_ended:
title: Has ended
type: boolean
offer_html:
title: Offer html
type: string
minLength: 1
offer:
title: Offer
type: object
additionalProperties:
type: string
x-nullable: true
resume_course:
$ref: '#/definitions/ResumeCourse'
welcome_message_html:
@@ -5590,13 +7673,10 @@ definitions:
type: string
minLength: 1
CertificateData:
title: Certificate data
required:
- cert_status
- cert_web_view_url
- download_url
- msg
- title
type: object
properties:
cert_status:
@@ -5611,104 +7691,54 @@ definitions:
title: Download url
type: string
minLength: 1
msg:
title: Msg
type: string
minLength: 1
title:
title: Title
type: string
minLength: 1
CreditRequirement:
CourseGrade:
required:
- display_name
- status
- status_date
- letter_grade
- percent
- is_passing
type: object
properties:
display_name:
title: Display name
letter_grade:
title: Letter grade
type: string
minLength: 1
min_grade:
title: Min grade
type: string
readOnly: true
status:
title: Status
type: string
minLength: 1
status_date:
title: Status date
type: string
format: date-time
CreditCourseRequirements:
title: Credit course requirements
required:
- eligibility_status
- requirements
type: object
properties:
dashboard_url:
title: Dashboard url
type: string
readOnly: true
eligibility_status:
title: Eligibility status
type: string
minLength: 1
requirements:
type: array
items:
$ref: '#/definitions/CreditRequirement'
GradedTotal:
title: Graded total
required:
- earned
- possible
type: object
properties:
earned:
title: Earned
percent:
title: Percent
type: number
possible:
title: Possible
type: number
Subsection:
is_passing:
title: Is passing
type: boolean
SubsectionScores:
required:
- assignment_type
- display_name
- due
- format
- graded
- graded_total
- has_graded_assignment
- num_points_earned
- num_points_possible
- percent_graded
- show_correctness
type: object
properties:
assignment_type:
title: Assignment type
type: string
minLength: 1
display_name:
title: Display name
type: string
minLength: 1
due:
title: Due
type: string
format: date-time
format:
title: Format
type: string
minLength: 1
graded:
title: Graded
has_graded_assignment:
title: Has graded assignment
type: boolean
graded_total:
$ref: '#/definitions/GradedTotal'
num_points_earned:
title: Num points earned
type: integer
num_points_possible:
title: Num points possible
type: integer
percent_graded:
title: Percent graded
type: number
problem_scores:
title: Problem scores
type: string
readOnly: true
show_correctness:
title: Show correctness
type: string
@@ -5721,7 +7751,7 @@ definitions:
title: Url
type: string
readOnly: true
Chapter:
SectionScores:
required:
- display_name
- subsections
@@ -5734,9 +7764,23 @@ definitions:
subsections:
type: array
items:
$ref: '#/definitions/Subsection'
$ref: '#/definitions/SubsectionScores'
GradingPolicy:
required:
- grade_range
type: object
properties:
assignment_policies:
title: Assignment policies
type: string
readOnly: true
grade_range:
title: Grade range
type: object
additionalProperties:
type: string
x-nullable: true
VerificationData:
title: Verification data
required:
- link
- status
@@ -5759,40 +7803,52 @@ definitions:
ProgressTab:
required:
- certificate_data
- credit_course_requirements
- credit_support_url
- courseware_summary
- completion_summary
- course_grade
- end
- user_has_passing_grade
- has_scheduled_content
- section_scores
- enrollment_mode
- grading_policy
- studio_url
- user_timezone
- verification_data
type: object
properties:
certificate_data:
$ref: '#/definitions/CertificateData'
credit_course_requirements:
$ref: '#/definitions/CreditCourseRequirements'
credit_support_url:
title: Credit support url
completion_summary:
title: Completion summary
type: object
additionalProperties:
type: string
x-nullable: true
course_grade:
$ref: '#/definitions/CourseGrade'
end:
title: End
type: string
format: uri
minLength: 1
courseware_summary:
format: date-time
user_has_passing_grade:
title: User has passing grade
type: boolean
has_scheduled_content:
title: Has scheduled content
type: boolean
section_scores:
type: array
items:
$ref: '#/definitions/Chapter'
$ref: '#/definitions/SectionScores'
enrollment_mode:
title: Enrollment mode
type: string
minLength: 1
grading_policy:
$ref: '#/definitions/GradingPolicy'
studio_url:
title: Studio url
type: string
minLength: 1
user_timezone:
title: User timezone
type: string
minLength: 1
verification_data:
$ref: '#/definitions/VerificationData'
course_modes.CourseMode:
@@ -5841,8 +7897,18 @@ definitions:
title: Bulk sku
type: string
minLength: 1
_AbsolutMedia:
type: object
properties:
uri:
title: Uri
type: string
readOnly: true
uri_absolute:
title: Uri absolute
type: string
readOnly: true
_Media:
title: Course image
type: object
properties:
uri:
@@ -5850,7 +7916,6 @@ definitions:
type: string
readOnly: true
Image:
title: Image
required:
- raw
- small
@@ -5873,13 +7938,15 @@ definitions:
format: uri
minLength: 1
_CourseApiMediaCollection:
title: Media
required:
- banner_image
- course_image
- course_video
- image
type: object
properties:
banner_image:
$ref: '#/definitions/_AbsolutMedia'
course_image:
$ref: '#/definitions/_Media'
course_video:
@@ -6361,6 +8428,247 @@ definitions:
type: string
format: date-time
readOnly: true
ReportDownload:
description: Report Download
required:
- url
- name
- link
type: object
properties:
url:
title: Url
description: URL from which report can be downloaded.
type: string
format: uri
minLength: 1
name:
title: Name
description: Name of report.
type: string
minLength: 1
link:
title: Link
description: HTML anchor tag that contains the name and link.
type: string
minLength: 1
ReportDownloadsList:
required:
- downloads
type: object
properties:
downloads:
description: List of report downloads
type: array
items:
$ref: '#/definitions/ReportDownload'
ProblemResponseReportPostParams:
required:
- problem_locations
type: object
properties:
problem_locations:
description: 'A list of usage keys for the blocks to include in the report. '
type: array
items:
description: A usage key location for a section or a problem. If the location
is a block that contains other blocks, (such as the course, section, subsection,
or unit blocks) then all blocks under that block will be included in the
report.
type: string
minLength: 1
problem_types_filter:
description: 'A list of problem/block types to generate the report for. This
field can be omitted if the report should include details of allblock types. '
type: array
items:
type: string
minLength: 1
ProblemResponsesReportStatus:
required:
- status
- task_id
type: object
properties:
status:
title: Status
description: User-friendly text describing current status of report generation.
type: string
minLength: 1
task_id:
title: Task id
description: A unique id for the report generation task. It can be used to
query the latest report generation status.
type: string
format: uuid
InstructorTask:
required:
- status
- task_type
- task_id
- created
- task_input
- requester
- task_state
- duration_sec
- task_message
type: object
properties:
status:
title: Status
description: Current status of task.
type: string
minLength: 1
task_type:
title: Task type
description: Identifies the kind of task being performed, e.g. rescoring.
type: string
minLength: 1
task_id:
title: Task id
description: The celery ID for the task.
type: string
minLength: 1
created:
title: Created
description: The date and time when the task was created.
type: string
format: date-time
task_input:
title: Task input
description: The input parameters for the task. The format and content of
this data will depend on the kind of task being performed. For instanceit
may contain the problem locations for a problem resources task.
type: object
additionalProperties:
type: string
x-nullable: true
requester:
title: Requester
description: The username of the user who initiated this task.
type: string
minLength: 1
task_state:
title: Task state
description: The last knows state of the celery task.
type: string
minLength: 1
duration_sec:
title: Duration sec
description: Task duration information, if known
type: string
minLength: 1
task_message:
title: Task message
description: User-friendly task status information, if available.
type: string
minLength: 1
InstructorTasksList:
required:
- tasks
type: object
properties:
tasks:
description: List of instructor tasks.
type: array
items:
$ref: '#/definitions/InstructorTask'
LtiAgsLineItem:
required:
- resourceId
- scoreMaximum
- label
type: object
properties:
id:
title: Id
type: string
readOnly: true
resourceId:
title: Resourceid
type: string
minLength: 1
scoreMaximum:
title: Scoremaximum
type: integer
label:
title: Label
type: string
maxLength: 100
minLength: 1
tag:
title: Tag
type: string
maxLength: 50
resourceLinkId:
title: Resourcelinkid
type: string
startDateTime:
title: Startdatetime
type: string
format: date-time
endDateTime:
title: Enddatetime
type: string
format: date-time
mobile_api.User:
required:
- username
type: object
properties:
id:
title: ID
type: integer
readOnly: true
username:
title: Username
description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_
only.
type: string
pattern: ^[\w.@+-]+$
maxLength: 150
minLength: 1
email:
title: Email address
type: string
format: email
maxLength: 254
name:
title: Name
type: string
readOnly: true
course_enrollments:
title: Course enrollments
type: string
readOnly: true
CourseEnrollment:
type: object
properties:
audit_access_expires:
title: Audit access expires
type: string
readOnly: true
created:
title: Created
type: string
format: date-time
readOnly: true
mode:
title: Mode
type: string
maxLength: 100
minLength: 1
is_active:
title: Is active
type: boolean
course:
title: Course
type: string
readOnly: true
certificate:
title: Certificate
type: string
readOnly: true
Organization:
required:
- name
@@ -6388,8 +8696,9 @@ definitions:
minLength: 1
short_name:
title: Short Name
description: Please do not use spaces or special characters. Only allowed
special characters are period (.), hyphen (-) and underscore (_).
description: Unique, short string identifier for organization. Please do not
use spaces or special characters. Only allowed special characters are period
(.), hyphen (-) and underscore (_).
type: string
maxLength: 255
minLength: 1
@@ -6576,6 +8885,10 @@ definitions:
title: Updated at
type: string
format: date-time
receipt_id:
title: Receipt id
type: string
readOnly: true
user_api.User:
type: object
properties:

View File

@@ -8,7 +8,6 @@ from django.conf import settings
from edx_django_utils.plugins import PluginSettings, PluginURLs
from edx_proctoring.runtime import set_runtime_service
from openedx.core.constants import COURSE_ID_PATTERN
from openedx.core.djangoapps.plugins.constants import ProjectType, SettingsType
@@ -22,8 +21,8 @@ class InstructorConfig(AppConfig):
PluginURLs.CONFIG: {
ProjectType.LMS: {
PluginURLs.NAMESPACE: '',
PluginURLs.REGEX: f'^courses/{COURSE_ID_PATTERN}/instructor/api/',
PluginURLs.RELATIVE_PATH: 'views.api_urls',
PluginURLs.REGEX: '',
PluginURLs.RELATIVE_PATH: 'urls',
}
},
PluginSettings.CONFIG: {

View File

@@ -19,6 +19,7 @@ from django.core import mail
from django.core.files.uploadedfile import SimpleUploadedFile
from django.http import HttpRequest, HttpResponse
from django.test import RequestFactory, TestCase
from django.test.client import MULTIPART_CONTENT
from django.urls import reverse as django_reverse
from django.utils.translation import ugettext as _
from edx_when.api import get_dates_for_course, get_overrides_for_user, set_date_for_block
@@ -140,6 +141,8 @@ REPORTS_DATA = (
INSTRUCTOR_GET_ENDPOINTS = {
'get_anon_ids',
'get_issued_certificates',
'instructor_api_v1:list_instructor_tasks',
'instructor_api_v1:list_report_downloads',
}
INSTRUCTOR_POST_ENDPOINTS = {
'add_users_to_cohorts',
@@ -177,6 +180,7 @@ INSTRUCTOR_POST_ENDPOINTS = {
'students_update_enrollment',
'update_forum_role_membership',
'override_problem_score',
'instructor_api_v1:generate_problem_responses'
}
@@ -412,13 +416,15 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
('list_forum_members', {'rolename': FORUM_ROLE_COMMUNITY_TA}),
('send_email', {'send_to': '["staff"]', 'subject': 'test', 'message': 'asdf'}),
('list_instructor_tasks', {}),
('instructor_api_v1:list_instructor_tasks', {}),
('list_background_email_tasks', {}),
('list_report_downloads', {}),
('instructor_api_v1:list_report_downloads', {}),
('calculate_grades_csv', {}),
('get_students_features', {}),
('get_students_who_may_enroll', {}),
('get_proctored_exam_results', {}),
('get_problem_responses', {}),
('instructor_api_v1:generate_problem_responses', {"problem_locations": [str(self.problem.location)]}),
('export_ora2_data', {}),
('export_ora2_submission_files', {}),
('export_ora2_summary', {}),
@@ -446,7 +452,7 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
('reset_student_attempts', {'problem_to_reset': self.problem_urlname, 'all_students': True}),
]
def _access_endpoint(self, endpoint, args, status_code, msg):
def _access_endpoint(self, endpoint, args, status_code, msg, content_type=MULTIPART_CONTENT):
"""
Asserts that accessing the given `endpoint` gets a response of `status_code`.
@@ -459,7 +465,7 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
if endpoint in INSTRUCTOR_GET_ENDPOINTS:
response = self.client.get(url, args)
else:
response = self.client.post(url, args)
response = self.client.post(url, args, content_type=content_type)
assert response.status_code == status_code, msg
def test_student_level(self):
@@ -484,7 +490,7 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
"Student should not be allowed to access endpoint " + endpoint
)
def _access_problem_responses_endpoint(self, msg):
def _access_problem_responses_endpoint(self, endpoint, msg):
"""
Access endpoint for problem responses report, ensuring that
UsageKey.from_string returns a problem key that the endpoint
@@ -496,7 +502,7 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
mock_problem_key.course_key = self.course.id
with patch.object(UsageKey, 'from_string') as patched_method:
patched_method.return_value = mock_problem_key
self._access_endpoint('get_problem_responses', {}, 200, msg)
self._access_endpoint(endpoint, {"problem_locations": ["test"]}, 200, msg, content_type="application/json")
def test_staff_level(self):
"""
@@ -516,8 +522,9 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
# TODO: make these work
if endpoint in ['update_forum_role_membership', 'list_forum_members']:
continue
elif endpoint == 'get_problem_responses':
elif endpoint in ('get_problem_responses', 'instructor_api_v1:generate_problem_responses'):
self._access_problem_responses_endpoint(
endpoint,
"Staff member should be allowed to access endpoint " + endpoint
)
continue
@@ -553,8 +560,9 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
# TODO: make these work
if endpoint in ['update_forum_role_membership']:
continue
elif endpoint == 'get_problem_responses':
elif endpoint in ('get_problem_responses', 'instructor_api_v1:generate_problem_responses'):
self._access_problem_responses_endpoint(
endpoint,
"Instructor should be allowed to access endpoint " + endpoint
)
continue
@@ -2486,18 +2494,22 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
email=student.email, course_id=self.course.id
)
def test_get_problem_responses_invalid_location(self):
@ddt.data(
('get_problem_responses', {'problem_location': ""}),
('instructor_api_v1:generate_problem_responses', {"problem_locations": ["abc"]}),
)
@ddt.unpack
def test_get_problem_responses_invalid_location(self, endpoint, post_data):
"""
Test whether get_problem_responses returns an appropriate status
message when users submit an invalid problem location.
"""
url = reverse(
'get_problem_responses',
endpoint,
kwargs={'course_id': str(self.course.id)}
)
problem_location = ''
response = self.client.post(url, {'problem_location': problem_location})
response = self.client.post(url, post_data, content_type="application/json")
res_json = json.loads(response.content.decode('utf-8'))
assert res_json == 'Could not find problem with this location.'
@@ -2521,18 +2533,22 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
return wrapper
@valid_problem_location
def test_get_problem_responses_successful(self):
@ddt.data(
('get_problem_responses', {'problem_location': "test"}),
('instructor_api_v1:generate_problem_responses', {'problem_locations': ["test"]}),
)
@ddt.unpack
def test_get_problem_responses_successful(self, endpoint, post_data):
"""
Test whether get_problem_responses returns an appropriate status
message if CSV generation was started successfully.
"""
url = reverse(
'get_problem_responses',
endpoint,
kwargs={'course_id': str(self.course.id)}
)
problem_location = ''
response = self.client.post(url, {'problem_location': problem_location})
response = self.client.post(url, post_data, content_type="application/json")
res_json = json.loads(response.content.decode('utf-8'))
assert 'status' in res_json
status = res_json['status']
@@ -2541,13 +2557,14 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
assert 'task_id' in res_json
@valid_problem_location
def test_get_problem_responses_already_running(self):
@ddt.data('get_problem_responses', 'instructor_api_v1:generate_problem_responses')
def test_get_problem_responses_already_running(self, endpoint):
"""
Test whether get_problem_responses returns an appropriate status
message if CSV generation is already in progress.
"""
url = reverse(
'get_problem_responses',
endpoint,
kwargs={'course_id': str(self.course.id)}
)
task_type = 'problem_responses_csv'
@@ -2555,7 +2572,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
with patch('lms.djangoapps.instructor_task.api.submit_calculate_problem_responses_csv') as submit_task_function:
error = AlreadyRunningError(already_running_status)
submit_task_function.side_effect = error
response = self.client.post(url, {})
response = self.client.post(url, {"problem_locations": ["test"]}, content_type="application/json")
self.assertContains(response, already_running_status, status_code=400)
@@ -2732,15 +2749,19 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
@patch('lms.djangoapps.instructor_task.models.logger.error')
@patch.dict(settings.GRADES_DOWNLOAD, {'STORAGE_TYPE': 's3', 'ROOT_PATH': 'tmp/edx-s3/grades'})
def test_list_report_downloads_error(self, mock_error):
@ddt.data('list_report_downloads', 'instructor_api_v1:list_report_downloads')
def test_list_report_downloads_error(self, endpoint, mock_error):
"""
Tests the Rate-Limit exceeded is handled and does not raise 500 error.
"""
ex_status = 503
ex_reason = 'Slow Down'
url = reverse('list_report_downloads', kwargs={'course_id': str(self.course.id)})
url = reverse(endpoint, kwargs={'course_id': str(self.course.id)})
with patch('storages.backends.s3boto.S3BotoStorage.listdir', side_effect=BotoServerError(ex_status, ex_reason)):
response = self.client.post(url, {})
if endpoint in INSTRUCTOR_GET_ENDPOINTS:
response = self.client.get(url)
else:
response = self.client.post(url, {})
mock_error.assert_called_with(
'Fetching files failed for course: %s, status: %s, reason: %s',
self.course.id,
@@ -2751,14 +2772,18 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
res_json = json.loads(response.content.decode('utf-8'))
assert res_json == {'downloads': []}
def test_list_report_downloads(self):
url = reverse('list_report_downloads', kwargs={'course_id': str(self.course.id)})
@ddt.data('list_report_downloads', 'instructor_api_v1:list_report_downloads')
def test_list_report_downloads(self, endpoint):
url = reverse(endpoint, kwargs={'course_id': str(self.course.id)})
with patch('lms.djangoapps.instructor_task.models.DjangoStorageReportStore.links_for') as mock_links_for:
mock_links_for.return_value = [
('mock_file_name_1', 'https://1.mock.url'),
('mock_file_name_2', 'https://2.mock.url'),
]
response = self.client.post(url, {})
if endpoint in INSTRUCTOR_GET_ENDPOINTS:
response = self.client.get(url)
else:
response = self.client.post(url, {})
expected_response = {
"downloads": [
@@ -3456,6 +3481,7 @@ class MockCompletionInfo:
return False, 'Task Errored In Some Way'
@ddt.ddt
class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Test instructor task list endpoint.
@@ -3535,16 +3561,20 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
self.tasks[-1].make_invalid_output()
@patch('lms.djangoapps.instructor_task.api.get_running_instructor_tasks')
def test_list_instructor_tasks_running(self, act):
@ddt.data('instructor_api_v1:list_instructor_tasks', 'list_instructor_tasks')
def test_list_instructor_tasks_running(self, endpoint, act):
""" Test list of all running tasks. """
act.return_value = self.tasks
url = reverse('list_instructor_tasks', kwargs={'course_id': str(self.course.id)})
url = reverse(endpoint, kwargs={'course_id': str(self.course.id)})
mock_factory = MockCompletionInfo()
with patch(
'lms.djangoapps.instructor.views.instructor_task_helpers.get_task_completion_info'
) as mock_completion_info:
mock_completion_info.side_effect = mock_factory.mock_get_task_completion_info
response = self.client.post(url, {})
if endpoint in INSTRUCTOR_GET_ENDPOINTS:
response = self.client.get(url)
else:
response = self.client.post(url, {})
assert response.status_code == 200
# check response
@@ -3577,18 +3607,24 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
assert actual_tasks == expected_tasks
@patch('lms.djangoapps.instructor_task.api.get_instructor_task_history')
def test_list_instructor_tasks_problem(self, act):
@ddt.data('instructor_api_v1:list_instructor_tasks', 'list_instructor_tasks')
def test_list_instructor_tasks_problem(self, endpoint, act):
""" Test list task history for problem. """
act.return_value = self.tasks
url = reverse('list_instructor_tasks', kwargs={'course_id': str(self.course.id)})
url = reverse(endpoint, kwargs={'course_id': str(self.course.id)})
mock_factory = MockCompletionInfo()
with patch(
'lms.djangoapps.instructor.views.instructor_task_helpers.get_task_completion_info'
) as mock_completion_info:
mock_completion_info.side_effect = mock_factory.mock_get_task_completion_info
response = self.client.post(url, {
'problem_location_str': self.problem_urlname,
})
if endpoint in INSTRUCTOR_GET_ENDPOINTS:
response = self.client.get(url, {
'problem_location_str': self.problem_urlname,
})
else:
response = self.client.post(url, {
'problem_location_str': self.problem_urlname,
})
assert response.status_code == 200
# check response
@@ -3600,19 +3636,26 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
assert actual_tasks == expected_tasks
@patch('lms.djangoapps.instructor_task.api.get_instructor_task_history')
def test_list_instructor_tasks_problem_student(self, act):
@ddt.data('list_instructor_tasks', 'instructor_api_v1:list_instructor_tasks')
def test_list_instructor_tasks_problem_student(self, endpoint, act):
""" Test list task history for problem AND student. """
act.return_value = self.tasks
url = reverse('list_instructor_tasks', kwargs={'course_id': str(self.course.id)})
url = reverse(endpoint, kwargs={'course_id': str(self.course.id)})
mock_factory = MockCompletionInfo()
with patch(
'lms.djangoapps.instructor.views.instructor_task_helpers.get_task_completion_info'
) as mock_completion_info:
mock_completion_info.side_effect = mock_factory.mock_get_task_completion_info
response = self.client.post(url, {
'problem_location_str': self.problem_urlname,
'unique_student_identifier': self.student.email,
})
if endpoint in INSTRUCTOR_GET_ENDPOINTS:
response = self.client.get(url, {
'problem_location_str': self.problem_urlname,
'unique_student_identifier': self.student.email,
})
else:
response = self.client.post(url, {
'problem_location_str': self.problem_urlname,
'unique_student_identifier': self.student.email,
})
assert response.status_code == 200
# check response
@@ -3663,7 +3706,7 @@ class TestInstructorEmailContentList(SharedModuleStoreTestCase, LoginEnrollmentT
return self.emails[email_id]
def get_email_content_response(self, num_emails, task_history_request, with_failures=False):
""" Calls the list_email_content endpoint and returns the repsonse """
""" Calls the list_email_content endpoint and returns the respsonse """
self.setup_fake_email_info(num_emails, with_failures)
task_history_request.return_value = list(self.tasks.values())
url = reverse('list_email_content', kwargs={'course_id': str(self.course.id)})

View File

@@ -0,0 +1,17 @@
"""
Instructor API endpoint urls.
"""
from django.conf.urls import url, include
from openedx.core.constants import COURSE_ID_PATTERN
from .views import api_urls
urlpatterns = [
url(rf'^courses/{COURSE_ID_PATTERN}/instructor/api/', include(api_urls.urlpatterns)),
url(
r'^api/instructor/v1/',
include((api_urls.v1_api_urls, 'lms.djangoapps.instructor'), namespace='instructor_api_v1'),
),
]

View File

@@ -9,10 +9,11 @@ Many of these GETs may become PUTs in the future.
import csv
import json
import logging
import string
import random
import re
import string
import edx_api_doc_tools as apidocs
from django.conf import settings
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist, PermissionDenied, ValidationError
@@ -26,17 +27,18 @@ from django.utils.html import strip_tags
from django.utils.translation import ugettext as _
from django.views.decorators.cache import cache_control
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_http_methods, require_POST
from django.views.decorators.http import require_POST, require_http_methods
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
from edx_rest_framework_extensions.auth.session.authentication import SessionAuthenticationAllowInactiveUser
from edx_when.api import get_date_for_block
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey, UsageKey
from rest_framework import status
from rest_framework import serializers, status
from rest_framework.permissions import IsAdminUser, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from submissions import api as sub_api # installed from the edx-submissions repository
from xmodule.modulestore.django import modulestore
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.student import auth
@@ -44,17 +46,17 @@ from common.djangoapps.student.api import is_user_enrolled_in_course
from common.djangoapps.student.models import (
ALLOWEDTOENROLL_TO_ENROLLED,
ALLOWEDTOENROLL_TO_UNENROLLED,
CourseEnrollment,
CourseEnrollmentAllowed,
DEFAULT_TRANSITION_STATE,
ENROLLED_TO_ENROLLED,
ENROLLED_TO_UNENROLLED,
UNENROLLED_TO_ALLOWEDTOENROLL,
UNENROLLED_TO_ENROLLED,
UNENROLLED_TO_UNENROLLED,
CourseEnrollment,
CourseEnrollmentAllowed,
EntranceExamConfiguration,
ManualEnrollmentAudit,
Registration,
UNENROLLED_TO_ALLOWEDTOENROLL,
UNENROLLED_TO_ENROLLED,
UNENROLLED_TO_UNENROLLED,
UserProfile,
get_user_by_username_or_email,
is_email_retired,
@@ -63,7 +65,7 @@ from common.djangoapps.student.roles import CourseFinanceAdminRole, CourseSalesA
from common.djangoapps.util.file import (
FileValidationException,
course_and_time_based_filename_generator,
store_uploaded_file
store_uploaded_file,
)
from common.djangoapps.util.json_request import JsonResponse, JsonResponseBadRequest
from common.djangoapps.util.views import require_global_staff
@@ -79,7 +81,7 @@ from lms.djangoapps.courseware.models import StudentModule
from lms.djangoapps.discussion.django_comment_client.utils import (
get_group_id_for_user,
get_group_name,
has_forum_access
has_forum_access,
)
from lms.djangoapps.instructor import enrollment
from lms.djangoapps.instructor.access import ROLES, allow_access, list_with_level, revoke_access, update_forum_role
@@ -89,13 +91,11 @@ from lms.djangoapps.instructor.enrollment import (
get_user_email_language,
send_beta_role_email,
send_mail_to_student,
unenroll_email
unenroll_email,
)
from lms.djangoapps.instructor.views import INVOICE_KEY
from lms.djangoapps.instructor.views.instructor_task_helpers import extract_email_features, extract_task_features
from lms.djangoapps.instructor_analytics import basic as instructor_analytics_basic
from lms.djangoapps.instructor_analytics import csvs as instructor_analytics_csvs
from lms.djangoapps.instructor_analytics import distributions as instructor_analytics_distributions # lint-amnesty, pylint: disable=unused-import
from lms.djangoapps.instructor_analytics import basic as instructor_analytics_basic, csvs as instructor_analytics_csvs
from lms.djangoapps.instructor_task import api as task_api
from lms.djangoapps.instructor_task.api_helper import AlreadyRunningError, QueueConnectionError
from lms.djangoapps.instructor_task.models import ReportStore
@@ -107,17 +107,14 @@ from openedx.core.djangoapps.django_comment_common.models import (
FORUM_ROLE_COMMUNITY_TA,
FORUM_ROLE_GROUP_MODERATOR,
FORUM_ROLE_MODERATOR,
Role
Role,
)
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference
from openedx.core.djangolib.markup import HTML, Text
from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin, view_auth_classes
from openedx.core.lib.courses import get_course_by_id
from xmodule.modulestore.django import modulestore
from .. import permissions
from .tools import (
dump_module_extensions,
dump_student_extensions,
@@ -127,8 +124,9 @@ from .tools import (
parse_datetime,
require_student_from_identifier,
set_due_date_extension,
strip_if_string
strip_if_string,
)
from .. import permissions
log = logging.getLogger(__name__)
@@ -971,12 +969,144 @@ def list_course_role_members(request, course_id):
return JsonResponse(response_payload)
class ProblemResponseReportPostParamsSerializer(serializers.Serializer): # pylint: disable=abstract-method
"""
Serializer that describes that POST parameters for the report generation API.
"""
problem_locations = serializers.ListSerializer(
child=serializers.CharField(
help_text=_(
"A usage key location for a section or a problem. "
"If the location is a block that contains other blocks, (such as the course, "
"section, subsection, or unit blocks) then all blocks under that block will be "
"included in the report."
),
),
required=True,
allow_empty=False,
help_text=_(
"A list of usage keys for the blocks to include in the report. "
)
)
problem_types_filter = serializers.ListSerializer(
child=serializers.CharField(),
required=False,
allow_empty=True,
help_text=_(
"A list of problem/block types to generate the report for. "
"This field can be omitted if the report should include details of all"
"block types. "
),
)
class ProblemResponsesReportStatusSerializer(serializers.Serializer): # pylint: disable=abstract-method
"""
Serializer that describes the response of the problem response report generation API.
"""
status = serializers.CharField(help_text=_("User-friendly text describing current status of report generation."))
task_id = serializers.UUIDField(
help_text=_(
"A unique id for the report generation task. "
"It can be used to query the latest report generation status."
)
)
@view_auth_classes()
@method_decorator(transaction.non_atomic_requests, name='dispatch')
class ProblemResponseReportInitiate(DeveloperErrorViewMixin, APIView):
"""
Initiate generation of a CSV file containing all student answers
to a given problem.
"""
@apidocs.schema(
parameters=[
apidocs.path_parameter(
'course_id',
str,
description="ID of the course for which report is to be generate.",
),
],
body=ProblemResponseReportPostParamsSerializer,
responses={
200: ProblemResponsesReportStatusSerializer,
400: _(
"The provided parameters were invalid. Make sure you've provided at least "
"one valid usage key for `problem_locations`."
),
401: _("The requesting user is not authenticated."),
403: _("The requesting user lacks access to the course."),
}
)
@transaction.non_atomic_requests
@method_decorator(require_course_permission(permissions.CAN_RESEARCH))
def post(self, request, course_id):
"""
Initiate generation of a CSV file containing all student answers
to a given problem.
**Example requests**
POST /api/instructor/v1/reports/{course_id}/generate/problem_responses {
"problem_locations": [
"{usage_key1}",
"{usage_key2}",
"{usage_key3}"
]
}
POST /api/instructor/v1/reports/{course_id}/generate/problem_responses {
"problem_locations": ["{usage_key}"],
"problem_types_filter": ["problem"]
}
**POST Parameters**
A POST request can include the following parameters:
* problem_location: A list of usage keys for the blocks to include in
the report. If the location is a block that contains other blocks,
(such as the course, section, subsection, or unit blocks) then all
blocks under that block will be included in the report.
* problem_types_filter: Optional. A comma-separated list of block types
to include in the report. If set, only blocks of the specified types
will be included in the report.
To get data on all the poll and survey blocks in a course, you could
POST the usage key of the course for `problem_location`, and
"poll, survey" as the value for `problem_types_filter`.
**Example Response:**
If initiation is successful (or generation task is already running):
```json
{
"status": "The problem responses report is being created. ...",
"task_id": "4e49522f-31d9-431a-9cff-dd2a2bf4c85a"
}
```
Responds with BadRequest if any of the provided problem locations are faulty.
"""
params = ProblemResponseReportPostParamsSerializer(data=request.data)
params.is_valid(raise_exception=True)
problem_locations = params.validated_data.get('problem_locations')
problem_types_filter = params.validated_data.get('problem_types_filter')
if problem_types_filter:
problem_types_filter = ','.join(problem_types_filter)
return _get_problem_responses(
request,
course_id=course_id,
problem_locations=problem_locations,
problem_types_filter=problem_types_filter,
)
@transaction.non_atomic_requests
@require_POST
@ensure_csrf_cookie
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
@require_course_permission(permissions.CAN_RESEARCH)
@common_exceptions_400
def get_problem_responses(request, course_id):
"""
Initiate generation of a CSV file containing all student answers
@@ -1020,24 +1150,38 @@ def get_problem_responses(request, course_id):
Responds with BadRequest if any of the provided problem locations are faulty.
"""
course_key = CourseKey.from_string(course_id)
# A comma-separated list of problem locations
# The name of the POST parameter is `problem_location` (not pluralised) in
# order to preserve backwards compatibility with existing third-party
# scripts.
problem_locations = request.POST.get('problem_location', '')
problem_locations = request.POST.get('problem_location', '').split(',')
# A comma-separated list of block types
problem_types_filter = request.POST.get('problem_types_filter', '')
problem_types_filter = request.POST.get('problem_types_filter')
return _get_problem_responses(
request,
course_id=course_id,
problem_locations=problem_locations,
problem_types_filter=problem_types_filter,
)
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
@common_exceptions_400
def _get_problem_responses(request, *, course_id, problem_locations, problem_types_filter):
"""
Shared code for new DRF and old APIS for problem response report generation.
"""
course_key = CourseKey.from_string(course_id)
report_type = _('problem responses')
try:
for problem_location in problem_locations.split(','):
problem_key = UsageKey.from_string(problem_location).map_into_course(course_key) # lint-amnesty, pylint: disable=unused-variable
for problem_location in problem_locations:
UsageKey.from_string(problem_location).map_into_course(course_key)
except InvalidKeyError:
return JsonResponseBadRequest(_("Could not find problem with this location."))
task = task_api.submit_calculate_problem_responses_csv(
request, course_key, problem_locations, problem_types_filter,
request, course_key, ','.join(problem_locations), problem_types_filter,
)
success_status = SUCCESS_MESSAGE_TEMPLATE.format(report_type=report_type)
@@ -1852,10 +1996,139 @@ def list_email_content(request, course_id):
return JsonResponse(response_payload)
class InstructorTaskSerializer(serializers.Serializer): # pylint: disable=abstract-method
"""
Serializer that describes the format of a single instructor task.
"""
status = serializers.CharField(help_text=_("Current status of task."))
task_type = serializers.CharField(help_text=_("Identifies the kind of task being performed, e.g. rescoring."))
task_id = serializers.CharField(help_text=_("The celery ID for the task."))
created = serializers.DateTimeField(help_text=_("The date and time when the task was created."))
task_input = serializers.DictField(
help_text=_(
"The input parameters for the task. The format and content of this "
"data will depend on the kind of task being performed. For instance"
"it may contain the problem locations for a problem resources task.")
)
requester = serializers.CharField(help_text=_("The username of the user who initiated this task."))
task_state = serializers.CharField(help_text=_("The last knows state of the celery task."))
duration_sec = serializers.CharField(help_text=_("Task duration information, if known"))
task_message = serializers.CharField(help_text=_("User-friendly task status information, if available."))
class InstructorTasksListSerializer(serializers.Serializer): # pylint: disable=abstract-method
"""
Serializer to describe the response of the instructor tasks list API.
"""
tasks = serializers.ListSerializer(
child=InstructorTaskSerializer(),
help_text=_("List of instructor tasks.")
)
@view_auth_classes()
class InstructorTasks(DeveloperErrorViewMixin, APIView):
"""
**Use Cases**
Lists currently running instructor tasks
**Parameters**
- With no arguments, lists running tasks.
- `problem_location_str` lists task history for problem
- `problem_location_str` and `unique_student_identifier` lists task
history for problem AND student (intersection)
**Example Requests**:
GET /courses/{course_id}/instructor/api/v0/tasks
**Response Values**
{
"tasks": [
{
"status": "Incomplete",
"task_type": "grade_problems",
"task_id": "2519ff31-22d9-4a62-91e2-55495895b355",
"created": "2019-01-15T18:00:15.902470+00:00",
"task_input": "{}",
"duration_sec": "unknown",
"task_message": "No status information available",
"requester": "staff",
"task_state": "PROGRESS"
}
]
}
"""
@apidocs.schema(
parameters=[
apidocs.string_parameter(
'course_id',
apidocs.ParameterLocation.PATH,
description="ID for the course whose tasks need to be listed.",
),
apidocs.string_parameter(
'problem_location_str',
apidocs.ParameterLocation.QUERY,
description="Filter instructor tasks to this problem location.",
),
apidocs.string_parameter(
'unique_student_identifier',
apidocs.ParameterLocation.QUERY,
description="Filter tasks to a singe problem and a single student. "
"Must be used in combination with `problem_location_str`.",
),
],
responses={
200: InstructorTasksListSerializer,
401: _("The requesting user is not authenticated."),
403: _("The requesting user lacks access to the course."),
404: _("The requested course does not exist."),
}
)
def get(self, request, course_id):
"""
List instructor tasks filtered by `course_id`.
**Use Cases**
Lists currently running instructor tasks
**Parameters**
- With no arguments, lists running tasks.
- `problem_location_str` lists task history for problem
- `problem_location_str` and `unique_student_identifier` lists task
history for problem AND student (intersection)
**Example Requests**:
GET /courses/{course_id}/instructor/api/v0/tasks
**Response Values**
```json
{
"tasks": [
{
"status": "Incomplete",
"task_type": "grade_problems",
"task_id": "2519ff31-22d9-4a62-91e2-55495895b355",
"created": "2019-01-15T18:00:15.902470+00:00",
"task_input": "{}",
"duration_sec": "unknown",
"task_message": "No status information available",
"requester": "staff",
"task_state": "PROGRESS"
}
]
}
```
"""
return _list_instructor_tasks(request=request, course_id=course_id)
@require_POST
@ensure_csrf_cookie
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
@require_course_permission(permissions.SHOW_TASKS)
def list_instructor_tasks(request, course_id):
"""
List instructor tasks.
@@ -1866,9 +2139,21 @@ def list_instructor_tasks(request, course_id):
- `problem_location_str` and `unique_student_identifier` lists task
history for problem AND student (intersection)
"""
return _list_instructor_tasks(request=request, course_id=course_id)
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
@require_course_permission(permissions.SHOW_TASKS)
def _list_instructor_tasks(request, course_id):
"""
List instructor tasks.
Internal function with common code for both DRF and and tradition views.
"""
course_id = CourseKey.from_string(course_id)
problem_location_str = strip_if_string(request.POST.get('problem_location_str', False))
student = request.POST.get('unique_student_identifier', None)
params = getattr(request, 'query_params', request.POST)
problem_location_str = strip_if_string(params.get('problem_location_str', False))
student = params.get('unique_student_identifier', None)
if student is not None:
student = get_student_from_identifier(student)
@@ -1940,10 +2225,85 @@ def list_entrance_exam_instructor_tasks(request, course_id):
return JsonResponse(response_payload)
class ReportDownloadSerializer(serializers.Serializer): # pylint: disable=abstract-method
"""
Serializer that describes a single report download.
"""
url = serializers.URLField(help_text=_("URL from which report can be downloaded."))
name = serializers.CharField(help_text=_("Name of report."))
link = serializers.CharField(help_text=_("HTML anchor tag that contains the name and link."))
class ReportDownloadsListSerializer(serializers.Serializer): # pylint: disable=abstract-method
"""
Serializer that describes the response of the report downloads list API.
"""
downloads = serializers.ListSerializer(
child=ReportDownloadSerializer(help_text="Report Download"),
help_text=_("List of report downloads"),
)
@view_auth_classes()
class ReportDownloads(DeveloperErrorViewMixin, APIView):
"""
API view to list report downloads for a course.
"""
@apidocs.schema(parameters=[
apidocs.string_parameter(
'course_id',
apidocs.ParameterLocation.PATH,
description=_("ID for the course whose reports need to be listed."),
),
apidocs.string_parameter(
'report_name',
apidocs.ParameterLocation.QUERY,
description=_(
"Filter results to only return details of for the report with the specified name."
),
),
], responses={
200: ReportDownloadsListSerializer,
401: _("The requesting user is not authenticated."),
403: _("The requesting user lacks access to the course."),
404: _("The requested course does not exist."),
})
def get(self, request, course_id):
"""
List report CSV files that are available for download for this course.
**Use Cases**
Lists reports available for download
**Example Requests**:
GET /api/instructor/v1/reports/{course_id}
**Response Values**
```json
{
"downloads": [
{
"url": "https://1.mock.url",
"link": "<a href=\"https://1.mock.url\">mock_file_name_1</a>",
"name": "mock_file_name_1"
}
]
}
```
The report name will depend on the type of report generated. For example a
problem responses report for an entire course might be called:
edX_DemoX_Demo_Course_student_state_from_block-v1_edX+DemoX+Demo_Course+type@course+block@course_2021-04-30-0918.csv
""" # pylint: disable=line-too-long
return _list_report_downloads(request=request, course_id=course_id)
@require_POST
@ensure_csrf_cookie
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
@require_course_permission(permissions.CAN_RESEARCH)
def list_report_downloads(request, course_id):
"""
List grade CSV files that are available for download for this course.
@@ -1951,9 +2311,20 @@ def list_report_downloads(request, course_id):
Takes the following query parameters:
- (optional) report_name - name of the report
"""
return _list_report_downloads(request=request, course_id=course_id)
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
@require_course_permission(permissions.CAN_RESEARCH)
def _list_report_downloads(request, course_id):
"""
List grade CSV files that are available for download for this course.
Internal function with common code shared between DRF and functional views.
"""
course_id = CourseKey.from_string(course_id)
report_store = ReportStore.from_config(config_name='GRADES_DOWNLOAD')
report_name = request.POST.get("report_name", None)
report_name = getattr(request, 'query_params', request.POST).get("report_name", None)
response_payload = {
'downloads': [

View File

@@ -2,10 +2,22 @@
Instructor API endpoint urls.
"""
from django.conf.urls import url
from lms.djangoapps.instructor.views import api, gradebook_api
from openedx.core.constants import COURSE_ID_PATTERN
# These endpoints are exposing existing views in a way that can be used by MFEs
# or other API clients. They are currently versioned at `v1` since they have
# been around without major changes for a while and will probably not be changed
# in incompatible ways. If they do need incompatible changes for use via MFEs
# then new v2 endpoints can be introduced.
v1_api_urls = [
url(rf'^tasks/{COURSE_ID_PATTERN}$', api.InstructorTasks.as_view(), name='list_instructor_tasks', ),
url(rf'^reports/{COURSE_ID_PATTERN}$', api.ReportDownloads.as_view(), name='list_report_downloads', ),
url(rf'^reports/{COURSE_ID_PATTERN}/generate/problem_responses$', api.ProblemResponseReportInitiate.as_view(),
name='generate_problem_responses', ),
]
urlpatterns = [
url(r'^students_update_enrollment$', api.students_update_enrollment, name='students_update_enrollment'),

View File

@@ -53,8 +53,8 @@ class CourseKeyField(serializers.Field):
"""Convert unicode to a course key. """
try:
return CourseKey.from_string(data)
except InvalidKeyError as ex:
raise serializers.ValidationError(f"Invalid course key: {ex.msg}") # lint-amnesty, pylint: disable=no-member
except InvalidKeyError as err:
raise serializers.ValidationError("Invalid course key") from err
class UsageKeyField(serializers.Field):
@@ -68,5 +68,5 @@ class UsageKeyField(serializers.Field):
"""Convert unicode to a usage key. """
try:
return UsageKey.from_string(data)
except InvalidKeyError as ex:
raise serializers.ValidationError(f"Invalid usage key: {ex.msg}") # lint-amnesty, pylint: disable=no-member
except InvalidKeyError as err:
raise serializers.ValidationError("Invalid course key") from err