Extra Open edX REST APIs for analytics, course management, and grading.
Project description
Extra API endpoints for Open edX
This Django app provides additional REST API endpoints for Open edX to enable advanced features such as analytics, course management, and role inspection. It is intended to be deployed inside an Open edX platform using Tutor.
Installation (via Tutor plugin)
Use the Tutor plugin from aulasneo to install and enable these APIs inside your Open edX deployment:
Repository: https://github.com/aulasneo/tutor-contrib-owly
Quick start with Tutor:
Install the plugin
tutor plugins install git+https://github.com/aulasneo/tutor-contrib-owly.gitEnable and configure
tutor plugins enable owly tutor config saveApply and start
tutor images build openedx tutor local launch
Once enabled, the app is included in LMS and exposes endpoints under the paths registered by openedx_owly_apis/urls.py.
API Summary
Base router registrations are defined in openedx_owly_apis/urls.py:
/owly-analytics/ → OpenedXAnalyticsViewSet
/owly-config/ → OpenedXConfigViewSet
/owly-courses/ → OpenedXCourseViewSet
/owly-roles/ → OpenedXRolesViewSet
Authentication is supported via JWT/Bearer/Session. Specific permissions are enforced per endpoint (see notes below).
v1 Contract Source of Truth
The v1 API contract is now defined by serializer classes in openedx_owly_apis/views/v1/serializers.py.
Request bodies and query parameters are validated at the view boundary before calling the business logic in openedx_owly_apis/operations/.
Serializer field names are the authoritative wire contract for v1.
The API validates and rejects malformed payloads; it does not normalize them.
Caller-side systems such as owly-server are responsible for shaping their payloads to match the documented serializer contract exactly.
Response Envelope
v1 endpoints now use a consistent envelope pattern:
Success: {"success": true, "data": {...}}
Error: {"success": false, "error": "<message>", "error_detail": {...}, "error_code": "<code>"}
error_detail contains the structured machine-readable error information used for validation feedback and client-side reformulation.
Configuration endpoints (GET)
ViewSet: openedx_owly_apis/views/config_openedx.py Requires: Authenticated user.
GET /owly-config/enable_owly_chat Check if the Owly chat feature is enabled via waffle flag. Can check for a specific user by providing an email query parameter.
Analytics endpoints (GET)
ViewSet: openedx_owly_apis/views/analytics.py Requires: Admin or Course Staff permissions.
GET /owly-analytics/overview?course_id=<course-key> Returns overview analytics for a course or platform-wide stats.
GET /owly-analytics/enrollments?course_id=<course-key> Returns detailed enrollment analytics for a course.
GET /owly-analytics/discussions?course_id=<course-key> Returns forum analytics and configuration for a course.
GET /owly-analytics/detailed?course_id=<course-key> Returns a comprehensive, combined analytics payload for a course.
Course management endpoints (POST)
ViewSet: openedx_owly_apis/views/courses.py Requires: Authenticated user. Additional role-based permissions per action.
POST /owly-courses/create Create a new course. Requires admin or course creator.
POST /owly-courses/structure Create or edit course structure. Requires admin, course creator, or course staff.
POST /owly-courses/content/html Add HTML content to a vertical. Requires admin, course creator, or course staff.
POST /owly-courses/content/video Add video content to a vertical. Requires admin, course creator, or course staff.
POST /owly-courses/content/problem Add problems/exercises to a vertical using XML. Requires admin, course creator, or course staff.
POST /owly-courses/content/problem/create Create a problem component with structured data (e.g., multiple choice). Requires admin, course creator, or course staff. The exact payload contract is defined by CreateProblemComponentRequestSerializer.
POST /owly-courses/content/discussion Add discussion components to a vertical. Requires admin, course creator, or course staff.
POST /owly-courses/content/publish Publish a course or course component (unit, subsection, etc.). Requires admin or course staff.
POST /owly-courses/xblock/delete Delete an XBlock component from a course. Requires admin or course staff.
POST /owly-courses/settings/update Update general course settings (dates, details, etc.). Requires admin or course staff.
POST /owly-courses/settings/advanced Update advanced course settings. Requires admin or course staff.
POST /owly-courses/certificates/configure Configure or activate/deactivate course certificates. Requires admin or course staff.
POST /owly-courses/units/availability/control Control unit availability and due dates. Requires admin or course staff.
Staff management endpoints
POST /owly-courses/staff/manage Add or remove a user from a course staff role (staff or course_creator). Requires admin or course staff.
GET /owly-courses/staff/list?course_id=<course-key> List users with staff roles for a given course. Requires admin or course staff.
Roles endpoint (GET)
ViewSet: openedx_owly_apis/views/roles.py Requires: Authenticated user.
GET /owly-roles/me?course_id=<course-key>&org=<org-key> Returns the effective role of the authenticated user, including flags for:
superadmin (Django superuser or global staff)
course_staff (instructor/staff/limited_staff for given course)
course_creator (global or org-specific according to platform settings)
authenticated
Permissions and Authentication
Authentication classes: JWT (JwtAuthentication), Bearer (BearerAuthentication), Session.
Permissions:
Analytics: IsAdminOrCourseStaff
Courses: action-specific guards such as IsAdminOrCourseCreator, IsAdminOrCourseCreatorOrCourseStaff, IsAdminOrCourseStaff
Roles: IsAuthenticated
Config: IsAuthenticated
Access Control Policy
The API follows this rule:
if the underlying Open edX implementation path already performs the correct access control for the authenticated user, the API should preserve that behavior and avoid adding stricter app-level checks
if an endpoint uses lower-level access paths that could bypass normal Open edX visibility or authoring controls, the API adds the minimum explicit guardrails needed to avoid that bypass
Async course structure job polling additionally verifies that the requesting user is authorized to inspect the cached job state.
Development
Source paths of interest:
Views: openedx_owly_apis/views/
Operations logic: openedx_owly_apis/operations/
URL routing: openedx_owly_apis/urls.py
License
AGPL-3.0. See LICENSE.txt.
Project Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openedx_owly_apis-2.1.1.tar.gz.
File metadata
- Download URL: openedx_owly_apis-2.1.1.tar.gz
- Upload date:
- Size: 109.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d2ff0412764d765fa572c3a0f57bed1bad3487e2996bdb2a962ca884ed192fe
|
|
| MD5 |
0e610a4cad70b48a65ed97b9f2bdef8b
|
|
| BLAKE2b-256 |
96ed9bced13456493a6c092098ea1aa6559a43acc1199b457e00ae6a7cc121dd
|
Provenance
The following attestation bundles were made for openedx_owly_apis-2.1.1.tar.gz:
Publisher:
pypi-publish.yml on aulasneo/openedx-owly-apis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openedx_owly_apis-2.1.1.tar.gz -
Subject digest:
5d2ff0412764d765fa572c3a0f57bed1bad3487e2996bdb2a962ca884ed192fe - Sigstore transparency entry: 1203616481
- Sigstore integration time:
-
Permalink:
aulasneo/openedx-owly-apis@c4d005831632703e9fbeca3127151fc0fe6caf41 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/aulasneo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@c4d005831632703e9fbeca3127151fc0fe6caf41 -
Trigger Event:
workflow_run
-
Statement type:
File details
Details for the file openedx_owly_apis-2.1.1-py3-none-any.whl.
File metadata
- Download URL: openedx_owly_apis-2.1.1-py3-none-any.whl
- Upload date:
- Size: 97.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bfa7477856afb83d6aad53d1f0c004c694ca8cba601d053f4fdd5fe753cfc1d
|
|
| MD5 |
0f3d7be5485466c98bc1b71a9ca285c2
|
|
| BLAKE2b-256 |
40b54ffbeb0de42d2cf8cb06423bfefb22a662a0eac2dcb4bef01944d3c76da9
|
Provenance
The following attestation bundles were made for openedx_owly_apis-2.1.1-py3-none-any.whl:
Publisher:
pypi-publish.yml on aulasneo/openedx-owly-apis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openedx_owly_apis-2.1.1-py3-none-any.whl -
Subject digest:
7bfa7477856afb83d6aad53d1f0c004c694ca8cba601d053f4fdd5fe753cfc1d - Sigstore transparency entry: 1203616485
- Sigstore integration time:
-
Permalink:
aulasneo/openedx-owly-apis@c4d005831632703e9fbeca3127151fc0fe6caf41 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/aulasneo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@c4d005831632703e9fbeca3127151fc0fe6caf41 -
Trigger Event:
workflow_run
-
Statement type: