Commit 1d738527 by Mark Hoeber

Platform/Mobile API doc updates

parent e9759dc2
############
Change Log
############
*****************
January, 2015
*****************
.. list-table::
:widths: 10 70
:header-rows: 1
* - Date
- Change
* - 29 January 2015
- Added the :ref:`Get or Change User Status in a Course` section.
......@@ -7,6 +7,17 @@
import os
from path import path
import sys
import mock
MOCK_MODULES = ['lxml', 'requests', 'xblock', 'fields', 'xblock.fields',
'frament', 'xblock.fragment', 'webob', 'multidict', 'webob.multidict', 'core',
'xblock.core', 'runtime', 'xblock.runtime', 'sortedcontainers', 'contracts',
'plugin', 'xblock.plugin', 'opaque_keys.edx.asides', 'asides',
'dogstats_wrapper', 'fs', 'fs.errors', 'edxmako', 'edxmako.shortcuts',
'shortcuts', 'crum', 'opaque_keys.edx.locator', 'LibraryLocator', 'Location']
for mod_name in MOCK_MODULES:
sys.modules[mod_name] = mock.Mock()
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
......@@ -35,6 +46,8 @@ if not on_rtd: # only import and set the theme if we're building docs locally
# documentation root, use os.path.abspath to make it absolute, like shown here.
root = path('../../../..').abspath()
sys.path.insert(0, root)
sys.path.append(root / "common/lib/xmodule")
sys.path.append(root / "lms/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")
......@@ -54,7 +67,7 @@ sys.path.append('.')
if on_rtd:
os.environ['DJANGO_SETTINGS_MODULE'] = 'lms'
else:
os.environ['DJANGO_SETTINGS_MODULE'] = 'lms.envs.test'
os.environ['DJANGO_SETTINGS_MODULE'] = 'lms'
# -- General configuration -----------------------------------------------------
......@@ -66,164 +79,9 @@ extensions = [
'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath',
'sphinx.ext.mathjax', 'sphinx.ext.viewcode', 'sphinxcontrib.napoleon']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['build']
# Output file base name for HTML help builder.
htmlhelp_basename = 'edXDocs'
project = u'edX Platform API Version 0.5 Alpha'
copyright = u'2014, edX'
# --- Mock modules ------------------------------------------------------------
# Mock all the modules that the readthedocs build can't import
class Mock(object):
def __init__(self, *args, **kwargs):
pass
def __call__(self, *args, **kwargs):
return Mock()
@classmethod
def __getattr__(cls, name):
if name in ('__file__', '__path__'):
return '/dev/null'
elif name[0] == name[0].upper():
mockType = type(name, (), {})
mockType.__module__ = __name__
return mockType
else:
return Mock()
# The list of modules and submodules that we know give RTD trouble.
# Make sure you've tried including the relevant package in
# docs/share/requirements.txt before adding to this list.
MOCK_MODULES = [
'bson',
'bson.errors',
'bson.objectid',
'dateutil',
'dateutil.parser',
'fs',
'fs.errors',
'fs.osfs',
'lazy',
'mako',
'mako.template',
'matplotlib',
'matplotlib.pyplot',
'mock',
'numpy',
'oauthlib',
'oauthlib.oauth1',
'oauthlib.oauth1.rfc5849',
'PIL',
'pymongo',
'pyparsing',
'pysrt',
'requests',
'scipy.interpolate',
'scipy.constants',
'scipy.optimize',
'yaml',
'webob',
'webob.multidict',
]
if on_rtd:
for mod_name in MOCK_MODULES:
sys.modules[mod_name] = Mock()
# -----------------------------------------------------------------------------
# from http://djangosnippets.org/snippets/2533/
# autogenerate models definitions
import inspect
import types
from HTMLParser import HTMLParser
def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
"""
Similar to smart_unicode, except that lazy instances are resolved to
strings, rather than kept as lazy objects.
If strings_only is True, don't convert (some) non-string-like objects.
"""
if strings_only and isinstance(s, (types.NoneType, int)):
return s
if not isinstance(s, basestring,):
if hasattr(s, '__unicode__'):
s = unicode(s)
else:
s = unicode(str(s), encoding, errors)
elif not isinstance(s, unicode):
s = unicode(s, encoding, errors)
return s
class MLStripper(HTMLParser):
def __init__(self):
self.reset()
self.fed = []
def handle_data(self, d):
self.fed.append(d)
def get_data(self):
return ''.join(self.fed)
def strip_tags(html):
s = MLStripper()
s.feed(html)
return s.get_data()
def process_docstring(app, what, name, obj, options, lines):
"""Autodoc django models"""
# This causes import errors if left outside the function
from django.db import models
# If you want extract docs from django forms:
# from django import forms
# from django.forms.models import BaseInlineFormSet
# Only look at objects that inherit from Django's base MODEL class
if inspect.isclass(obj) and issubclass(obj, models.Model):
# Grab the field list from the meta class
fields = obj._meta._fields()
for field in fields:
# Decode and strip any html out of the field's help text
help_text = strip_tags(force_unicode(field.help_text))
# Decode and capitalize the verbose name, for use if there isn't
# any help text
verbose_name = force_unicode(field.verbose_name).capitalize()
if help_text:
# Add the model field to the end of the docstring as a param
# using the help text as the description
lines.append(u':param %s: %s' % (field.attname, help_text))
else:
# Add the model field to the end of the docstring as a param
# using the verbose name as the description
lines.append(u':param %s: %s' % (field.attname, verbose_name))
copyright = u'2015, edX'
# Add the field's type to the docstring
lines.append(u':type %s: %s' % (field.attname, type(field).__name__))
return lines
exclude_patterns = ['build', 'links.rst']
def setup(app):
"""Setup docsting processors"""
#Register the docstring processor with sphinx
app.connect('autodoc-process-docstring', process_docstring)
......@@ -171,4 +171,4 @@ Get the HTML for the course about page.
</article>\n
</section>\n
</section>"
}
}
\ No newline at end of file
......@@ -19,6 +19,8 @@ The following tasks and endpoints are currently supported.
- /api/mobile/v0.5/users/{username}
* - :ref:`Get course enrollments for about a user<Get a User's Course Enrollments>`
- /api/mobile/v0.5/users/{username}/course_enrollments/
* - :ref:`Get or change user status in a course<Get or Change User Status in a Course>`
- /api/mobile/v0.5/users/{username}/course_status_info/{course_id}
* - :ref:`Get a course About page<Get the Course About Page>`
- /api/mobile/v0.5/course_info/{organization}/{course_number}/{course_run}/about
* - :ref:`Get updates for a course<Get Course Updates>`
......
......@@ -35,6 +35,9 @@ With the edX Platform API, you can:
* Get :ref:`user details<Get User Details>` and :ref:`course enrollments<Get a
User's Course Enrollments>` for a user.
* :ref:`Get or change user status in a course <Get or Change User Status in a
Course>`
* Get :ref:`course information<Get the Course About Page>`, :ref:`updates<Get
Course Updates>`, and :ref:`handouts<Get Course Handouts>` for courses the
user is enrolled in.
......
......@@ -8,6 +8,7 @@ This page describes how to use the mobile user API to:
* `Get User Details`_
* `Get a User's Course Enrollments`_
* `Get or Change User Status in a Course`_
.. _Get User Details:
......@@ -28,7 +29,7 @@ Users are redirected to this endpoint after logging in.
You can use the **course_enrollments** value in the response to get a list of
courses the user is enrolled in.
**Example request**:
**Example request**
``GET /api/mobile/v0.5/users/{username}``
......@@ -165,4 +166,62 @@ Get information about the courses the currently logged in user is enrolled in.
"start": "2013-02-05T05:00:00Z",
"course_image": "/c4x/edX/DemoX/asset/images_course_image.jpg"
}
}
.. _Get or Change User Status in a Course:
**************************************
Get or Change User Status in a Course
**************************************
.. .. autoclass:: mobile_api.users.views.UserCourseStatus
.. :members:
**Use Case**
Get or update the ID of the module that the specified user last visited in the
specified course.
**Example request**
``GET /api/mobile/v0.5/users/{username}/course_status_info/{course_id}``
.. code-block:: http
PATCH /api/mobile/v0.5/users/{username}/course_status_info/{course_id}
body:
last_visited_module_id={module_id}
modification_date={date}
The modification_date is optional. If it is present, the update will
only take effect if the modification_date is later than the
modification_date saved on the server.
**Response Values**
* last_visited_module_id: The ID of the last module visited by the user in the
course.
* last_visited_module_path: The ID of the modules in the path from the last
visited module to the course module.
**Example Response**
.. code-block:: json
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
{
"last_visited_module_id": "i4x://edX/DemoX/html/6018785795994726950614ce7d0f38c5",
"last_visited_module_path": [
"i4x://edX/DemoX/html/6018785795994726950614ce7d0f38c5",
"i4x://edX/DemoX/vertical/26d89b08f75d48829a63520ed8b0037d",
"i4x://edX/DemoX/sequential/dbe8fc027bcb4fe9afb744d2e8415855",
"i4x://edX/DemoX/chapter/social_integration",
"i4x://edX/DemoX/course/Demo_Course"
]
}
\ No newline at end of file
......@@ -70,8 +70,29 @@ class UserDetail(generics.RetrieveAPIView):
@mobile_view(is_user=True)
class UserCourseStatus(views.APIView):
"""
Endpoints for getting and setting meta data
about a user's status within a given course.
**Use Case**
Get or update the ID of the module that the specified user last visited in the specified course.
**Example request**:
GET /api/mobile/v0.5/users/{username}/course_status_info/{course_id}
PATCH /api/mobile/v0.5/users/{username}/course_status_info/{course_id}
body:
last_visited_module_id={module_id}
modification_date={date}
The modification_date is optional. If it is present, the update will only take effect
if the modification_date is later than the modification_date saved on the server.
**Response Values**
* last_visited_module_id: The ID of the last module visited by the user in the course.
* last_visited_module_path: The ID of the modules in the path from the
last visited module to the course module.
"""
http_method_names = ["get", "patch"]
......@@ -142,20 +163,7 @@ class UserCourseStatus(views.APIView):
@mobile_course_access()
def get(self, request, course, *args, **kwargs): # pylint: disable=unused-argument
"""
**Use Case**
Get meta data about user's status within a specific course
**Example request**:
GET /api/mobile/v0.5/users/{username}/course_status_info/{course_id}
**Response Values**
* last_visited_module_id: The id of the last module visited by the user in the given course
* last_visited_module_path: The ids of the modules in the path from the last visited module
to the course module
Get the ID of the module that the specified user last visited in the specified course.
"""
return self._get_course_info(request, course)
......@@ -163,24 +171,7 @@ class UserCourseStatus(views.APIView):
@mobile_course_access()
def patch(self, request, course, *args, **kwargs): # pylint: disable=unused-argument
"""
**Use Case**
Update meta data about user's status within a specific course
**Example request**:
PATCH /api/mobile/v0.5/users/{username}/course_status_info/{course_id}
body:
last_visited_module_id={module_id}
modification_date={date}
modification_date is optional. If it is present, the update will only take effect
if modification_date is later than the modification_date saved on the server
**Response Values**
The same as doing a GET on this path
Update the ID of the module that the specified user last visited in the specified course.
"""
module_id = request.DATA.get("last_visited_module_id")
modification_date_string = request.DATA.get("modification_date")
......
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