-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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: [FC-0031] Add new endpoint BlocksInfoInCourseView #33296
feat: [FC-0031] Add new endpoint BlocksInfoInCourseView #33296
Conversation
Thanks for the pull request, @oksana-slu! Please note that it may take us up to several weeks or months to complete a review and merge your PR. Feel free to add as much of the following information to the ticket as you can:
All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here. Please let us know once your PR is ready for our review and all tests are green. |
835815e
to
36dd2cd
Compare
36dd2cd
to
0807140
Compare
|
||
**Example requests**: | ||
|
||
This api works with all versions {api_version}, you can use: v0.5, v1, v2 or v3 |
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 introduce a new version if it can work with previous versions?
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.
Hello @jawad-khan, the version 3 was introduced first of all in PR: #33294
Here we have added version 3 support as per comment https://openedx.atlassian.net/wiki/spaces/COMM/pages/3853910042?focusedCommentId=3856859206 for general consistency in new mobile applications.
Ed's suggestion was to make it more intuitive for using mobile API with new and old apps:
one could assume that any call to the API version n or above would be for the new apps, < n for the legacy apps
&block_counts=video | ||
&student_view_data=video | ||
&block_types_filter=problem,html | ||
|
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.
Can you add information about the params this view accpets?
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.
Yes, I have done that
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.
You can refer to the parent class about all params not used here. We are only using course_id and return_type here.
information about each block. Each block contains the following | ||
fields. | ||
|
||
id: (str) The Course's id (Course Run key) |
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.
what if we call the view with list param, will we still get these fields?
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.
Ok, it's done. Add description to "return_type=list"
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 we call this view with return_type=list we will not get certificate and all other details processed in this view. Please update view according to the desired behavior.
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.
@jawad-khan, the docstring was updated to explicitly include data about the response when return_type=list is provided
course_data = { | ||
# identifiers | ||
'id': course_id, | ||
'name': course_overview.display_name, |
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.
Can we move course overview data in another function and update dict here?
This will clean this view method.
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.
Yes, I moved course overview data to new method "compose_course_info"
ed315cb
to
4e20865
Compare
@jawad-khan kindly ask you for another round of review |
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'm a little confused by this PR, the one new view simply returns courseoverviews data and I don't see how it does anything with pulling block data out of the system.
""" | ||
|
||
def get_certificate(self, request, course_id): | ||
"""Returns the information about the user's certificate in the course.""" |
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.
Given that this is a public function, can you document the input parameters and the format of the output data?
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.
Yes, sure
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.
input and output docs still missing.
Method for obtaining additional information about the course. | ||
|
||
Arguments: | ||
request - Django request object |
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.
This is incorrect, update to say that it expects a CourseOverviews object as input.
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.
Thanks, this is a mistake, should be fixed
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.
This function was replaced with serializer as suggested
return {} | ||
|
||
@staticmethod | ||
def compose_course_info(course_overview): |
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 have this function instead of using a serializer? For the places where names differ you can just set them explicitly.
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 will check what to do with this
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 are already extracting most of the info related to course info and certificate in this serializer.
Can we use that api, or serializer for this case?
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.
@feanil @jawad-khan This function was replaced with CourseInfoOverviewSerializer
, please review the latest changes
response = super().list(request, kwargs) | ||
|
||
if request.GET.get('return_type', 'dict') == 'dict': | ||
course_id = request.query_params.get('course_id', None) |
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.
What if course_id is None?
Please handle all these cases in tests.
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.
Hi Jawad!
The course_id
is a required field and validated in the parent class - here https://github.com/raccoongang/edx-platform/blob/master/lms/djangoapps/course_api/blocks/views.py#L305
Furthermore, all the test cases are covered because TestBlocksInfoInCourseView class is extending TestBlocksInCourseView which has those test cases covered.
&block_counts=video | ||
&student_view_data=video | ||
&block_types_filter=problem,html | ||
|
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.
You can refer to the parent class about all params not used here. We are only using course_id and return_type here.
|
||
|
||
@ddt.ddt | ||
class TestBlocksInfoInCourseView(TestBlocksInCourseView): # lint-amnesty, pylint: disable=test-inherits-tests |
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.
Add test cases for all the response types mentioned in response status codes returned by this view.
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.
Just because we are extending TestBlocksInCourseView we decided and agreed to focus only on testing the changes in response (new fields as media
, course dates
, certificate
) exist in response
information about each block. Each block contains the following | ||
fields. | ||
|
||
id: (str) The Course's id (Course Run key) |
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 we call this view with return_type=list we will not get certificate and all other details processed in this view. Please update view according to the desired behavior.
""" | ||
|
||
def get_certificate(self, request, course_id): | ||
"""Returns the information about the user's certificate in the course.""" |
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.
input and output docs still missing.
return {} | ||
|
||
@staticmethod | ||
def compose_course_info(course_overview): |
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 are already extracting most of the info related to course info and certificate in this serializer.
Can we use that api, or serializer for this case?
6e21bc1
to
022d508
Compare
@feanil This is ready for review, the function was replaced with serializer, also docstrings were updated |
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.
@GlugovGrGlib I think instead of adding this as a new mobile view, why not add this as more parameters on the existing block view? We could provide the new data behind a query param so as not to break the existing behavior if necessary. But this feels like a lot of copying just to add additional data. It looks like the only difference between this endpoint and the original one is the addition or the image urls, is that right?
Hi @feanil, while designing, @GlugovGrGlib and I determined that creating a dedicated endpoint for the mobile course home screen could be advantageous in the long run. cc @marcotuts |
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.
Making a specific backend for the mobile frontend makes sense, I'm concerned that changes in the upstream classes will be harder to make or cause downstream issues here but I think the tests you have will hopefully catch that. I think we should update the docstring for the new class to make it clear that this API endpoint is specifically meant to optimize the mobile homepage. Once we've updated that, I'm okay with merging this.
""" | ||
**Use Case** | ||
|
||
Returns the blocks in the course according to the requesting user's access level. |
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 think if this is going to be an API optimized for the mobile home page, we should update the comment to say so.
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.
The docstring is updated.
Thank you!
e0e4b34
to
774dd6b
Compare
774dd6b
to
cae4091
Compare
@oksana-slu 🎉 Your pull request was merged! Please take a moment to answer a two question survey so we can improve your experience in the future. |
2U Release Notice: This PR has been deployed to the edX staging environment in preparation for a release to production. |
2U Release Notice: This PR has been deployed to the edX production environment. |
2U Release Notice: This PR has been deployed to the edX staging environment in preparation for a release to production. |
2U Release Notice: This PR has been deployed to the edX production environment. |
1 similar comment
2U Release Notice: This PR has been deployed to the edX production environment. |
Description
Add a new mobile endpoint that extends BlocksInCourseView, and add more data about a course as
media
,course dates
,certificate
etc.This endpoint was added into mobile_api LMS application. In the future, this endpoint can be extended to be, for example, a coursee home endpoint for a mobile.
Supporting information
This contribution is done as a part of the project FC-0031
Testing instructions
GET /api/mobile/{api_version}/course_info/blocks/?course_id=<course_id>
Check that fields
start
,media
,certificate
are in the reponse.