feat: update recommendations api (#31259)

- updated status codes
- for control group return general recommendations

VAN-1154
This commit is contained in:
Zainab Amir
2022-11-07 15:20:01 +05:00
committed by GitHub
parent 1925eb10c9
commit 6a89635aa4
4 changed files with 84 additions and 21 deletions

View File

@@ -823,6 +823,21 @@ class TestCourseRecommendationApiView(SharedModuleStoreTestCase):
password = "test"
url = reverse_lazy("learner_home:courses")
GENERAL_RECOMMENDATIONS = [
{
"course_key": "HogwartsX+6.00.1x",
"logo_image_url": random_url(),
"marketing_url": random_url(),
"title": "Defense Against the Dark Arts",
},
{
"course_key": "MonstersX+SC101EN",
"logo_image_url": random_url(),
"marketing_url": random_url(),
"title": "Scaring 101",
},
]
def setUp(self):
super().setUp()
self.user = UserFactory()
@@ -849,10 +864,10 @@ class TestCourseRecommendationApiView(SharedModuleStoreTestCase):
@override_waffle_flag(ENABLE_LEARNER_HOME_AMPLITUDE_RECOMMENDATIONS, active=False)
def test_waffle_flag_off(self):
"""
Verify API returns 400 if waffle flag is off.
Verify API returns 404 if waffle flag is off.
"""
response = self.client.get(self.url)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.status_code, 404)
self.assertEqual(response.data, None)
@override_waffle_flag(ENABLE_LEARNER_HOME_AMPLITUDE_RECOMMENDATIONS, active=True)
@@ -864,13 +879,25 @@ class TestCourseRecommendationApiView(SharedModuleStoreTestCase):
self, mocked_get_course_data, mocked_get_personalized_course_recommendations
):
"""
Verify API returns 400 if no course recommendations from amplitude.
Verify API returns 404 if no course recommendations from amplitude.
"""
mocked_get_personalized_course_recommendations.return_value = [False, []]
mocked_get_course_data.return_value = self.course_data
response = self.client.get(self.url)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.status_code, 404)
self.assertEqual(response.data, None)
@override_waffle_flag(ENABLE_LEARNER_HOME_AMPLITUDE_RECOMMENDATIONS, active=True)
@mock.patch(
"lms.djangoapps.learner_home.views.get_personalized_course_recommendations", Mock(side_effect=Exception)
)
def test_amplitude_api_unexpected_error(self):
"""
Test that if the Amplitude API gives an unexpected error, 500 is returned.
"""
response = self.client.get(self.url)
self.assertEqual(response.status_code, 500)
self.assertEqual(response.data, None)
@override_waffle_flag(ENABLE_LEARNER_HOME_AMPLITUDE_RECOMMENDATIONS, active=True)
@@ -898,6 +925,25 @@ class TestCourseRecommendationApiView(SharedModuleStoreTestCase):
len(response.data.get("courses")), expected_recommendations_length
)
@override_waffle_flag(ENABLE_LEARNER_HOME_AMPLITUDE_RECOMMENDATIONS, active=True)
@mock.patch("django.conf.settings.GENERAL_RECOMMENDATIONS", GENERAL_RECOMMENDATIONS)
@mock.patch(
"lms.djangoapps.learner_home.views.get_personalized_course_recommendations"
)
def test_general_recommendations(self, mocked_get_personalized_course_recommendations):
"""
Test that a user gets general recommendations for the control group.
"""
mocked_get_personalized_course_recommendations.return_value = [
True,
self.recommended_courses,
]
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data.get("is_personalized_recommendation"), False)
self.assertEqual(response.data.get("courses"), self.GENERAL_RECOMMENDATIONS)
@override_waffle_flag(ENABLE_LEARNER_HOME_AMPLITUDE_RECOMMENDATIONS, active=True)
@mock.patch(
"lms.djangoapps.learner_home.views.get_personalized_course_recommendations"

View File

@@ -93,16 +93,13 @@ def get_personalized_course_recommendations(user_id):
"get_recs": True,
"rec_id": settings.REC_ID,
}
try:
response = requests.get(settings.AMPLITUDE_URL, params=params, headers=headers)
if response.status_code == 200:
response = response.json()
recommendations = response.get("userData", {}).get("recommendations", [])
if recommendations:
is_control = recommendations[0].get("is_control")
recommended_course_keys = recommendations[0].get("items")
return is_control, recommended_course_keys
except Exception as ex: # pylint: disable=broad-except
log.warning(f"Cannot get recommendations from Amplitude: {ex}")
response = requests.get(settings.AMPLITUDE_URL, params=params, headers=headers)
if response.status_code == 200:
response = response.json()
recommendations = response.get("userData", {}).get("recommendations", [])
if recommendations:
is_control = recommendations[0].get("is_control")
recommended_course_keys = recommendations[0].get("items")
return is_control, recommended_course_keys
return True, []

View File

@@ -543,6 +543,8 @@ class InitializeView(RetrieveAPIView): # pylint: disable=unused-argument
class CourseRecommendationApiView(APIView):
"""
API to get personalized recommendations from Amplitude.
**Example Request**
GET /api/learner_home/recommendation/courses/
@@ -555,12 +557,18 @@ class CourseRecommendationApiView(APIView):
permission_classes = (IsAuthenticated,)
def get(self, request):
"""Retrieves course recommendations details of a user in a specified course."""
"""
Retrieves course recommendations details.
"""
if not should_show_learner_home_amplitude_recommendations():
return Response(status=400)
return Response(status=404)
user_id = request.user.id
is_control, course_keys = get_personalized_course_recommendations(user_id)
try:
user_id = request.user.id
is_control, course_keys = get_personalized_course_recommendations(user_id)
except Exception as ex: # pylint: disable=broad-except
logger.warning(f"Cannot get recommendations from Amplitude: {ex}")
return Response(status=500)
# Emits an event to track student dashboard page visits.
segment.track(
@@ -571,8 +579,17 @@ class CourseRecommendationApiView(APIView):
},
)
if is_control or not course_keys:
return Response(status=400)
if is_control:
return Response(
{
"courses": settings.GENERAL_RECOMMENDATIONS,
"is_personalized_recommendation": False,
},
status=200,
)
if not course_keys:
return Response(status=404)
recommended_courses = []
user_enrolled_course_keys = set()

View File

@@ -4753,8 +4753,11 @@ EDX_BRAZE_API_SERVER = None
AMPLITUDE_URL = ''
AMPLITUDE_API_KEY = ''
REC_ID = ''
# Keeping this for back compatibility with learner dashboard api
GENERAL_RECOMMENDATION = {}
GENERAL_RECOMMENDATIONS = []
############### Settings for Retirement #####################
# .. setting_name: RETIRED_USERNAME_PREFIX
# .. setting_default: retired__user_