An Open edX plugin to generate industry/length-specific UAI custom courses from video CSV data.
Project description
An Open edX CMS plugin that automates the generation of industry- and length-specific UAI course variants using direct Open edX modulestore APIs.
Version Compatibility
Supports Open edX releases from Sumac and onwards.
Installing The Plugin
For detailed installation instructions, please refer to the plugin installation guide.
Installation required in:
CMS
Overview
For each unique (course_key, industry, duration) row group in the CSV the command clones the source course into a new UAI-specific key, removes every existing section from the clone, and rebuilds the content from the CSV data. This produces multiple industry- and length-specific variants per source course while preserving all course settings (grading policy, certificates, pacing, advanced settings) from the original.
Supported industry/length combinations:
Industry |
Code |
Length code |
Length |
|---|---|---|---|
Healthcare |
HC |
S |
Short |
Healthcare |
HC |
F |
Full |
Finance |
F |
S |
Short |
Finance |
F |
F |
Full |
Energy |
E |
S |
Short |
Energy |
E |
F |
Full |
Original |
— |
S |
Short |
Original |
— |
F |
Full |
Course Key Format
course-v1:ORG+NUMBER.<DURATION>[.<INDUSTRY>]+RUN
For the Original industry, no industry code is appended:
course-v1:UAI_SOURCE+UAI.3.S+1T2026 ← Original, Short
course-v1:UAI_SOURCE+UAI.3.F+1T2026 ← Original, Full
course-v1:UAI_SOURCE+UAI.3.S.HC+1T2026 ← Healthcare, Short
Course Structure
Each generated course has the following structure:
Course (<display name>)
├── Introduction (section, optional)
└── Introduction (subsection)
└── Introduction (unit)
└── Introduction (HTML block)
└── Lectures (section)
└── <Video Title> (subsection)
└── <Video Title> (unit)
└── <Video Title> (video block with edX video ID)
Usage
Prerequisites
You will need two CSV files:
Processed videos CSV — produced by the video customization workflow. Required columns:
course_key — the Open edX course key of the source course to clone (e.g. course-v1:UAI_SOURCE+UAI.2+1T2026). This course must already exist in the CMS modulestore before the command runs. The command validates all source keys up-front and aborts with an error if any are missing.
industry — one of: Healthcare, Finance, Energy, Original
duration — short or long
video_file_name — file name matching the name column in the edX videos CSV
video_title — display name for the subsection/unit/video
module_name — used to build the course display name
course_intro — optional introduction content for the generated course. If this value contains HTML tags, it is used as-is. If it is plain text, the command HTML-escapes it and wraps it in <p>...</p>.
Intro resolution precedence for each generated (course_key, industry, duration) variant:
exact match on (course_key, industry, duration)
fallback to (course_key, industry) (industry-only intro, reused for both short and long)
fallback to (course_key, Original industry) (reused across all industries and durations for that source course)
If no intro is resolved, no Introduction section is created for that variant.
Open edX videos CSV — exported from Studio / OVS after uploading the customized videos. Required columns:
name — video file name (matches video_file_name above)
video_id — the Open edX UUID for the video
Running the Command
Run the management command from inside the CMS container (e.g. Tutor dev shell):
python manage.py generate_uai_course_versions \
--processed-videos-csv /path/to/processed_videos.csv \
--edx-videos-csv /path/to/edx_videos.csv \
[--username studio_worker] \
[--dry-run]
Options
- --processed-videos-csv
Path to the processed video metadata CSV file. Required.
- --edx-videos-csv
Path to the Open edX videos CSV file. Required.
- --username
Username of the platform user under whose authority the courses are created. Defaults to studio_worker.
- --dry-run
Print what would be created without writing anything to the modulestore. Use this to verify CSV mapping before committing.
How It Works
For each unique (course_key, industry, duration) group the command:
Validates all source course keys against the live modulestore before making any writes (fail-fast — aborts if any source is missing).
Clones the source course into the new UAI-specific key, inheriting all course settings.
Deletes every existing section (chapter) from the clone.
Rebuilds the content tree from the CSV rows:
Course (cloned — settings inherited) ├── Introduction (optional, created only when ``course_intro`` resolves) └── Introduction (subsection) └── Introduction (unit) └── Introduction (HTML block) └── Lectures (section) └── <Video Title> (subsection) └── <Video Title> (unit) └── <Video Title> (video block)Publishes the course.
Development
# Install dependencies
uv sync --dev
# Run tests (requires Open edX environment — see AGENTS.md)
./run_edx_integration_tests.sh --plugin ol_openedx_uai_content_customization --skip-build
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 ol_openedx_uai_content_customization-0.1.1.tar.gz.
File metadata
- Download URL: ol_openedx_uai_content_customization-0.1.1.tar.gz
- Upload date:
- Size: 11.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49bd7152bfe84cd2f32d2bcb964cec6dbd43e12ce7bb6919263ba3a28773c7f7
|
|
| MD5 |
e015e071192182ce56e2859874c968e3
|
|
| BLAKE2b-256 |
c007e2494482846c22a3e1af6f42ad247b032f3b946f9cfd87e6f258764f89b7
|
File details
Details for the file ol_openedx_uai_content_customization-0.1.1-py3-none-any.whl.
File metadata
- Download URL: ol_openedx_uai_content_customization-0.1.1-py3-none-any.whl
- Upload date:
- Size: 16.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03568aead19cb17bc4c8077ce70f014756127717eb9db0a611df2018bf004754
|
|
| MD5 |
d912e540c725ed5cb594f5e2dd2b84ca
|
|
| BLAKE2b-256 |
5bff004cb45c33a41588dc8dea0fbb4baa13b5996b4e10ce10e915500433ec14
|