Commit be16ced3 by Clinton Blackburn

Consolidated Course Structure API Client

This consolidations removes duplicated code and adds the ability for the access token to be overridden by Django settings. The override should make it easier to specify an access token if the authenticated user does not have one, specifically when running tests locally using a course structure API client on another machine.
parent 0ae6802d
...@@ -4,13 +4,12 @@ from unittest import skip ...@@ -4,13 +4,12 @@ from unittest import skip
from bok_choy.promise import EmptyPromise from bok_choy.promise import EmptyPromise
from analyticsclient.client import Client from analyticsclient.client import Client
import slumber
from acceptance_tests import API_SERVER_URL, API_AUTH_TOKEN, DASHBOARD_FEEDBACK_EMAIL, SUPPORT_URL, LMS_USERNAME, \ from acceptance_tests import API_SERVER_URL, API_AUTH_TOKEN, DASHBOARD_FEEDBACK_EMAIL, SUPPORT_URL, LMS_USERNAME, \
LMS_PASSWORD, DASHBOARD_SERVER_URL, ENABLE_AUTO_AUTH, DOC_BASE_URL, COURSE_API_URL, \ LMS_PASSWORD, DASHBOARD_SERVER_URL, ENABLE_AUTO_AUTH, DOC_BASE_URL, COURSE_API_URL, \
COURSE_API_KEY, ENABLE_COURSE_API COURSE_API_KEY, ENABLE_COURSE_API
from common import BearerAuth
from acceptance_tests.pages import LMSLoginPage from acceptance_tests.pages import LMSLoginPage
from common.clients import CourseStructureApiClient
MAX_SUMMARY_POINT_VALUE_LENGTH = 13 MAX_SUMMARY_POINT_VALUE_LENGTH = 13
...@@ -34,7 +33,7 @@ class CourseApiMixin(object): ...@@ -34,7 +33,7 @@ class CourseApiMixin(object):
super(CourseApiMixin, self).setUp() super(CourseApiMixin, self).setUp()
if ENABLE_COURSE_API: if ENABLE_COURSE_API:
self.course_api_client = slumber.API(COURSE_API_URL, auth=BearerAuth(COURSE_API_KEY)) self.course_api_client = CourseStructureApiClient(COURSE_API_URL, COURSE_API_KEY)
def get_course_name_or_id(self, course_id): def get_course_name_or_id(self, course_id):
""" Returns the course name if the course API is enabled; otherwise, the course ID. """ """ Returns the course name if the course API is enabled; otherwise, the course ID. """
......
...@@ -7,9 +7,9 @@ from django.conf import settings ...@@ -7,9 +7,9 @@ from django.conf import settings
from django.core.cache import cache from django.core.cache import cache
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import slumber
import common import common
from common.clients import CourseStructureApiClient
from courses import utils from courses import utils
from courses.exceptions import NoAnswerSubmissionsError from courses.exceptions import NoAnswerSubmissionsError
from courses.presenters import BasePresenter from courses.presenters import BasePresenter
...@@ -45,8 +45,7 @@ class CoursePerformancePresenter(BasePresenter): ...@@ -45,8 +45,7 @@ class CoursePerformancePresenter(BasePresenter):
def __init__(self, access_token, course_id, timeout=10): def __init__(self, access_token, course_id, timeout=10):
super(CoursePerformancePresenter, self).__init__(course_id, timeout) super(CoursePerformancePresenter, self).__init__(course_id, timeout)
self.course_api_client = slumber.API(settings.COURSE_API_URL, self.course_api_client = CourseStructureApiClient(settings.COURSE_API_URL, access_token)
auth=common.BearerAuth(access_token))
def get_answer_distribution(self, problem_id, problem_part_id): def get_answer_distribution(self, problem_id, problem_part_id):
""" """
......
...@@ -14,13 +14,12 @@ from django.utils.functional import cached_property ...@@ -14,13 +14,12 @@ from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic import TemplateView from django.views.generic import TemplateView
import requests import requests
import slumber
from slumber.exceptions import HttpClientError from slumber.exceptions import HttpClientError
from waffle import switch_is_active from waffle import switch_is_active
from analyticsclient.client import Client from analyticsclient.client import Client
from analyticsclient.exceptions import NotFoundError, ClientError from analyticsclient.exceptions import NotFoundError, ClientError
from common import BearerAuth from common.clients import CourseStructureApiClient
from core.utils import sanitize_cache_key from core.utils import sanitize_cache_key
from courses import permissions from courses import permissions
from courses.serializers import LazyEncoder from courses.serializers import LazyEncoder
...@@ -50,8 +49,8 @@ class CourseAPIMixin(object): ...@@ -50,8 +49,8 @@ class CourseAPIMixin(object):
self.course_api_enabled = switch_is_active('enable_course_api') self.course_api_enabled = switch_is_active('enable_course_api')
if self.course_api_enabled and request.user.is_authenticated(): if self.course_api_enabled and request.user.is_authenticated():
self.access_token = request.user.access_token self.access_token = settings.COURSE_API_KEY or request.user.access_token
self.course_api = slumber.API(settings.COURSE_API_URL, auth=BearerAuth(self.access_token)).courses self.course_api = CourseStructureApiClient(settings.COURSE_API_URL, self.access_token).courses
return super(CourseAPIMixin, self).dispatch(request, *args, **kwargs) return super(CourseAPIMixin, self).dispatch(request, *args, **kwargs)
......
...@@ -414,5 +414,7 @@ THEME_SCSS = 'sass/themes/open-edx.scss' ...@@ -414,5 +414,7 @@ THEME_SCSS = 'sass/themes/open-edx.scss'
########## COURSE API ########## COURSE API
COURSE_API_URL = None COURSE_API_URL = None
# If no key is specified, the authenticated user's OAuth2 access token will be used.
COURSE_API_KEY = None COURSE_API_KEY = None
########## END COURSE API ########## END COURSE API
import slumber
from common import BearerAuth
class CourseStructureApiClient(slumber.API):
"""
Course Structure API Client
This class is a sub-class slumber.API (http://slumber.readthedocs.org/en/latest/). Details
about the API itself can be found at https://openedx.atlassian.net/wiki/display/AN/Course+Structure+API.
"""
DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
def __init__(self, url, access_token):
super(CourseStructureApiClient, self).__init__(url, auth=BearerAuth(access_token))
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