Unverified Commit ac3642ad by Albert (AJ) St. Aubin Committed by GitHub

Merge pull request #16493 from edx/aj/LEARNER-3160

Added new method to retrieve the course runs for a course based on UUID
parents c37ce9b7 ddcc5fea
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('catalog', '0004_auto_20170616_0618'),
]
operations = [
migrations.AddField(
model_name='catalogintegration',
name='long_term_cache_ttl',
field=models.PositiveIntegerField(default=86400, help_text='Specified in seconds (defaults to 86400s, 24hr). In some cases the cache does needs to be refreshed less frequently. Enable long term caching of API responses by setting this to a value greater than 0.', verbose_name='Long Term Cache Time To Live'),
),
]
......@@ -29,6 +29,15 @@ class CatalogIntegration(ConfigurationModel):
)
)
long_term_cache_ttl = models.PositiveIntegerField(
verbose_name=_('Long Term Cache Time To Live'),
default=86400,
help_text=_(
'Specified in seconds (defaults to 86400s, 24hr). In some cases the cache does needs to be refreshed '
'less frequently. Enable long term caching of API responses by setting this to a value greater than 0.'
)
)
service_username = models.CharField(
max_length=100,
default='lms_catalog_service_user',
......
......@@ -11,10 +11,11 @@ from student.tests.factories import UserFactory
from openedx.core.djangoapps.catalog.cache import PROGRAM_CACHE_KEY_TPL, SITE_PROGRAM_UUIDS_CACHE_KEY_TPL
from openedx.core.djangoapps.catalog.models import CatalogIntegration
from openedx.core.djangoapps.catalog.tests.factories import CourseRunFactory, ProgramFactory, ProgramTypeFactory
from openedx.core.djangoapps.catalog.tests.factories import CourseFactory, CourseRunFactory, ProgramFactory, ProgramTypeFactory
from openedx.core.djangoapps.catalog.tests.mixins import CatalogIntegrationMixin
from openedx.core.djangoapps.catalog.utils import (
get_course_runs,
get_course_runs_for_course,
get_course_run_details,
get_currency_data,
get_program_types,
......@@ -330,6 +331,18 @@ class TestGetCourseRuns(CatalogIntegrationMixin, TestCase):
self.assert_contract(mock_get_edx_api_data.call_args)
self.assertEqual(data, catalog_course_runs)
def test_get_course_runs_by_course(self, mock_get_edx_api_data):
"""
Test retrievals of run from a Course.
"""
catalog_course_runs = CourseRunFactory.create_batch(10)
catalog_course = CourseFactory(course_runs=catalog_course_runs)
mock_get_edx_api_data.return_value = catalog_course
data = get_course_runs_for_course(course_uuid=str(catalog_course['uuid']))
self.assertTrue(mock_get_edx_api_data.called)
self.assertEqual(data, catalog_course_runs)
@skip_unless_lms
@mock.patch(UTILS_MODULE + '.get_edx_api_data')
......
......@@ -210,6 +210,38 @@ def get_course_runs():
return course_runs
def get_course_runs_for_course(course_uuid):
catalog_integration = CatalogIntegration.current()
if catalog_integration.is_enabled():
try:
user = catalog_integration.get_service_user()
except ObjectDoesNotExist:
logger.error(
'Catalog service user with username [%s] does not exist. Course runs will not be retrieved.',
catalog_integration.service_username,
)
return []
api = create_catalog_api_client(user)
cache_key = '{base}.course.{uuid}.course_runs'.format(
base=catalog_integration.CACHE_KEY,
uuid=course_uuid
)
data = get_edx_api_data(
catalog_integration,
'courses',
resource_id=course_uuid,
api=api,
cache_key=cache_key if catalog_integration.is_cache_enabled else None,
long_term_cache=True
)
return data.get('course_runs', [])
else:
return []
def get_course_run_details(course_run_key, fields):
"""
Retrieve information about the course run with the given id
......
......@@ -24,7 +24,7 @@ def get_fields(fields, response):
def get_edx_api_data(api_config, resource, api, resource_id=None, querystring=None, cache_key=None, many=True,
traverse_pagination=True, fields=None):
traverse_pagination=True, fields=None, long_term_cache=False):
"""GET data from an edX REST API.
DRY utility for handling caching and pagination.
......@@ -42,6 +42,7 @@ def get_edx_api_data(api_config, resource, api, resource_id=None, querystring=No
many (bool): Whether the resource requested is a collection of objects, or a single object.
If false, an empty dict will be returned in cases of failure rather than the default empty list.
traverse_pagination (bool): Whether to traverse pagination or return paginated response..
long_term_cache (bool): Whether to use the long term cache ttl or the standard cache ttl
Returns:
Data returned by the API. When hitting a list endpoint, extracts "results" (list of dict)
......@@ -81,7 +82,10 @@ def get_edx_api_data(api_config, resource, api, resource_id=None, querystring=No
if cache_key:
zdata = zpickle(results)
cache.set(cache_key, zdata, api_config.cache_ttl)
cache_ttl = api_config.cache_ttl
if long_term_cache:
cache_ttl = api_config.long_term_cache_ttl
cache.set(cache_key, zdata, cache_ttl)
return results
......
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