-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This django app is installed into the analytics-data-api to expose an endpoint to allow enterprises to access their learner enrollment data
- Loading branch information
1 parent
6da8344
commit 695a5d4
Showing
61 changed files
with
1,807 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
language: python | ||
python: | ||
- 2.7 | ||
- 3.5 | ||
env: | ||
- TOXENV=master | ||
matrix: | ||
include: | ||
- python: 3.5 | ||
env: TOXENV=quality | ||
- python: 2.7 | ||
env: TOXENV=quality | ||
cache: | ||
- pip | ||
install: | ||
- pip install -r requirements/travis.txt | ||
script: | ||
- if env | grep RUNJSHINT; then make jshint; else tox; fi | ||
after_success: | ||
- codecov | ||
deploy: | ||
provider: pypi | ||
user: edx | ||
distributions: sdist bdist_wheel | ||
on: | ||
tags: true | ||
condition: "$TOXENV = quality" | ||
password: | ||
secure: vWQHEuSdKajVDfw6C3BQ+hEiGm8RIhjE6bu13URaHAHNYnxaxlyUEaw0HX8dKPeQ5O4WIwL1XutClKAb/hyL8VP3u7Pj9ZyiQX05Ift2mN0TDn4xWV/IgaBHAU/o4MIzDyZPriogHfp0i+GtD35ByfqOj6MTB3ntrDc7twDMkgYYPTVfMElKNtY3X1C5N6Lx/vprzdd+JFf/NuuMz8mPBe/rqBCIQNZRE3IXfyHAQwERY833LHrCWrEGhkR5zlirHQPd9enQ/1WRxMaICptnSaNwNnDib+h3XzKmM2l9uGXJV+vUQ+PK7C5fyiqr99DPKlQ9vyOINyxKDH+RS28umLeGMWxTrf30h5u24VcKtnq3JmP5jzduy2dAoQohgdqlBb132j79hlUC7W/fES3wDnKYxEpniCTQHOpZLTMt170cyKxHJmdC9NVw3ZmiKXh7bAYbS9Ul/Yv46SV3PHt0ls6tqP3HzKj5TFNwWj9wqNWbIh3b5jtdjngeN6ibiYZ2IirEesW4PCtUX6SC1nAY3diiET+z/NVsUwVLIZ4Evz0MB+DtCM4x69ubN5B9TVVd0oAR9wfvBup3TgnqeePNF8HM4z+ru9JWxoAHmucR0mX3FzXvAxLT0IF7csm+KMAjuEoPMkSKRRCbcKov5lAjaIjjXnivrIvtWXCjWndpfZ0= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Change Log | ||
========== | ||
|
||
.. | ||
All enhancements and patches to edx-enteprise-data will be documented | ||
in this file. It adheres to the structure of http://keepachangelog.com/ , | ||
but in reStructuredText instead of Markdown (for ease of incorporation into | ||
Sphinx documentation and the PyPI description). | ||
This project adheres to Semantic Versioning (http://semver.org/). | ||
|
||
.. There should always be an "Unreleased" section for changes pending release. | ||
Unreleased | ||
---------- | ||
|
||
[0.1.0] - 2018-03-07 | ||
--------------------- | ||
|
||
* Add new app `enterprise_api`. This django app is used to expose a REST endpoint in th eex-analytics-data-api project. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
include AUTHORS | ||
include CHANGELOG.rst | ||
include CONTRIBUTING.rst | ||
include LICENSE.txt | ||
include README.rst | ||
recursive-include enterprise_data *.html *.png *.gif *js *.css *jpg *jpeg *svg *py *.txt | ||
recursive-include enterprise_reporting *.html *.png *.gif *js *.css *jpg *jpeg *svg *py *.txt | ||
recursive-include requirements *.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,13 @@ | ||
# edx-enterprise-data | ||
The edX Enterprise Data repo is the home to tools and products related to providing access to Enterprise related data. | ||
|
||
This repository is currently split into 2 folders: enterprise_reporting and enterprise_data | ||
|
||
## enterprise_data app | ||
This django app exposes a REST api endpoint to access enterprise learner activity. The enterprise-data app is published | ||
to pypi as a library and installed into the [edx-analytics-data-api](github.com/edx/edx-analytics-data-api/) project | ||
and uses OAuth JWT authentication from [edx-drf-extensions](https://github.com/edx/edx-drf-extensions/blob/master/edx_rest_framework_extensions/authentication.py). | ||
|
||
## enterprise_reporting scripts | ||
This folder contains a set of scripts used to push enterprise data reports. | ||
It supports multiple delivery methods (email, sftp) and is triggered through jenkins scheduled jobs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
""" | ||
Enterprise data api application. This Django app exposes API endpoints used by enterprises. | ||
""" | ||
|
||
from __future__ import absolute_import, unicode_literals | ||
|
||
__version__ = "0.1.0" | ||
|
||
default_app_config = "enterprise_data.apps.EnterpriseDataAppConfig" # pylint: disable=invalid-name |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
URL definitions for enterprise data API endpoint. | ||
""" | ||
from __future__ import absolute_import, unicode_literals | ||
|
||
from rest_framework.urlpatterns import format_suffix_patterns | ||
|
||
from django.conf.urls import include, url | ||
|
||
urlpatterns = [ | ||
url(r'^v0/', include('enterprise_data.api.v0.urls', 'v0'), name='api_v0'), | ||
] | ||
|
||
urlpatterns = format_suffix_patterns(urlpatterns) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
API endpoint for enterprise data app. | ||
""" | ||
from __future__ import unicode_literals | ||
|
||
default_app_config = 'enterprise_data.api.v0.apps.ApiAppConfig' # pylint: disable=invalid-name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Serializers for enterprise api version 0 endpoint. | ||
""" | ||
from __future__ import absolute_import, unicode_literals | ||
|
||
from rest_framework import serializers | ||
|
||
from enterprise_data.models import EnterpriseEnrollment | ||
|
||
|
||
class EnterpriseEnrollmentSerializer(serializers.ModelSerializer): | ||
""" | ||
Serializer for EnterpriseEnrollment model. | ||
""" | ||
|
||
class Meta: | ||
model = EnterpriseEnrollment | ||
fields = '__all__' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
URL definitions for enterprise data api version 1 endpoint. | ||
""" | ||
from __future__ import absolute_import, unicode_literals | ||
|
||
from django.conf.urls import url | ||
|
||
from enterprise_data.api.v0 import views | ||
|
||
urlpatterns = [ | ||
url(r'^enterprise/(?P<enterprise_id>.+)/enrollments/$', | ||
views.EnterpriseEnrollmentsView.as_view(), | ||
name='enterprise_enrollments'), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Views for enterprise api version 0 endpoint. | ||
""" | ||
from __future__ import absolute_import, unicode_literals | ||
|
||
from edx_rest_framework_extensions.authentication import JwtAuthentication | ||
from edx_rest_framework_extensions.paginators import DefaultPagination | ||
from rest_framework import generics | ||
|
||
from enterprise_data.api.v0 import serializers | ||
from enterprise_data.filters import ConsentGrantedFilterBackend | ||
from enterprise_data.models import EnterpriseEnrollment | ||
from enterprise_data.permissions import IsStaffOrEnterpriseUser | ||
|
||
|
||
class EnterpriseEnrollmentsView(generics.ListAPIView): | ||
""" | ||
The EnterpriseEnrollments view returns all learner enrollment records for a given enterprise | ||
""" | ||
serializer_class = serializers.EnterpriseEnrollmentSerializer | ||
pagination_class = DefaultPagination | ||
authentication_classes = (JwtAuthentication,) | ||
permission_classes = (IsStaffOrEnterpriseUser,) | ||
filter_backends = (ConsentGrantedFilterBackend,) | ||
CONSENT_GRANTED_FILTER = 'consent_granted' | ||
|
||
def get_queryset(self): | ||
enterprise_id = self.kwargs['enterprise_id'] | ||
return EnterpriseEnrollment.objects.filter(enterprise_id=enterprise_id) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Enterprise Data Django application initialization. | ||
""" | ||
|
||
from __future__ import absolute_import, unicode_literals | ||
|
||
from django.apps import AppConfig | ||
|
||
|
||
class EnterpriseDataAppConfig(AppConfig): | ||
""" | ||
Configuration for the enterprise Django application. | ||
""" | ||
|
||
name = "enterprise_data" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
""" | ||
Clients used to connect to other systems. | ||
""" | ||
from __future__ import absolute_import, unicode_literals | ||
|
||
import logging | ||
|
||
from edx_rest_api_client.client import EdxRestApiClient | ||
from edx_rest_api_client.exceptions import HttpClientError, HttpServerError | ||
from rest_framework.exceptions import NotFound, ParseError | ||
|
||
from django.conf import settings | ||
|
||
LOGGER = logging.getLogger('enterprise_data') | ||
|
||
|
||
class EnterpriseApiClient(EdxRestApiClient): | ||
""" | ||
The EnterpriseApiClient is used to communicate with the enterprise API endpoints in the LMS. | ||
This class is a sub-class of the edX Rest API Client | ||
(https://github.com/edx/edx-rest-api-client). | ||
""" | ||
|
||
API_BASE_URL = settings.LMS_BASE_URL + 'enterprise/api/v1/' | ||
|
||
def __init__(self, jwt): | ||
""" | ||
Initialize client with given jwt. | ||
""" | ||
super(EnterpriseApiClient, self).__init__(self.API_BASE_URL, jwt=jwt) | ||
|
||
def get_enterprise_learner(self, user): | ||
""" | ||
Get an enterprise learner record for a given user with the enterprise association. | ||
Returns: learner record or None if unable to retrieve or no Enterprise Learner exists | ||
""" | ||
try: | ||
querystring = {'username': user.username} | ||
endpoint = getattr(self, 'enterprise-learner') | ||
response = endpoint.get(**querystring) | ||
except (HttpClientError, HttpServerError) as exc: | ||
LOGGER.warning("Unable to retrieve Enterprise Customer Learner details for user {}: {}" | ||
.format(user.username, exc)) | ||
raise exc | ||
|
||
if response.get('results', None) is None: | ||
raise NotFound('Unable to process Enterprise Customer Learner details for user {}: No Results Found' | ||
.format(user.username)) | ||
|
||
if response['count'] > 1: | ||
raise ParseError('Multiple Enterprise Customer Learners found for user {}'.format(user.username)) | ||
|
||
if response['count'] == 0: | ||
return None | ||
|
||
return response['results'][0] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
""" | ||
Filters for enterprise data views. | ||
""" | ||
from __future__ import absolute_import, unicode_literals | ||
|
||
from rest_framework import filters | ||
|
||
|
||
class ConsentGrantedFilterBackend(filters.BaseFilterBackend): | ||
""" | ||
Filter backend for any view that needs to filter results where consent has not been granted. | ||
This requires that `CONSENT_GRANTED_FILTER` be set in the view as a class variable, to identify | ||
the object's relationship to the consent_granted field. | ||
""" | ||
|
||
def filter_queryset(self, request, queryset, view): | ||
""" | ||
Filter a queryset for results where consent has been granted. | ||
""" | ||
filter_kwargs = {view.CONSENT_GRANTED_FILTER: True} | ||
return queryset.filter(**filter_kwargs) |
Oops, something went wrong.