Skip to content

Commit

Permalink
feat: ACADEMIC-16210: Created a module for API methods
Browse files Browse the repository at this point in the history
  • Loading branch information
rijuma committed Jul 26, 2023
1 parent b27cc3b commit 4ddf700
Show file tree
Hide file tree
Showing 10 changed files with 552 additions and 100 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ Change Log
Unreleased
**********

3.2.0 – 2023-07-26
**********************************************

Features
=========
* Added the checks for the module settings behind the waffle flag `summaryhook.summaryhook_summaries_configuration`.
* Error suppression logs now include block ID
* Missing video transcript is caught earlier in content fetch

Expand Down
46 changes: 46 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,52 @@ For the summary aside to work, you will have to make two changes in the LMS admi

2. You must enable a course waffle flag for each course you want to summarize. ``summaryhook.summaryhook_enabled`` is the main one, ``summaryhook_enabled.summaryhook_staff_only`` can be used if you only want staff to see it.

3. You must enable a course waffle flag if you want to use the feature for enabling/disabling the summary by its settings. ``summaryhook.summaryhook_summaries_configuration``. If this flag is enabled, you can enable/disable the courses and the blocks by its settings.

Aside Settings API
~~~~~~~~~~~~~~~~~~

There are some endpoints that can be used to pinpoint units to be either enabled or disabled based on their configs. The new settings work as follows:
- If a course is enabled, the summary for all the blocks for that course are enabled by default.
- If a course is disabled or the setting does not exists, then the summary for all the blocks from that course are disabled by default.
- If a block has its own settings, it will override any other setting with the one that is saved.
- If a block does not have any settings saved, then the enabled state will fall back to the course's enabled state mentioned above.

The new endpoints for updating these settings are:

Fetch settings
..............

+--------+-------------------------------------+-------------------------------------------------------------------+
| Method | Path | Responses |
+========+=====================================+===================================================================+
| GET | ``ai_aside/v1/:course_id`` | - Code 200: ``{ "success": true }`` |
+--------+-------------------------------------+ - Code 400: ``{ "success": false, "message": "(description)" }`` |
| GET | ``ai_aside/v1/:course_id/:unit_id`` | - Code 404: ``{ "success": false }`` |
+--------+-------------------------------------+-------------------------------------------------------------------+

Update settings
...............

+--------+-------------------------------------+-------------------------------+------------------------------------------------------------------+
| Method | Path | Payload | Responses |
+========+=====================================+===============================+==================================================================+
| POST | ``ai_aside/v1/:course_id`` | ``{ "enabled": true|false }`` | - Code 200: ``{ "success": true }`` |
+--------+-------------------------------------+-------------------------------+ - Code 400: ``{ "success": false, "message": "(description)" }`` |
| POST | ``ai_aside/v1/:course_id/:unit_id`` | ``{ "enabled": true|false }`` | |
+--------+-------------------------------------+-------------------------------+------------------------------------------------------------------+

Delete settings
...............

+--------+-------------------------------------+-------------------------------------------------------------------+
| Method | Path | Responses |
+========+=====================================+===================================================================+
| DELETE | ``ai_aside/v1/:course_id`` | - Code 200: ``{ "success": true }`` |
+--------+-------------------------------------+ - Code 400: ``{ "success": false, "message": "(description)" }`` |
| DELETE | ``ai_aside/v1/:course_id/:unit_id`` | - Code 404: ``{ "success": false }`` |
+--------+-------------------------------------+-------------------------------------------------------------------+

Every time you develop something in this repo
---------------------------------------------
.. code-block::
Expand Down
2 changes: 1 addition & 1 deletion ai_aside/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
A plugin containing xblocks and apps supporting GPT and other LLM use on edX.
"""

__version__ = '3.1.0'
__version__ = '3.2.0'

default_app_config = "ai_aside.apps.AiAsideConfig"
138 changes: 138 additions & 0 deletions ai_aside/api/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
"""
Implements an API for updating unit and course settings.
"""
from ai_aside.models import AIAsideCourseEnabled, AIAsideUnitEnabled
from ai_aside.waffle import summaries_configuration_enabled


class NotFoundError(Exception):
"Raised when the course/unit is not found in the database"


def _get_course(course_key):
"Private method that gets a course based on an id"
try:
record = AIAsideCourseEnabled.objects.get(
course_key=course_key,
)
except AIAsideCourseEnabled.DoesNotExist as exc:
raise NotFoundError from exc

return record


def _get_unit(course_key, unit_key):
"Private method that gets a unit based on an id"
try:
record = AIAsideUnitEnabled.objects.get(
course_key=course_key,
unit_key=unit_key,
)
except AIAsideUnitEnabled.DoesNotExist as exc:
raise NotFoundError from exc

return record


def get_course_settings(course_key):
"Gets the settings of a course"
record = _get_course(course_key)
fields = {
'enabled': record.enabled
}

return fields


def set_course_settings(course_key, settings):
"Sets the settings of a course"

enabled = settings['enabled']

if not isinstance(enabled, bool):
raise TypeError

update = {'enabled': enabled}

AIAsideCourseEnabled.objects.update_or_create(
course_key=course_key,
defaults=update,
)

return True


def delete_course_settings(course_key):
"Deletes the settings of a course"
record = _get_course(course_key)
record.delete()

return True


def get_unit_settings(course_key, unit_key):
"Gets the settings of a course's unit"
record = _get_unit(course_key, unit_key)

fields = {
'enabled': record.enabled
}

return fields


def set_unit_settings(course_key, unit_key, settings):
"Sets the settings of a course's unit"

enabled = settings['enabled']

if not isinstance(enabled, bool):
raise TypeError

update = {'enabled': enabled}

AIAsideUnitEnabled.objects.update_or_create(
course_key=course_key,
unit_key=unit_key,
defaults=update,
)

return True


def delete_unit_settings(course_key, unit_key):
"Deletes the settings of a course's unit"
record = _get_unit(course_key, unit_key)
record.delete()

return True


def is_summary_enabled(course_key, unit_key=None):
"""
Gets the enabled state of a course's unit.
It considers both the state of a unit's override and a course defaults.
"""

# If the feature flag is disabled, do not restrict
if not summaries_configuration_enabled(course_key):
return True

if unit_key is not None:
try:
unit = _get_unit(course_key, unit_key)

if unit is not None:
return unit.enabled
except NotFoundError:
pass

try:
course = _get_course(course_key)
except NotFoundError:
return False

if course is not None:
return course.enabled

return False
Loading

0 comments on commit 4ddf700

Please sign in to comment.