-
Notifications
You must be signed in to change notification settings - Fork 12
feat: API endpoint for in-context Supserset dashboards #136
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
Conversation
|
Thanks for the pull request, @ArturGaspar! This repository is currently maintained by Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review. 🔘 Get product approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. DetailsWhere can I find more information?If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources: When can I expect my changes to be merged?Our goal is to get community contributions seen and reviewed as efficiently as possible. However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
8be5718 to
4abec48
Compare
platform_plugin_aspects/views.py
Outdated
| ) | ||
|
|
||
| if dashboard.get("allow_translations"): | ||
| user = get_current_user() |
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 you don't need get_current_user from crum here and can use just request.user.
ea229ae to
1bb1aa4
Compare
1bb1aa4 to
15e8edd
Compare
df53d40 to
8d8d996
Compare
farhaanbukhsh
left a comment
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 added few comments but overall it looks good.
👍
- ✅ I tested this on sandbox
- ✅ I read through the code
- ❌ I checked for accessibility issues
- ✅ Includes documentation
platform_plugin_aspects/urls.py
Outdated
| from . import views | ||
|
|
||
| # Copied from openedx.core.constants | ||
| # Copied from edx-platform |
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.
Adding the filename or URL should be a good comment.
platform_plugin_aspects/urls.py
Outdated
| # FIXME: remove this one, keeping it until frontend plugin is updated | ||
| re_path( | ||
| rf"superset_embedded_dashboard/{USAGE_ID_PATTERN}/?$", | ||
| views.SupersetInContextDashboardView.as_view(), | ||
| name="superset_embedded_dashboard", | ||
| ), |
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.
Do we still need this?
platform_plugin_aspects/views.py
Outdated
| ) | ||
|
|
||
| course_runs = {} | ||
| # TODO: obtain course 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.
We should remove this.
|
|
||
| class SupersetInContextDashboardView(GenericAPIView): | ||
| """ | ||
| Endpoint for in-context analytics embedded Superset dashboard parameters. |
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.
Putting in an example get request and response would make this view look great.
| # TODO: obtain course runs. | ||
| for course_run in [course_key.run]: | ||
| course_filter = block_filter.copy() | ||
| for filter_id in dashboard["course_filter_ids"]: |
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 iff course_filter_id in not present?
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.
Same as block_filter_ids, I think it makes sense to require it to be specified, especially as it makes less sense to have a dashboard where data is not filtered to the current course.
|
|
||
| block_filter = {} | ||
| if not isinstance(usage_key, CourseKey): | ||
| for filter_id in dashboard["block_filter_ids"]: |
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.
| for filter_id in dashboard["block_filter_ids"]: | |
| for filter_id in dashboard.get("block_filter_ids"): |
what about 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.
@farhaanbukhsh Any block-specific dashboard (including subsection ones) should require this configuration, the course-wide dashboard being the only exception. I think it makes more sense to fail than to silently ignore a misconfiguration.
Embedded dashboard configuration will be operator-extensible in the future e.g. for custom XBlocks.
bmtcril
left a comment
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.
Looking great overall, just a few comments!
platform_plugin_aspects/utils.py
Outdated
| """ | ||
| try: | ||
| user_language = ( | ||
| get_model("user_preference").get_value(user, "pref-lang") or "en" |
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.
Eventually we would like to make the default language configurable, but in the meantime can we define en as a constant so there are fewer places to change it later?
|
|
||
| def build_filter(filter_id, col, op, val): | ||
| """Build a Superset native filter option.""" | ||
| return { |
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: this comment's format doesn't match the format of the others in the file.
Can you also put in a description of what the filter values mean? Superset's col, op, and val are not very intuitive.
platform_plugin_aspects/views.py
Outdated
| CourseOverview = get_model("course_overviews") | ||
| if CourseOverview: | ||
| try: | ||
| course_overview = CourseOverview.objects.get(id=course_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.
CourseOverview is a pretty big model with a lot of fields, if you only care about display_name you could do (fake code, but should be close):
course_overview = CourseOverview.objects.get(id=course_key).only("display_name") to get the model with only that field populated or
display_name = CourseOverview.objects.get(id=course_key).values("display_name")["display_name"] to skip all of the model code and just get return the name.
This matters more now with likely increase in how often this code will be called.
platform_plugin_aspects/views.py
Outdated
| course = self.get_object() | ||
|
|
||
| dashboards = settings.ASPECTS_INSTRUCTOR_DASHBOARDS | ||
| dashboards = settings.ASPECTS_INSTRUCTOR_DASHBOARDS[:] |
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.
Is the [:] needed here? If it's just for the copy, can you use an explicit settings.ASPECTS_INSTRUCTOR_DASHBOARDS.copy() for readability?
| filter_id, course_key_col, "IN", [str(course_key)] | ||
| ) | ||
| course_runs[course_run] = { | ||
| "native_filters": prison.dumps(course_filter), |
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 usage of prison probably deserves a comment since I think it's the only place in this repo where it's used.
f5f1d9e to
ae27d9b
Compare
|
@ArturGaspar is this pr complete? |
d3f1ebe to
c38633f
Compare
|
@farhaanbukhsh Yes. |
c38633f to
fa4aceb
Compare
fa4aceb to
f1bd765
Compare
bmtcril
left a comment
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.
Looks good, thanks for getting this done. There are a couple of outstanding comments, but I don't think any of them are blocking.
|
@bmtcril can we merge this? |
|
All set, merged and released as v1.1.0! |
Description
Adds an API endpoint for in-context Supserset dashboards.
This uses the dashboards from openedx/tutor-contrib-aspects#1046.
Supporting information
In-Context Metrics for Studio: Product Requirements
Testing instructions
Add this repository checked out to this branch as a Tutor mountpoint:
tutor mounts add platform-plugin-aspectsInstall tutor-contrib-aspects from feat: in-context analytics dashboards tutor-contrib-aspects#1046
Enable Aspects as instructed in tutor-contrib-aspects (ignoring the pip install tutor-contrib-aspects, as it should be installed from the PR above)
Add and enable the following Tutor plugin in order to use the local copy instead of the one installed by tutor-contrib-aspects.
Save the following HTML for testing embedding:
Details
Obtain the guest token from http://local.openedx.io:8000/aspects/superset_guest_token/course-v1:OpenedX+DemoX+DemoCourse and fill it in the HTML above
Obtain the dashboard UUID and native filters from http://local.openedx.io:8000/aspects/superset_in_context_dashboard/course-v1:OpenedX+DemoX+DemoCourse, fill in the HTML above, see that it embeds successfully and loads data corresponsing to the selected course
Obtain the dashboard UUID and native filters from http://local.openedx.io:8000/aspects/superset_in_context_dashboard/[block id], fill in the HTML above, see that it embeds successfully and loads data corresponsing to the selected subsection or block
Deadline
9 April 2025
Other information
Merge checklist:
Check off if complete or not applicable:
Private-ref: https://tasks.opencraft.com/browse/BB-9597