-
Notifications
You must be signed in to change notification settings - Fork 172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: filter restricted runs on APIs #4356
Conversation
9c1c271
to
f65796f
Compare
course_discovery/apps/api/utils.py
Outdated
@@ -198,6 +199,9 @@ def increment_character(character): | |||
""" | |||
return chr(ord(character) + 1) if character != 'z' else 'a' | |||
|
|||
def get_forbidden_runs(request): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use get_restricted_runs (and restricted_runs as a variable) for consistency. Forbidden_runs can mislead when someone else is reading the code (with little to no context). (and to add to following comment, this method is only returning restriction type(s), not actual course runs. That is also misleading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have updated some names. Hopefully it's good enough now
course_discovery/apps/api/utils.py
Outdated
@@ -198,6 +199,9 @@ def increment_character(character): | |||
""" | |||
return chr(ord(character) + 1) if character != 'z' else 'a' | |||
|
|||
def get_forbidden_runs(request): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- nit: missing docstring.
- the method is not really returning runs but rather restriction types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have updated some names. Hopefully it's good enough now
@@ -47,7 +47,7 @@ def prepare_position(self, obj): | |||
return [] | |||
return [position.title, position.organization_override] | |||
|
|||
def get_queryset(self): | |||
def get_queryset(self, excluded_restriction_types=[]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need this default but unused argument?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to this change, the get_queryset method is called with the excluded_restriction_types for all documents. We don't really use excluded_restriction_type
in the get_queryset
of some documents but the argument is still passed. Hence, this is to prevent an error.
We could have a condition to check the document type, and only pass it in for those documents which need it, but I think it is neater this way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. It would be good to have this context in docstrings/context for future's sake.
course_discovery/apps/course_metadata/search_indexes/serializers/course.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Played around a bit with this locally, looks good.
One thing: search/<> endpoints are missing restriction_type field on course_run serializers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did some playaround with the include_restricted
in api/v1 endpoints & search endpoints on local. Changes look good.
[thinking] One thing we can do in a followup PR to check for N+1 queries.
@@ -87,7 +87,8 @@ def _wrap(self, *args, **kwargs): | |||
|
|||
|
|||
def get_course_availability(course): | |||
all_runs = course.course_runs.filter(status=CourseRunStatus.Published) | |||
all_runs = course.course_runs.all() | |||
all_runs = filter(lambda r: r.status == CourseRunStatus.Published, all_runs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering why this change has been done?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have prefetched course_runs
on course
. And in that prefetch, we have excluded restricted runs. Now if we dont make this change, it will go to the database and course.course_runs
will return all runs (even restricted ones). This makes sure that the prefetched course runs are used.
course_discovery/apps/course_metadata/search_indexes/documents/learner_pathway.py
Outdated
Show resolved
Hide resolved
3f8337a
to
7e0c087
Compare
course_discovery/apps/api/v1/tests/test_views/test_course_runs.py
Outdated
Show resolved
Hide resolved
course_discovery/apps/api/v1/tests/test_views/test_course_runs.py
Outdated
Show resolved
Hide resolved
self.assertEqual(set(response.data['course_run_keys']), {run_not_restricted.key, run_restricted.key}) | ||
self.assertEqual( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if block is doing assertListEqual, this is doing assertEqual. Since the context is same, we should try to keep the code consistent where applicable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have converted both to assertEqual.
if include_restricted_run: | ||
RestrictedCourseRunFactory(course_run=course_run, restriction_type='custom-b2c') # pylint: disable=possibly-used-before-assignment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: if we move this if include_restricted_run:
under if block at 55, will we still need pylint disable checks there? Considering we can't restriction without run, it makes sense to nest this if block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have nested the block, and have also removed the pylint disable.
course_discovery/apps/course_metadata/tests/test_algolia_models.py
Outdated
Show resolved
Hide resolved
1e215aa
to
2295621
Compare
2295621
to
3881ed6
Compare
Internal tickets: PROD-4005 + PROD-4006
Hide restricted runs across APIs by default. Also do not include them when calculating fields like course_run_statuses. If a query-param
include_restricted=<some_value>
is present, do not hide themTesting
update_index