Open edX Opaque Keys
edx-opaque-keys is a Python library that provides a clear and consistent API for creating and introspecting identifiers (known as opaque keys) for various Open edX objects like courses and XBlocks. The library is currently at version 4.0.0 and is actively maintained with frequent updates, often related to Python requirements and dependency bumps.
Common errors
-
ModuleNotFoundError: No module named 'opaque_keys.locators'
cause Attempting to import deprecated `locators` module which might have been refactored or removed in recent versions.fixUpdate your import statements to use the `opaque_keys.edx.keys` module for specific key types (e.g., `from opaque_keys.edx.keys import CourseKey`). -
AttributeError: 'CourseKey' object has no attribute 'run' (or 'version_agnostic', etc.)
cause Attempting to access attributes or methods that were part of older `Locator` objects or have been refactored/removed from the current `OpaqueKey` subclasses. The internal structure of keys has evolved.fixReview the API documentation for the specific `OpaqueKey` subclass (e.g., `CourseKey`) you are using to understand its current attributes and methods. Many key properties are accessible directly as attributes, but some older helper methods might be deprecated or removed. -
django.core.exceptions.ValidationError: ['"invalid_key_string" is not a valid OpaqueKey.']
cause A string provided to `CourseKey.from_string()` or a `CourseKeyField` in Django is not in the correct opaque key format.fixEnsure that the input string adheres to the expected opaque key format (e.g., `course-v1:Org+Course+Run`). Validate inputs before attempting to convert them to `OpaqueKey` objects.
Warnings
- breaking The `LibraryItemKey` class was removed in version 3.0.0 and replaced by `CollectionKey` and `ContainerKey`. Code using `LibraryItemKey` will break.
- deprecated Several methods and classes, particularly older `Locator` classes and utility methods like `to_deprecated_string()`, are marked as deprecated. They may still function but are subject to removal.
- gotcha Older documentation and blog posts about 'Opaque Keys' can be misleading due to significant changes in the project's architecture and API over its 10+ year lifespan. Concepts like `CourseLocator` were once `CourseKey` and vice versa, leading to confusion.
Install
-
pip install edx-opaque-keys
Imports
- CourseKey
from opaque_keys.locators import CourseLocator
from opaque_keys.edx.keys import CourseKey
- UsageKey
from opaque_keys.locators import BlockUsageLocator
from opaque_keys.edx.keys import UsageKey
- CollectionKey
from opaque_keys.edx.keys import LibraryItemKey
from opaque_keys.edx.keys import CollectionKey
- CourseKeyField
from opaque_keys.edx.django.models import CourseKeyField
Quickstart
from opaque_keys.edx.keys import CourseKey, UsageKey
# Create a CourseKey from a string identifier
course_id_string = "course-v1:OrgX+DemoCourse+2023_T1"
course_key = CourseKey.from_string(course_id_string)
print(f"Parsed CourseKey: {course_key}")
print(f"Organization: {course_key.org}")
print(f"Course: {course_key.course}")
# Create a UsageKey (for an XBlock) associated with the course
usage_key = course_key.make_usage_key("video", "video_id_123")
print(f"Generated UsageKey: {usage_key}")
# Convert key back to string
key_string = str(usage_key)
print(f"UsageKey as string: {key_string}")
# Example with Django model field (conceptual, requires Django setup)
try:
from opaque_keys.edx.django.models import CourseKeyField
# Example of how it would be used in a Django model
# class MyModel(models.Model):
# course_id = CourseKeyField(max_length=255)
print("Django model fields available for integration.")
except ImportError:
print("Django is not installed or Django-specific features are not in use.")