Modern Moodle CLI tool
Project description
python-moodle
A modern Pythonic CLI and library to manage Moodle via web sessions, with full session and CAS support.
!!! warning "Experimental" This library is under active development. Use a test Moodle instance and back up data before running commands that create, modify, or delete content.
py-moodle allows you to automate tedious Moodle tasks—like creating courses, uploading content, and managing modules—directly from your terminal or in your Python scripts. It works by simulating a real user's web session, so it doesn't require API tokens or special Moodle plugins.
Features
- Manage Moodle entities: Courses, sections, users, and modules from the command line.
- Rich module support: Includes built-in support for Folders, Labels, Assignments, and SCORM packages.
- Session-based: Works with standard Moodle web sessions, avoiding the need for web service tokens.
- Authentication: Supports standard Moodle login and SSO/CAS authentication.
- Dual Use: Can be used as a powerful CLI or imported as a library into your own Python projects.
- Extensible: Designed to be easily extended with new modules and commands. See
AGENTS.md. - English-only codebase: For clear, global collaboration.
Moodle Compatibility
py-moodle interacts with Moodle through authenticated web sessions, HTML forms, and page parsing. To make those flows more resilient across Moodle releases, the library now centralizes version-sensitive logic in py_moodle.compat.
- Version detection happens during login/session initialization. The library first tries
core_webservice_get_site_infowhen a webservice token is available, then falls back to probing the dashboard HTML (/my/) for Moodle release metadata. - Version-aware strategies are grouped into compatibility ranges instead of scattering selectors throughout the codebase. The current built-in strategies cover legacy Moodle 3.x layouts and modern Moodle 4.x/5.x layouts.
- Feature probing remains in place when version detection is not enough. Each strategy can try multiple selectors or form patterns before failing.
- Fragile flows should read selectors from the compatibility layer so future Moodle HTML changes are isolated to one module.
At the moment, representative compatibility handling has been wired into login/session bootstrap, generic module form parsing, and folder page scraping. When a new Moodle release changes one of these flows, the recommended fix is to update py_moodle.compat and add a regression test for the new selector or workflow.
Installation
You will need Python 3.8+ and pip.
Install from PyPI (Recommended)
pip install python-moodle
Install from Source
Clone the repository and install:
git clone https://github.com/erseco/python-moodle.git
cd python-moodle
pip install .
Configure your environment
Copy the example .env.example file to .env and add your Moodle instance credentials.
cp .env.example .env
# Now, edit the .env file with your credentials
!!! danger
The .env file stores real credentials. Keep it out of version control and share it with no one.
Your .env file should look like this:
# Production environment credentials
MOODLE_PROD_URL=https://your.moodle.site
MOODLE_PROD_USERNAME=your_admin_user
MOODLE_PROD_PASSWORD=your_super_secret_password
# Optional: CAS SSO URL
# MOODLE_PROD_CAS_URL=https://cas.your-institution.org/cas
# Optional: Predefined webservice token (required for CAS)
# MOODLE_PROD_WS_TOKEN=your_webservice_token
Use the --env flag or the MOODLE_ENV variable to select the environment, e.g. py-moodle --env prod courses list.
Note: For local development, you can quickly spin up a Moodle instance using the provided
docker-compose.yml:docker-compose up -d.
CLI Usage
Once installed, all functionality is available through the py-moodle command. Every command and subcommand includes detailed help with the -h or --help flag.
Common Commands
Here are a few examples of common commands:
List all available courses:
py-moodle courses list
Output:
┏━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┓
┃ ID ┃ Shortname ┃ Fullname ┃ Category ┃ Visible ┃
┡━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━┩
│ 2 │ my-first-course │ My first course │ 1 │ 1 │
│ 4 │ my-second-course │ My second course │ 1 │ 1 │
└────┴────────────────────┴────────────────────┴──────────┴─────────┘
Show the structure of a single course:
py-moodle courses show 2
Create a new course:
py-moodle courses create --fullname "My New Automated Course" --shortname "auto-course-01"
Add a label to a course section:
py-moodle modules add label --course-id 2 --section-id 1 --name "Welcome" --intro "<h1>Welcome to the course!</h1>"
Upload a SCORM package to a course:
py-moodle modules add scorm --course-id 2 --section-id 1 --name "My SCORM Package" --path "path/to/your/scorm.zip"
Library Usage (Automation Scripting)
You can also import py-moodle's functions into your own Python scripts to automate complex workflows. The example_script.py file provides a comprehensive tutorial.
Quick Example
from py_moodle import MoodleSession
from py_moodle.course import list_courses
# Credentials are loaded automatically from your .env file
ms = MoodleSession.get()
courses = list_courses(ms.session, ms.settings.url, token=ms.token)
for course in courses:
print(course["id"], course["fullname"])
How the Example Script Works
The script is a self-contained demonstration that:
- Logs into Moodle using the credentials from your
.envfile. - Creates a new, temporary course.
- Populates the course with sections, labels, assignments, and a SCORM package.
- Creates a folder and uploads multiple files to it.
- Prints a summary of the final course structure.
- Automatically cleans up and deletes the course and all its contents.
Running the Example
Make sure you have a valid .env file and have installed the dependencies. Then, simply run:
python example_script.py
This script is the best starting point for understanding how to use the library's functions for your own automation needs.
Testing
The project uses pytest and provides a Makefile with convenient targets.
Run the fast smoke test suite (no Moodle service required):
make test-unit
Run the Docker-backed integration suite against the local environment:
make test-local
Run tests against the staging environment:
make test-staging
Run all configured environments:
make test
GitHub Actions automatically runs:
- linting on Python 3.13
- smoke tests on Python 3.8 through 3.13
- Docker-backed integration tests on representative Python/Moodle combinations:
- Python 3.8 with Moodle 4.5.5
- Python 3.13 with Moodle 5.0.1
Development
Use the Makefile to format code, run linters, or build the documentation:
make format # run black and isort
make lint # run static analysis
make docs # build the MkDocs site
Documentation
Documentation is generated with MkDocs using the Read the Docs theme and published automatically to the gh-pages branch.
Every push to main builds the API reference and CLI guide from the source code and makes it available via GitHub Pages.
To build the documentation locally:
pip install mkdocs 'mkdocstrings[python]'
mkdocs build --strict
The rendered site will be available under the site/ directory.
Contribution
Contributions are welcome! Please follow the guidelines outlined in [AGENTS.md]. Key principles include:
- All code, comments, and documentation must be in English.
- Code must be formatted with
blackand linted withflake8. - Docstrings must use the Google style;
flake8-docstringsis configured for this convention. - The CLI should be a thin layer over the core library functions.
- All new features must be accompanied by tests.
License
This project is licensed under the MIT License.
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 python_moodle-0.1.0.tar.gz.
File metadata
- Download URL: python_moodle-0.1.0.tar.gz
- Upload date:
- Size: 75.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a4fd8497d01a1ebed4a47123410cfca12decb3a938f7adb3dbcea80954bb60f9
|
|
| MD5 |
b509bd0a0f65e85a2e37cba166963fa6
|
|
| BLAKE2b-256 |
a98f2eab1589c5c805dfa3935a0c5760c3a185cfe25e4ed277fc5c24b89f7968
|
Provenance
The following attestation bundles were made for python_moodle-0.1.0.tar.gz:
Publisher:
release.yml on erseco/python-moodle
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python_moodle-0.1.0.tar.gz -
Subject digest:
a4fd8497d01a1ebed4a47123410cfca12decb3a938f7adb3dbcea80954bb60f9 - Sigstore transparency entry: 1110090185
- Sigstore integration time:
-
Permalink:
erseco/python-moodle@675dcdafaa4b00c75556587c050458e3f38fa8c5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/erseco
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@675dcdafaa4b00c75556587c050458e3f38fa8c5 -
Trigger Event:
release
-
Statement type:
File details
Details for the file python_moodle-0.1.0-py3-none-any.whl.
File metadata
- Download URL: python_moodle-0.1.0-py3-none-any.whl
- Upload date:
- Size: 75.7 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 |
59bdb6f94a1b3c57bb398570d28424f0884a2ebcc0129bccbcbe0c2ccfed805a
|
|
| MD5 |
518731f530490706c5766bd9b76c904b
|
|
| BLAKE2b-256 |
97fd3947abbbb93cfaae89122ba302bc1efb9b9713dd8ee0d9630a47c83be7e6
|
Provenance
The following attestation bundles were made for python_moodle-0.1.0-py3-none-any.whl:
Publisher:
release.yml on erseco/python-moodle
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python_moodle-0.1.0-py3-none-any.whl -
Subject digest:
59bdb6f94a1b3c57bb398570d28424f0884a2ebcc0129bccbcbe0c2ccfed805a - Sigstore transparency entry: 1110090190
- Sigstore integration time:
-
Permalink:
erseco/python-moodle@675dcdafaa4b00c75556587c050458e3f38fa8c5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/erseco
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@675dcdafaa4b00c75556587c050458e3f38fa8c5 -
Trigger Event:
release
-
Statement type: