CertifyMe certificate issuance plugin for Open edX
Project description
CertifyMe Open edX Plugin
Open edX plugin that automatically issues CertifyMe credentials when a learner passes a course. The plugin is a thin bridge — all certificate design, templating, and delivery logic lives in CertifyMe; this package only talks to its REST API and keeps a local record of what was requested.
Features
- Admin-editable configuration (regional server, API token, template ID, credential fields, auto-issue toggle) with full change history.
- Automatic issuance on course completion, via the Open edX Hooks Extension Framework — never blocks an LMS request; all API calls happen in a Celery task.
- Automatic retries with exponential backoff for transient CertifyMe failures; permanent failures are recorded with a reason and can be retried manually from Django admin or the instructor tools page.
- Learner-facing "My Certificates" page (with a link to the CertifyMe-hosted certificate) and a public certificate verification page.
- Course-staff "instructor tools" page: search/filter, manual issue, bulk issue for a whole cohort, retry.
Architecture notes
- Registration: uses edx-platform's native Django plugin architecture
(
lms.djangoapp/cms.djangoappentry points + aplugin_appconfig inapps.py), not a bespoke Tutor plugin. NoINSTALLED_APPSedits, no core changes. - Course-completion signal: subscribes to
openedx_events.learning.signals.COURSE_PASSING_STATUS_UPDATED, the Hooks Extension Framework event edx-platform's own grading app emits whenever a learner's passing status changes. Event payload field names have shifted across Open edX releases before; the handler logs the raw payload and fails closed (logs + returns) rather than crashing grade processing if a field is ever missing. - Student/instructor pages: the real student dashboard and legacy
instructor dashboard are edx-platform core templates with no supported
third-party injection point (that only exists for the newer React MFEs, a
separate frontend project). Rather than patch core templates, this
plugin serves its own small, self-contained pages under
/certifyme/.... - CertifyMe API contract: confirmed via a real, successful live call
(not a guess) — see
api.py's module docstring for the full detail. In particular:- The working endpoint is the regional one, e.g.
POST https://apac.platform.certifyme.dev/api/v2/credential— seeservers.py. CertifyMe's public API reference documents a generichttps://my.certifyme.online/api/v2/credentialwhich consistently returned500in testing against a real account; the regional URL (matching CertifyMe's own Moodle plugin,local_certifyme) worked. - Auth is the raw API token in the
Authorizationheader (noBearerprefix). template_IDmust be sent as a JSON number, not a string.- No organization-id concept — an account is scoped entirely by its API token + regional server.
- No dedicated course/completion-date field — course data can only reach
the credential via
custom_fields(see Configuration below). - The response does carry a stable id (
credential_UID) and a verification URL (credential_url) — captured ascertificate_id/verification_urlonCertifyMeCertificate. - No badge, revoke, or resend endpoint is confirmed to exist. CertifyMe's
public API reference does document
GET/PUT/DELETEby credential id (retrieve/edit/delete) — not yet implemented here, only issuance.
- The working endpoint is the regional one, e.g.
Installation (Tutor)
-
For local development, bind-mount the plugin so Tutor builds it as an editable install and keeps it live-editable in the container:
tutor mounts add /path/to/openedx-certifyme
For a published release instead, add it to
OPENEDX_EXTRA_PIP_REQUIREMENTS:tutor config save --append OPENEDX_EXTRA_PIP_REQUIREMENTS=openedx-certifyme==<version>
-
Rebuild and restart the images (
openedxfortutor local,openedx-devfortutor dev):tutor images build openedx-dev # or `openedx` for a local/production deploy tutor dev launch # or `tutor local launch`
-
Run migrations (Tutor does this automatically on
launch/init; to run by hand):tutor dev run lms ./manage.py lms migrate openedx_certifyme
-
Make sure a Celery worker for the LMS queue is running (Tutor runs one by default) — automatic issuance depends on it.
-
Verify the plugin loaded: the LMS log should contain
CertifyMe plugin loaded (app=openedx_certifyme, ...), and:curl http://local.edly.io/certifyme/health # {"plugin": "openedx-certifyme", "status": "ok", "version": "0.1.0", "enabled": false}
Configuration
Go to Django admin → CertifyMe Configuration → Add. Every save creates a new versioned row (full change history, nothing is overwritten):
| Field | Purpose |
|---|---|
| Enabled | Master on/off switch for the whole integration |
| Server | Which CertifyMe regional server this account is on (APAC/EU2/US1/Butterfly) |
| API Token | CertifyMe API token (masked in the admin list view) |
| Template ID | CertifyMe credential template ID |
| Text | Free-text label shown on the credential (e.g. job title, organization) |
| Verify mode | Identity-verification mode: None / SSN / Code / Passport Number |
| Verify code | Required by CertifyMe when Verify mode isn't "None" |
| License number | Optional license number to display on the credential |
| Custom fields | One FieldName=value per line, sent as Custom.FieldName. Supports {course_name}, {student_name}, {student_email}, {date} tokens — this is the only way to get the course name onto the credential, e.g. Course={course_name} |
| Auto issue certificates | Issue automatically when a learner passes |
| API timeout / max retries | Tuning for the HTTP client |
There is no "Test connection" action: CertifyMe has no confirmed non-mutating endpoint to check against. Use the instructor tools page's manual Issue Certificate to confirm a token/template pair actually works.
Usage
- Learners:
/certifyme/certificates/lists their certificates, each linking to the CertifyMe-hosted certificate and a local verify page. - Course staff:
/certifyme/instructor/<course_id>/for manual issue, bulk issue, retry, search, and filtering. Requires course staff/instructor role or platform staff. - Support/ops: Django admin → CertifyMe Certificates for a read-only audit log (status, retry count, failure reason, raw API response) across all courses, with a bulk Retry action.
Troubleshooting
- Certificates never get issued: check
EnabledandAuto issue certificatesare both on in the current configuration, and that a Celery worker is consuming the LMS default queue. - "CertifyMe is not configured yet" errors: an API token is required before any API call will be attempted.
- A specific certificate is stuck FAILED: check
failure_reasonon the row (Django admin or instructor tools). A401/403means the API token is wrong; a404means the template ID doesn't exist on the selected server (per CertifyMe's own troubleshooting docs). Permanent failures are not auto-retried — fix the underlying issue, then use the Retry action. - Health check flooding logs: it logs at
DEBUG, notINFO, precisely because liveness probes hit it constantly — raise your log level if you need to see it. - Certificates stuck retrying with a connection/timeout error: a real
successful issuance call was observed taking ~20 seconds (CertifyMe
appears to generate and upload the credential image before responding),
which is why
API timeout / max retriesdefaults to a 30s timeout — if you've lowered it, raise it back up rather than assuming the API is down.
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_certifyme-0.1.0.tar.gz.
File metadata
- Download URL: openedx_certifyme-0.1.0.tar.gz
- Upload date:
- Size: 30.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
116676218c074ae441062df75973d6c8622fd7ffb6160331cc6b9529e5d86762
|
|
| MD5 |
f268b26c9f274a309727e903932429c2
|
|
| BLAKE2b-256 |
6a62332a001e14d764b81e2be71d173293f0db8176a51b3dbff6aaf937d073e2
|
File details
Details for the file openedx_certifyme-0.1.0-py3-none-any.whl.
File metadata
- Download URL: openedx_certifyme-0.1.0-py3-none-any.whl
- Upload date:
- Size: 35.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74672e163255afde4d00372a0fb33040a3d2f3023063b0b0d834cdbd9c158745
|
|
| MD5 |
53e960b333eb9fee4e5a0d24f6e457bc
|
|
| BLAKE2b-256 |
b9b12b0120e03e45931435550c233043e7c83b7137f3b3fa8ba479e44138bcb7
|