Commit 42de3d89 by Mark Hoeber Committed by Jonathan Piacenti

API Doc

parent 2de84b51
###############################
edX ReST API Resources
###############################
**********
Courses
**********
.. list-table::
:widths: 20 60
:header-rows: 1
* - Goal
- Resource
* - :ref:`Get a List of Courses`
- GET /api/courses
* - :ref:`Get Course Content`
- GET /api/courses/{course_id}/content?type=content_type
* - :ref:`Get Course Details`
- GET /api/courses/{course_id}?depth=n
* - :ref:`Get Content Details`
- GET /api/courses/{course_id}/content/{content_id}?type=content_type
* - :ref:`Get a Course Overview`
- GET /api/courses/{course_id}/overview?parse=true
* - :ref:`Get Course Updates`
- GET /api/courses/{course_id}/updates?parse=true
* - :ref:`Get Pages`
- GET /api/courses/{course_id}/static_tabs?detail=true
* - :ref:`Get Page Detail`
- GET /api/courses/{course_id}/static_tabs/{tab_id}
* - :ref:`Get Users in a Course`
- GET /api/courses/{course_id}/users
* - :ref:`Add a User to a Course`
- POST /api/courses/{course_id}/users
* - :ref:`Get Details of a User in a Course`
- POST /api/courses/{course_id}/users/{user_id}
* - :ref:`Unenroll a User from a Course`
- DELETE /api/courses/{course_id}/users/{user_id}
**********
Sessions
**********
.. list-table::
:widths: 20 60
:header-rows: 1
* - Goal
- Resource
* -
-
\ No newline at end of file
###############################
Testing the edX ReST API
###############################
##############################
Courses API Module
##############################
.. module:: api_manager
The page contains docstrings and example responses for:
* `Get a List of Courses`_
* `Get Course Details`_
* `Get Course Content`_
* `Get Content Details`_
* `Get a Course Overview`_
* `Get Course Updates`_
* `Get Pages`_
* `Get Page Detail`_
* `Get Users in a Course`_
* `Add a User to a Course`_
* `Get Details of a User in a Course`_
* `Unenroll a User from a Course`_
.. _Get a List of Courses:
**************************
Get a List of Courses
**************************
.. autoclass:: courses.views.CoursesList
:members:
**Example response**
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
[
{
"category": "course",
"name": "Computer Science 101",
"uri": "http://edx-lms-server/api/courses/un/CS/cs101",
"number": "CS101",
"due": null,
"org": "University N",
"id": "un/CS/cs101"
}
]
.. _Get Course Details:
**************************
Get Course Details
**************************
.. autoclass:: courses.views.CoursesDetail
:members:
**Example response with no depth parameter**
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{
"category": "course",
"name": "Computer Science 101",
"uri": "http://edx-lms-server/api/courses/un/CS/cs101",
"number": "CS101",
"due": null,
"org": "University N",
"id": "un/CS/cs101"
"resources": [
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/"
},
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/groups/"
},
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/overview"
},
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/updates/"
},
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/static_tabs/"
},
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/users/"
}
]
}
**Example response with depth=2**
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{
"category": "course",
"name": "Computer Science 101",
"uri": "http://edx-lms-server/api/courses/un/CS/cs101",
"number": "CS101",
"content": [
{
"category": "chapter",
"name": "Introduction",
"due": null,
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/i4x://un/cs101/chapter/introduction",
"id": "i4x://un/cs101/chapter/introduction",
"children": [
{
"category": "sequential",
"due": null,
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/i4x://edX/Open_DemoX/sequential/cs_setup",
"id": "i4x://un/cs101/sequential/cs_setup",
"name": "Course Setup"
}
]
},
{
"category": "chapter",
"name": "Getting Started",
"due": null,
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/i4x://un/cs101/chapter/getting_started",
"id": "i4x://un/cs101/chapter/getting_started",
"children": [
{
"category": "sequential",
"due": null,
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/i4x://edX/Open_DemoX/sequential/sample_problem",
"id": "i4x://un/cs101/sequential/sample_problem",
"name": "Sample Problem"
}
]
},
"due": null,
"org": "University N",
"id": "un/CS/cs101",
"resources": [
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/"
},
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/groups/"
},
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/overview"
},
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/updates/"
},
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/static_tabs/"
},
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/users/"
}
]
}
.. _Get Course Content:
**************************
Get Course Content
**************************
.. autoclass:: courses.views.CourseContentList
:members:
**Example response**:
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
[
{
"category": "chapter",
"due": null,
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/i4x://un/cs101/chapter/introduction",
"id": "i4x://un/cs101/chapter/introduction",
"name": "Introduction"
},
{
"category": "chapter",
"due": null,
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/i4x://un/cs101/chapter/getting_started",
"id": "i4x://un/cs101/chapter/getting_started",
"name": "Getting Started"
}
]
.. _Get Content Details:
**************************
Get Content Details
**************************
.. autoclass:: courses.views.CourseContentDetail
:members:
**Example response**:
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{
"category": "chapter",
"due": null,
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/i4x://un/cs101/chapter/introduction",
"id": "i4x://un/cs101/chapter/introduction",
"name": "Introduction"
"children": [
{
"category": "sequential",
"due": null,
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/i4x://un/cs101/chapter/introduction/sequential/19a30717eff543078a5d94ae9d6c18a5",
"id": "i4x://un/cs101/chapter/introduction/sequential/19a30717eff543078a5d94ae9d6c18a5",
"name": "Lesson 1 - Getting Started"
},
{
"category": "sequential",
"due": null,
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/i4x://un/cs101/chapter/introduction/sequential/basic_questions",
"id": "i4x://un/cs101/chapter/introduction/sequential/basic_questions",
"name": "Homework - Basic Questions"
}
],
"resources": [
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/i4x://un/cs101/chapter/introduction/users"
},
{
"uri": "http://edx-lms-server/api/courses/un/CS/cs101/content/i4x://un/cs101/chapter/introduction/groups"
}
]
}
.. _Get a Course Overview:
**************************
Get a Course Overview
**************************
.. autoclass:: courses.views.CoursesOverview
:members:
**Example response with no parse parameter**:
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{ "overview_html": "\n\n<section class=\"about\">\n <h2>About This
Course</h2>\n <p>This course is about . . .</p>\n </section>\n\n
<section class=\"prerequisites\">\n <h2>Prerequisites</h2>\n
<p>Course prerequisites are: a, b, c</p>\n </section>\n\n <section class
=\"course-staff\">\n <h2>Course Staff</h2>\n <article
class=\"teacher\">\n <div class=\"teacher-image\">\n <img
src=\"/static/images/pl-faculty.png\" align=\"left\" style=\"margin:0 20
px 0\">\n </div>\n\n <h3>Staff Member #1</h3>\n <p>Biography
of . . .</p>\n </article>\n\n <article class=\"teacher\">\n <div
class=\"teacher-image\">\n <img src=\"/static/images/pl-
faculty.png\" align=\"left\" style=\"margin:0 20 px 0\">\n
</div>\n\n <h3>Staff Member #2</h3>\n <p>Biography of . .
.</p>\n </article>\n </section>\n\n <section class=\"faq\">\n
<section class=\"responses\">\n <h2>Frequently Asked
Questions</h2>\n <article class=\"response\">\n <h3>Do I need
to buy a textbook?</h3>\n <p>No</p>\n </article>\n\n
<article class=\"response\">\n <h3>Question #2</h3>\n
<p>Answer here . . .</p>\n </article>\n </section>\n
</section>\n\n\n"
}
**Example response when parse is true**:
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{
"sections": [
{
"class": "about",
"body": "<h2>About This Course</h2>\n
<p>This course is about . . .</p>\n "
},
{
"class": "prerequisites",
"body": "<h2>Prerequisites</h2>\n
<p>Course prerequisites are: a, b, c</p>\n "
},
{
"class": "course-staff",
"articles": [
{
"class": "teacher",
"name": "Staff Member #1",
"image_src": "/static/images/pl-faculty.png",
"bio": "<p>Biography of . . .</p>\n "
},
{
"class": "teacher",
"name": "Staff Member #2",
"image_src": "/static/images/pl-faculty.png",
"bio": "<p>Biography of . . .</p>\n "
}
]
},
{
"class": "faq",
"body": "<section class=\"responses\">
<h2>Frequently Asked Questions</h2>\n
<article class=\"response\">
<h3>Do I need to buy a textbook?</h3>\n
<p>No</p>\n
</article>
<article class=\"response\"><h3>Question #2</h3>\n
<p>Answer here . . .</p>\n
</article>
</section>"
}
]
}
.. _Get Course Updates:
**************************
Get Course Updates
**************************
.. autoclass:: courses.views.CoursesUpdates
:members:
**Example response with no parse parameter**:
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{ "content": "\n\n<ol><li><h2>Welcome!</h2>Hi! Welcome to the edX
demonstration course. We built this to help you become more familiar with
taking a course on edX prior to your first day of class. \n<br><br>\nIn a
live course, this section is where all of the latest course announcements
and updates would be. To get started with this demo course, view the <a href
=\"/courses/edX/Open_DemoX/edx_demo_course/courseware/d8a6192ade314473a78242
dfeedfbf5b/edx_introduction/\">courseware page</a> and click &#8220;Example
Week 1&#8221; in the left hand navigation. \n<br><br>\nWe tried to make
this both fun and informative. We hope you like it. &#8211; The edX Team\n<br><br></li></ol>\n\n\n" }
**Example response when parse is true**:
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{
"postings": [
{
"date": "Welcome!",
"content": "Hi! Welcome to the edX demonstration course. We
built this to help you become more familiar with taking a course
on edX prior to your first day of class. \n<br/><br/>\nIn a live
course, this section is where all of the latest course
announcements and updates would be. To get started with this
demo course, view the <a href=\"/courses/edX/Open_DemoX/edx_demo
_course/courseware/d8a6192ade314473a78242dfeedfbf5b/edx_introduc
tion/\">courseware page</a> and click &#8220;Example Week
1&#8221; in the left hand navigation. \n<br/><br/>\nWe tried to
make this both fun and informative. We hope you like it.
&#8211; The edX Team \n<br/><br/>" } }
.. _Get Pages:
**************************
Get Pages
**************************
.. autoclass:: courses.views.CoursesStaticTabsList
:members:
**Example response**:
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{
"tabs":
[
{
"id": "53c13f21a99b4dd3b58a4cfa73b91b6f",
"name": "Syllabus"
}
{
"id": "63f54g25a55b4nd3c5224csa73b91c7j",
"name": "Calendar"
}
]
}
If ``detail=true``, the response contains the ``content`` key, with the HTML content of the page as the value.
.. _Get Page Detail:
**************************
Get Page Detail
**************************
.. autoclass:: courses.views.CoursesStaticTabsDetail
:members:
**Example response**:
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{
"tabs":
[
{
"id": "53c13f21a99b4dd3b58a4cfa73b91b6f",
"name": "Syllabus"
"content": <p>The HTML syllabus content.</p>
}
{
"id": "63f54g25a55b4nd3c5224csa73b91c7j",
"name": "Calendar"
"content": <p>The HTML calednar content.</p>
}
]
}
.. _Get Users in a Course:
**************************
Get Users in a Course
**************************
.. autoclass:: courses.views.CoursesUsersList
:members:
**Example response**:
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{
{
"uri": "http://localhost:8000/api/courses/edX/Open_DemoX/edx_demo_course/users/",
"enrollments":
[
{
"id": 1,
"email": "honor@example.com",
"username": "honor"
},
{
"id": 2,
"email": "audit@example.com",
"username": "audit"
}
]
}
}
.. _Add a User to a Course:
**************************
Add a User to a Course
**************************
.. autoclass:: courses.views.CoursesUsersList
:members:
**Example Post Content**:
.. code-block:: json
{
"user_id" : 12345
}
Or:
.. code-block:: json
{
"email" : "newstudent@edx.org"
}
.. _Get Details of a User in a Course:
**********************************
Get Details of a User in a Course
**********************************
.. autoclass:: courses.views.CoursesUsersDetail
:members:
**Example response**:
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{
"course_id": "UniversityX/1/1",
"position": 1,
"user_id": "4",
"uri": "http://edx-lms-server/api/courses/UniversityX/1/1/users/4"
}
.. _Unenroll a User from a Course:
**********************************
Unenroll a User from a Course
**********************************
.. autoclass:: courses.views.CoursesUsersDetail
:members:
\ No newline at end of file
###############################
Gruops API Module
###############################
.. module:: api_manager
The page contains docstrings for:
* `Groups Views`_
* `Groups Tests`_
**************
Groups Views
**************
.. automodule:: groups.views
:members:
:show-inheritance:
**************
Groups Tests
**************
.. automodule:: groups.tests
:members:
:show-inheritance:
\ No newline at end of file
.. _API:
###############################
edX Platform ReST API
###############################
This section contains information on edX Platform ReST API.
View the following chapters to understand the ReST API, how to test it, and the
available endpoints.
.. toctree::
:maxdepth: 2
api_overview
api_testing
courses
groups
sessions
system
users
###############################
Sessions API Module
###############################
.. module:: api_manager
The page contains docstrings for:
*
\ No newline at end of file
###############################
System API Module
###############################
.. module:: api_manager
The page contains docstrings for:
* `System Views`_
* `System Tests`_
**************
System Views
**************
.. automodule:: system.views
:members:
:show-inheritance:
**************
System Tests
**************
.. automodule:: system.tests
:members:
:show-inheritance:
\ No newline at end of file
###############################
Users API Module
###############################
.. module:: api_manager
The page contains docstrings for:
* `Users Views`_
* `Users Tests`_
**************
Users Views
**************
.. automodule:: users.views
:members:
:show-inheritance:
**************
Users Tests
**************
.. automodule:: users.tests
:members:
:show-inheritance:
\ No newline at end of file
###############################
ReST API for Courses
###############################
The edX ReST API for courses enables you to:
* `Get a List of Courses`_
* `Get Course Details`_
.. _Get a List of Courses:
**********************
Get a List of Courses
**********************
.. http:get:: /api/courses
Retrieves a list of courses in the edX Platform as a JSON representation (array) of the set of Course entities.
**Example request**:
.. sourcecode:: http
GET /api/courses
**Example response**:
.. sourcecode:: http
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
[
{
"category": "course",
"name": "edX Demonstration Course",
"uri": "http://localhost:8000/api/courses/edX/Open_DemoX/edx_demo_course",
"number": "Open_DemoX",
"due": null,
"org": "edX",
"id": "edX/Open_DemoX/edx_demo_course"
}
{
"category": "course",
"name": "Introduction to Computer Science",
"uri": "http://localhost:8000/api/courses/University/101/1_2014",
"number": "101",
"due": null,
"org": "edX University",
"id": "University/101/1_2014"
}
]
.. _Get Course Details:
**********************
Get Course Details
**********************
.. http:get:: /api/courses/{course ID}
Retrieves a list of courses in the edX Platform as a JSON representation (array) of the set of Course entities.
**Example request**:
.. sourcecode:: http
GET /api/courses
**Example response**:
.. sourcecode:: http
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
[
{
"category": "course",
"name": "edX Demonstration Course",
"uri": "http://localhost:8000/api/courses/edX/Open_DemoX/edx_demo_course",
"number": "Open_DemoX",
"due": null,
"org": "edX",
"id": "edX/Open_DemoX/edx_demo_course"
}
{
"category": "course",
"name": "Introduction to Computer Science",
"uri": "http://localhost:8000/api/courses/University/101/1_2014",
"number": "101",
"due": null,
"org": "edX University",
"id": "University/101/1_2014"
}
]
\ No newline at end of file
###############################
ReST API for Groups
###############################
.. _ReST API:
###############################
ReST API
###############################
The edX ReST API is enabled by the :ref:`API Manager` module
.. toctree::
:maxdepth: 2
api_commands
testing_api
courses
groups
sessions
system
users
###############################
ReST API for Sessions
###############################
\ No newline at end of file
###############################
ReST API for System
###############################
\ No newline at end of file
###############################
ReST API for Users
###############################
\ No newline at end of file
...@@ -222,6 +222,11 @@ sys.path.append(root / "common/lib/xmodule") ...@@ -222,6 +222,11 @@ sys.path.append(root / "common/lib/xmodule")
sys.path.append(root / "common/djangoapps") sys.path.append(root / "common/djangoapps")
sys.path.append(root / "lms/djangoapps") sys.path.append(root / "lms/djangoapps")
sys.path.append(root / "openedx/core/djangoapps") sys.path.append(root / "openedx/core/djangoapps")
sys.path.append(root / "lms/djangoapps/mobile_api")
sys.path.append(root / "lms/djangoapps/mobile_api/course_info")
sys.path.append(root / "lms/djangoapps/mobile_api/users")
sys.path.append(root / "lms/djangoapps/mobile_api/video_outlines")
sys.path.append(root / "lms/djangoapps/api_manager")
sys.path.insert( sys.path.insert(
0, 0,
......
...@@ -259,23 +259,48 @@ def _parse_updates_html(html): ...@@ -259,23 +259,48 @@ def _parse_updates_html(html):
class CourseContentList(SecureAPIView): class CourseContentList(SecureAPIView):
""" """
### The CourseContentList view allows clients to retrieve the list of children for a given CourseContent entity **Use Case**
- URI: ```/api/courses/{course_id}/content/```
- URI: ```/api/courses/{course_id}/content/{content_id}/children``` CourseContentList gets a collection of content for a given
- GET: Returns a JSON representation (array) of the set of CourseContent entities course. You can use the **uri** value in
* type: Set filtering parameter the response to get details for that content entity.
### Use Cases/Notes:
* Handling two very-different looking URIs with this one method seems odd, but we don't know where in the CourseContentList has an optional type parameter that allows you to
CourseContent hierarchy we are -- we could even be at the top (ie, the Course entity itself) filter the response by content type. The value of the type parameter
* The 'type' parameter filters content children by their 'category' field ('chapter', 'video', etc.) matches the category value in the response. Valid values for the type
* Note that the type/child filter currently does not traverse deeper than the immediate child level parameter are:
"""
* chapter
* sequential
* vertical
* html
* problem
* discussion
* video
* [CONFIRM]
**Example requests**:
def get(self, request, course_id, content_id=None):
"""
GET /api/courses/{course_id}/content GET /api/courses/{course_id}/content
GET /api/courses/{course_id}/content?type=video
GET /api/courses/{course_id}/content/{content_id}/children GET /api/courses/{course_id}/content/{content_id}/children
"""
**Response Values**
* category: The type of content.
* due: The due date.
* uri: The URI to use to get details of the content entity.
* id: The unique identifier for the content entity.
* name: The name of the course.
"""
def get(self, request, course_id, content_id=None):
if content_id is None: if content_id is None:
content_id = course_id content_id = course_id
response_data = [] response_data = []
...@@ -303,24 +328,52 @@ class CourseContentList(SecureAPIView): ...@@ -303,24 +328,52 @@ class CourseContentList(SecureAPIView):
class CourseContentDetail(SecureAPIView): class CourseContentDetail(SecureAPIView):
""" """
### The CourseContentDetail view allows clients to interact with a specific CourseContent entity **Use Case**
- URI: ```/api/courses/{course_id}/content/{content_id}```
- GET: Returns a JSON representation of the specified CourseContent entity CourseContentDetail returns a JSON collection for a specified
* type: Set filtering parameter CourseContent entity. If the specified CourseContent is the Course, the
### Use Cases/Notes: course representation is returned. You can use the uri values in the
* If the specified CourseContent is actually the Course, then we return a Course representation children collection in the JSON response to get details for that content
* The Course representation includes a top-level CourseContent element named 'content' entity.
* CourseContent representations include child CourseContent elements as 'children'
* Including 'type' will filter the set of children to those having a category matching 'type' (eg, 'video') CourseContentDetail has an optional type parameter that allows you to
* A GET response will additionally include a list of URIs to available sub-resources: filter the response by content type. The value of the type parameter
** Related Users /api/courses/{course_id}/content/{content_id}/users matches the category value in the response. Valid values for the type
** Related Groups /api/courses/{course_id}/content/{content_id}/groups parameter are:
* chapter
* sequential
* vertical
* html
* problem
* discussion
* video
* [CONFIRM]
**Example Request**
GET /api/courses/{course_id}/content/{content_id}
**Response Values**
* category: The type of content.
* name: The name of the content entity.
* due: The due date.
* uri: The URI of the content entity.
* id: The unique identifier for the course.
* children: Content entities that this conent entity contains.
* resources: A list of URIs to available users and groups:
* Related Users /api/courses/{course_id}/content/{content_id}/users
* Related Groups /api/courses/{course_id}/content/{content_id}/groups
""" """
def get(self, request, course_id, content_id): def get(self, request, course_id, content_id):
"""
GET /api/courses/{course_id}/content/{content_id}?type=video
"""
store = modulestore() store = modulestore()
response_data = {} response_data = {}
base_uri = generate_base_uri(request) base_uri = generate_base_uri(request)
...@@ -369,17 +422,33 @@ class CourseContentDetail(SecureAPIView): ...@@ -369,17 +422,33 @@ class CourseContentDetail(SecureAPIView):
class CoursesList(SecureAPIView): class CoursesList(SecureAPIView):
""" """
### The CoursesList view allows clients to retrieve the list of courses available in Open edX **Use Case**
- URI: ```/api/courses/```
- GET: Returns a JSON representation (array) of the set of Course entities CoursesList returns a collection of courses in the edX Platform. You can
### Use Cases/Notes: use the uri value in the response to get details of the course.
* CoursesList currently returns *all* courses in the Open edX database
**Example Request**
GET /api/courses
**Response Values**
* category: The type of content. In this case, the value is always "course".
* name: The name of the course.
* uri: The URI to use to get details of the course.
* number: The course number.
* due: The due date. For courses, the value is always null.
* org: The organization specified for the course.
* id: The unique identifier for the course.
""" """
def get(self, request): def get(self, request):
"""
GET /api/courses
"""
response_data = [] response_data = []
store = modulestore() store = modulestore()
course_descriptors = store.get_courses() course_descriptors = store.get_courses()
...@@ -395,25 +464,52 @@ class CoursesList(SecureAPIView): ...@@ -395,25 +464,52 @@ class CoursesList(SecureAPIView):
class CoursesDetail(SecureAPIView): class CoursesDetail(SecureAPIView):
""" """
### The CoursesDetail view allows clients to interact with a specific Course entity **Use Case**
- URI: ```/api/courses/{course_id}```
- GET: Returns a JSON representation of the specified Course entity CoursesDetail returns details for a course. You can use the uri values
* depth: Tree prefetching/scoping parameter in the resources collection in the response to get more course
### Use Cases/Notes: information for:
* Direct access to course information, irrespective of request/user context
* If 'depth' is provided, the response will include children to the specified tree level * Users (/api/courses/{course_id}/users/)
* A GET response will additionally include a list of URIs to available sub-resources: * Groups (/api/courses/{course_id}/groups/)
** Related Users /api/courses/{course_id}/users/ * Course Overview (/api/courses/{course_id}/overview/)
** Related Groups /api/courses/{course_id}/groups/ * Course Updates (/api/courses/{course_id}/updates/)
** Course Overview /api/courses/{course_id}/overview/ * Course Pages (/api/courses/{course_id}/static_tabs/)
** Course Updates /api/courses/{course_id}/updates/
** Static Tabs List /api/courses/{course_id}/static_tabs/ CoursesDetail has an optional **depth** parameter that allows you to
get course content children to the specified tree level.
**Example requests**:
GET /api/courses/{course_id}
GET /api/courses/{course_id}?depth=2
**Response Values**
* category: The type of content.
* name: The name of the course.
* uri: The URI to use to get details of the course.
* number: The course number.
* content: When the depth parameter is used, a collection of child
course content entities, such as chapters, sequentials, and
components.
* due: The due date. For courses, the value is always null.
* org: The organization specified for the course.
* id: The unique identifier for the course.
* resources: A collection of URIs to use to get more information about
the course.
""" """
def get(self, request, course_id): def get(self, request, course_id):
"""
GET /api/courses/{course_id}?depth=3
"""
depth = request.QUERY_PARAMS.get('depth', 0) depth = request.QUERY_PARAMS.get('depth', 0)
depth_int = int(depth) depth_int = int(depth)
# get_course_by_id raises an Http404 if the requested course is invalid # get_course_by_id raises an Http404 if the requested course is invalid
...@@ -460,6 +556,25 @@ class CoursesDetail(SecureAPIView): ...@@ -460,6 +556,25 @@ class CoursesDetail(SecureAPIView):
class CoursesGroupsList(SecureAPIView): class CoursesGroupsList(SecureAPIView):
""" """
**Use Case**
CoursesGroupsList returns a collection of course group relationship
entities(?) for a specified course entity.
CoursesGroupsList has an optional **type** parameter that allows you to
filter the groups returned. Valid values for the type parameter are:
* [CONFIRM]
**Example Request**
GET /api/courses/{course_id}/groups?type=workgroup
POST /api/courses/{course_id}/groups
**Response Values**
### The CoursesGroupsList view allows clients to retrieve a list of Groups for a given Course entity ### The CoursesGroupsList view allows clients to retrieve a list of Groups for a given Course entity
- URI: ```/api/courses/{course_id}/groups/``` - URI: ```/api/courses/{course_id}/groups/```
- GET: Returns a JSON representation (array) of the set of CourseGroupRelationship entities - GET: Returns a JSON representation (array) of the set of CourseGroupRelationship entities
...@@ -582,20 +697,30 @@ class CoursesGroupsDetail(SecureAPIView): ...@@ -582,20 +697,30 @@ class CoursesGroupsDetail(SecureAPIView):
class CoursesOverview(SecureAPIView): class CoursesOverview(SecureAPIView):
""" """
### The CoursesOverview view allows clients to interact with a specific piece of Course content **Use Case**
- URI: ```/api/courses/{course_id}/overview```
- GET: Returns a JSON representation of the specified CourseContent entity CoursesOverview returns an HTML representation of the overview for the
* parse: Set filtering parameter specified course. CoursesOverview has an optional parse parameter that
### Use Cases/Notes: when true breaks the response into a collection named sections. By
* Use this operation to obtain the 'overview' content for a course default, parse is false.
* If 'parse' is provided (and true), the system will attempt to break the content into "sections"
* If 'parse' is not provided (or is false), the system will return the content in its current HTML format **Example Request**
GET /api/courses/{course_id}/overview
GET /api/courses/{course_id}/overview?parse=true
**Response Values**
* overview_html: The HTML representation of the course overview.
Sections of the overview are indicated by an HTML section element.
* sections: When parse=true, a collection of JSON objects representing
parts of the course overview.
""" """
def get(self, request, course_id): def get(self, request, course_id):
"""
GET /api/courses/{course_id}/overview
"""
response_data = OrderedDict() response_data = OrderedDict()
try: try:
existing_course = get_course(course_id) existing_course = get_course(course_id)
...@@ -617,20 +742,30 @@ class CoursesOverview(SecureAPIView): ...@@ -617,20 +742,30 @@ class CoursesOverview(SecureAPIView):
class CoursesUpdates(SecureAPIView): class CoursesUpdates(SecureAPIView):
""" """
### The CoursesUpdates view allows clients to interact with a specific piece of Course content **Use Case**
- URI: ```/api/courses/{course_id}/updates```
- GET: Returns a JSON representation of the specified CourseContent entity CoursesUpdates returns an HTML representation of the overview for the
* parse: Set filtering parameter specified course. CoursesUpdates has an optional parse parameter that
### Use Cases/Notes: when true breaks the response into a collection named postings. By
* Use this operation to obtain the 'updates' content for a course default, parse is false.
* If 'parse' is provided (and true), the system will attempt to break the content into "postings"
* If 'parse' is not provided (or is false), the system will return the content in its current HTML format **Example Requests**
GET /api/courses/{course_id}/updates
GET /api/courses/{course_id}/updates?parse=true
**Response Values**
* content: The HTML representation of the course overview.
Sections of the overview are indicated by an HTML section element.
* postings: When parse=true, a collection of JSON objects representing
parts of the course overview. Each element in postings contains a date
and content key.
""" """
def get(self, request, course_id): def get(self, request, course_id):
"""
GET /api/courses/{course_id}/updates
"""
response_data = OrderedDict() response_data = OrderedDict()
try: try:
existing_course = get_course(course_id) existing_course = get_course(course_id)
...@@ -650,20 +785,31 @@ class CoursesUpdates(SecureAPIView): ...@@ -650,20 +785,31 @@ class CoursesUpdates(SecureAPIView):
class CoursesStaticTabsList(SecureAPIView): class CoursesStaticTabsList(SecureAPIView):
""" """
### The CoursesStaticTabsList view allows clients to interact with a specific piece of CourseContent **Use Case**
- URI: ```/api/courses/{course_id}/static_tabs```
- GET: Returns a JSON representation of the specified CourseContent entity CoursesStaticTabsList returns a collection of custom pages in the
* detail: boolean, Content prefetching switch course. CoursesStaticTabsList has an optional detail parameter that when
### Use Cases/Notes: true includes the custom page content in the response.
* Use this operation to obtain the 'static tabs' content for a course
* Static tabs are a core part of the information architecture for the current LMS user interface **Example Requests**
* If 'detail' is provided (and true), the system will additionally load the content for each tab
GET /api/courses/{course_id}/static_tabs
GET /api/courses/{course_id}/static_tabs?detail=true
**Response Values**
* tabs: The collection of custom pages in the course. Each object in the
collection conains the following keys:
* id: The ID of the custom page.
* name: The Display Name of the custom page.
* detail: When detail=true, the content of the custom page as HTML.
""" """
def get(self, request, course_id): def get(self, request, course_id):
"""
GET /api/courses/{course_id}/static_tabs
"""
try: try:
existing_course = get_course(course_id) existing_course = get_course(course_id)
except ValueError: except ValueError:
...@@ -691,18 +837,28 @@ class CoursesStaticTabsList(SecureAPIView): ...@@ -691,18 +837,28 @@ class CoursesStaticTabsList(SecureAPIView):
class CoursesStaticTabsDetail(SecureAPIView): class CoursesStaticTabsDetail(SecureAPIView):
""" """
### The CoursesStaticTabsDetail view allows clients to interact with a specific Static Tab content entity **Use Case**
- URI: ```/api/courses/{course_id}/static_tabs/{tab_id}```
- GET: Returns a JSON representation of the specified Static Tab content entity CoursesStaticTabsDetail returns a collection of custom pages in the
### Use Cases/Notes: course, including the page content.
* For more on static tabs, see CoursesStaticTabsList
* The 'tab_id' is not the typical content id -- instead it is the tab's url_slug value **Example Requests**
GET /api/courses/{course_id}/static_tabs/{tab_id}
**Response Values**
* tabs: The collection of custom pages in the course. Each object in the
collection conains the following keys:
* id: The ID of the custom page.
* name: The Display Name of the custom page.
* detail: The content of the custom page as HTML.
""" """
def get(self, request, course_id, tab_id): def get(self, request, course_id, tab_id):
"""
GET /api/courses/{course_id}/static_tabs/{tab_id}
"""
try: try:
existing_course = get_course(course_id) existing_course = get_course(course_id)
except ValueError: except ValueError:
...@@ -725,28 +881,37 @@ class CoursesStaticTabsDetail(SecureAPIView): ...@@ -725,28 +881,37 @@ class CoursesStaticTabsDetail(SecureAPIView):
class CoursesUsersList(SecureAPIView): class CoursesUsersList(SecureAPIView):
""" """
### The CoursesUsersList view allows clients to retrieve a list of Users enrolled in the specified Course **Use Case**
- URI: ```/api/courses/{course_id}/users/```
- GET: Returns a JSON representation (array) of the set of enrolled Users, including pre-enrolled users
- POST: Creates a new CourseUserRelationship entity using the provided Course and User
* user_id: The identifier for the User being enrolled
* email: An alternative identifier for the User being enrolled
- POST Example:
{ CoursesUsersList returns a collection of users enrolled or pre-enrolled
"user_id" : 12345 in the course.
(or)
"email" : "newstudent@edx.org" You also use CoursesUsersList to enroll a new user in the course.
}
### Use Cases/Notes: **Example Requests**
* Example: Enroll a User in a Course simply by POSTing the User's identifier to this URI
* Alternatively, provide an email address which will effectively pre-enroll a user in the Course GET /api/courses/{course_id}/users
POST /api/courses/{course_id}/users
**GET Response Values**
* enrollments: The collection of users in the course. Each object in the
collection conains the following keys:
* id: The ID of the user.
* email: The email address of the user.
* username: The username of the user.
**Post Values**
To create a new user through POST /api/courses/{course_id}/users, you
must include either a user_id or email key in the JSON object.
""" """
def post(self, request, course_id): def post(self, request, course_id):
"""
POST /api/courses/{course_id}/users
"""
response_data = OrderedDict() response_data = OrderedDict()
try: try:
existing_course = get_course(course_id) existing_course = get_course(course_id)
...@@ -782,9 +947,6 @@ class CoursesUsersList(SecureAPIView): ...@@ -782,9 +947,6 @@ class CoursesUsersList(SecureAPIView):
return Response({}, status=status.HTTP_400_BAD_REQUEST) return Response({}, status=status.HTTP_400_BAD_REQUEST)
def get(self, request, course_id): def get(self, request, course_id):
"""
GET /api/courses/{course_id/users}
"""
response_data = OrderedDict() response_data = OrderedDict()
base_uri = generate_base_uri(request) base_uri = generate_base_uri(request)
response_data['uri'] = base_uri response_data['uri'] = base_uri
...@@ -817,15 +979,27 @@ class CoursesUsersList(SecureAPIView): ...@@ -817,15 +979,27 @@ class CoursesUsersList(SecureAPIView):
class CoursesUsersDetail(SecureAPIView): class CoursesUsersDetail(SecureAPIView):
""" """
### The CoursesUsersDetail view allows clients to interact with a specific Course enrollment **Use Case**
- URI: ```/api/courses/{course_id}/users/{user_id}```
- GET: Returns a JSON representation of the specified Course enrollment CoursesUsersDetail returns a details about a specified user of a course.
* type: Set filtering parameter
- DELETE: Inactivates an existing Course enrollment You also use CoursesUsersDetail to unenroll a user from the course.
### Use Cases/Notes:
* Use the GET operation to confirm an ACTIVE enrollment of a User in a Course **Example Requests**
* If the User is enrolled in the course, we provide their last-known position to the client
* Use the DELETE operation to unenroll a User from a Course GET /api/courses/{course_id}/users/{user_id}
DELETE /api/courses/{course_id}/users/{user_id}
**GET Response Values**
* course_id: The ID of the course the user is enrolled in.
* position: The last known position in the course. (??? in outline?)
* user_id: The ID of the user.
* uri: The URI to use to get details of the user.
""" """
def get(self, request, course_id, user_id): def get(self, request, course_id, user_id):
""" """
...@@ -862,9 +1036,6 @@ class CoursesUsersDetail(SecureAPIView): ...@@ -862,9 +1036,6 @@ class CoursesUsersDetail(SecureAPIView):
return Response(response_data, status=response_status) return Response(response_data, status=response_status)
def delete(self, request, course_id, user_id): def delete(self, request, course_id, user_id):
"""
DELETE /api/courses/{course_id}/users/{user_id}
"""
try: try:
existing_course = get_course(course_id) existing_course = get_course(course_id)
except ValueError: except ValueError:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment