-
Notifications
You must be signed in to change notification settings - Fork 1
feat: Allow adding custom LTI parameters via LTI_CUSTOM_PARAMS django setting #323
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
base: mitx/teak
Are you sure you want to change the base?
feat: Allow adding custom LTI parameters via LTI_CUSTOM_PARAMS django setting #323
Conversation
🔍 Existing Issues For ReviewYour pull request is modifying functions with the following pre-existing issues: 📄 File: lms/djangoapps/lti_provider/views.py
Did you find this useful? React with a 👍 or 👎 |
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.
Summary of Changes
Hello @xitij2000, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request primarily introduces the capability to define and process custom LTI (Learning Tools Interoperability) parameters within the platform. This enhancement allows for greater flexibility when integrating with external LTI tools by enabling the inclusion of additional, user-defined data during LTI launches. Beyond the core LTI feature, the PR also includes updates to the instructor dashboard, specifically adding support for Canvas integration-related tasks and making minor UI improvements to data tables.
Highlights
- Custom LTI Parameters: Introduced a new Django setting,
LTI_CUSTOM_PARAMS, which allows administrators to define a list of custom LTI parameters that the platform should recognize and process during an LTI launch. - LTI Launch Processing: Modified the LTI launch view to extract and store these newly defined custom parameters, ensuring they are available for other plugins or integrations.
- LTI Parameter Testing: Added a dedicated test case to validate that the system correctly handles LTI launches with custom parameters, confirming the new functionality works as expected.
- Instructor Dashboard & Canvas Integration: Integrated new functionality related to Canvas integration within the instructor dashboard, including filtering tasks and formatting messages based on Canvas-specific data.
- Frontend Improvements: Enhanced the instructor dashboard's user interface by enabling text selection within data tables and adding a new generic HTML data table template.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
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.
Code Review
This pull request introduces a new feature to allow custom LTI parameters to be passed during an LTI launch, configured via the LTI_CUSTOM_PARAMS Django setting. This is a useful extension for plugins that need to receive extra information. The changes include the core logic in the LTI provider view, a new setting, and corresponding tests. Additionally, there are several changes related to a Canvas integration, including updates to the instructor dashboard and task views.
My review focuses on improving code clarity, correctness, and maintainability. I've pointed out an opportunity to simplify test code, corrected a type hint and a misleading docstring in the new LTI parameter handling function, and fixed invalid HTML in a new template. These changes will help ensure the new code is robust and easy to understand.
| store_params.assert_called_with( | ||
| dict(list(ALL_PARAMS.items()) + list(LTI_OPTIONAL_PARAMS.items()) + list(extra_params.items())), | ||
| request.user, | ||
| self.consumer | ||
| ) |
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 dictionary construction for the assertion is a bit verbose. Since you're using the | operator for dictionary union on line 132, you could use it here as well to make the code more concise and readable.
| store_params.assert_called_with( | |
| dict(list(ALL_PARAMS.items()) + list(LTI_OPTIONAL_PARAMS.items()) + list(extra_params.items())), | |
| request.user, | |
| self.consumer | |
| ) | |
| store_params.assert_called_with( | |
| ALL_PARAMS | LTI_OPTIONAL_PARAMS | extra_params, | |
| request.user, | |
| self.consumer | |
| ) |
| def get_custom_parameters(params: dict[str]) -> dict[str]: | ||
| """ | ||
| Extract all optional LTI parameters from a dictionary. This method does not | ||
| fail if any parameters are missing. | ||
| :param params: A dictionary containing zero or more parameters. | ||
| :return: A new dictionary containing all optional parameters from the | ||
| original dictionary, or an empty dictionary if no optional parameters | ||
| were 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.
The type hint for params is invalid. It should be dict[str, str] since request.POST values are strings. Also, the docstring seems to be a copy-paste from get_optional_parameters and is misleading. It should refer to "custom" LTI parameters, not "optional" ones, to avoid confusion.
| def get_custom_parameters(params: dict[str]) -> dict[str]: | |
| """ | |
| Extract all optional LTI parameters from a dictionary. This method does not | |
| fail if any parameters are missing. | |
| :param params: A dictionary containing zero or more parameters. | |
| :return: A new dictionary containing all optional parameters from the | |
| original dictionary, or an empty dictionary if no optional parameters | |
| were present. | |
| """ | |
| def get_custom_parameters(params: dict[str, str]) -> dict[str, str]: | |
| """ | |
| Extract all custom LTI parameters from a dictionary. This method does not | |
| fail if any parameters are missing. | |
| :param params: A dictionary containing zero or more parameters. | |
| :return: A new dictionary containing all custom parameters from the | |
| original dictionary, or an empty dictionary if no custom parameters | |
| were present. | |
| """ |
| <p> | ||
| <h2><%- title %></h2> | ||
| <table class="stat_table"><tr> | ||
| <%_.forEach(header, function (h) {%> | ||
| <th><%- h %></th> | ||
| <%})%> | ||
| </tr> | ||
| <%_.forEach(data, function (row) {%> | ||
| <tr> | ||
| <%_.forEach(row, function (value) {%> | ||
| <td><%- value %></td> | ||
| <%})%> | ||
| </tr> | ||
| <%})%> | ||
| </table> | ||
| </p> |
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 HTML structure is invalid because an <h2> element cannot be a direct child of a <p> element. This can lead to unpredictable rendering in some browsers. You should use a <div> as the container instead.
<div>
<h2><%- title %></h2>
<table class="stat_table"><tr>
<%_.forEach(header, function (h) {%>
<th><%- h %></th>
<%})%>
</tr>
<%_.forEach(data, function (row) {%>
<tr>
<%_.forEach(row, function (value) {%>
<td><%- value %></td>
<%})%>
</tr>
<%})%>
</table>
</div>
fea8dd8 to
6c683ad
Compare
6c683ad to
a224971
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 tested this with tutor devstack
- ✅ I read through the code
- ❌ I checked for accessibility issues
- ❌ Includes documentation
16091f9 to
4b6df42
Compare
… setting Adds a new Django setting called `LTI_CUSTOM_PARAMS` that allows extending the list of optional LTI parameters processed by the platform. These parameters can be used by plugins for deeper platform integration. (cherry picked from commit 0fde8c2)
a224971 to
281f46e
Compare
4b6df42 to
ec79885
Compare
Cherry-pick of : openedx#37262