{"id":8971,"library":"edx-opaque-keys","title":"Open edX Opaque Keys","description":"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.","status":"active","version":"4.0.0","language":"en","source_language":"en","source_url":"https://github.com/openedx/opaque-keys","tags":["openedx","keys","identifiers","xblock","django","courseware"],"install":[{"cmd":"pip install edx-opaque-keys","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Used for MongoDB interactions when dealing with persistent keys.","package":"pymongo","optional":false},{"reason":"Plugin loading library, likely used for extensible key handling.","package":"stevedore","optional":false},{"reason":"Provides backported type hints for compatibility across Python versions.","package":"typing-extensions","optional":false}],"imports":[{"note":"Old 'locators' module is deprecated; use 'edx.keys' for specific key types. While CourseLocator might still exist for compatibility in older versions, CourseKey is the preferred direct import for courses.","wrong":"from opaque_keys.locators import CourseLocator","symbol":"CourseKey","correct":"from opaque_keys.edx.keys import CourseKey"},{"note":"Similar to CourseKey, BlockUsageLocator is an older concept. UsageKey is the direct opaque key for XBlock usages.","wrong":"from opaque_keys.locators import BlockUsageLocator","symbol":"UsageKey","correct":"from opaque_keys.edx.keys import UsageKey"},{"note":"In version 3.0.0 and later, LibraryItemKey was removed and replaced by CollectionKey and ContainerKey.","wrong":"from opaque_keys.edx.keys import LibraryItemKey","symbol":"CollectionKey","correct":"from opaque_keys.edx.keys import CollectionKey"},{"note":"This provides a Django model field for storing CourseKey instances.","symbol":"CourseKeyField","correct":"from opaque_keys.edx.django.models import CourseKeyField"}],"quickstart":{"code":"from opaque_keys.edx.keys import CourseKey, UsageKey\n\n# Create a CourseKey from a string identifier\ncourse_id_string = \"course-v1:OrgX+DemoCourse+2023_T1\"\ncourse_key = CourseKey.from_string(course_id_string)\nprint(f\"Parsed CourseKey: {course_key}\")\nprint(f\"Organization: {course_key.org}\")\nprint(f\"Course: {course_key.course}\")\n\n# Create a UsageKey (for an XBlock) associated with the course\nusage_key = course_key.make_usage_key(\"video\", \"video_id_123\")\nprint(f\"Generated UsageKey: {usage_key}\")\n\n# Convert key back to string\nkey_string = str(usage_key)\nprint(f\"UsageKey as string: {key_string}\")\n\n# Example with Django model field (conceptual, requires Django setup)\ntry:\n    from opaque_keys.edx.django.models import CourseKeyField\n    # Example of how it would be used in a Django model\n    # class MyModel(models.Model):\n    #     course_id = CourseKeyField(max_length=255)\n    print(\"Django model fields available for integration.\")\nexcept ImportError:\n    print(\"Django is not installed or Django-specific features are not in use.\")\n","lang":"python","description":"This quickstart demonstrates how to create `CourseKey` and `UsageKey` objects from string identifiers and how to extract their components. It also shows how to generate a `UsageKey` from a `CourseKey` and convert keys back to their string representations. A conceptual example for Django model fields is also included."},"warnings":[{"fix":"Migrate usage of `LibraryItemKey` to `CollectionKey` or `ContainerKey` as appropriate for your data structure. Review the 3.0.0 changelog for details on the new classes.","message":"The `LibraryItemKey` class was removed in version 3.0.0 and replaced by `CollectionKey` and `ContainerKey`. Code using `LibraryItemKey` will break.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Avoid using classes directly from `opaque_keys.locators` and instead prefer specific key types from `opaque_keys.edx.keys`. For string conversion, use `str(key)` or `unicode(key)` where appropriate instead of `to_deprecated_string()`.","message":"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.","severity":"deprecated","affected_versions":"All versions (deprecation warnings may appear in logs)"},{"fix":"Always refer to the official `edx-opaque-keys` GitHub repository and its docstrings for the most up-to-date and accurate API usage. Prioritize documentation generated from the current codebase.","message":"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.","severity":"gotcha","affected_versions":"All versions, when consulting old resources"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Update your import statements to use the `opaque_keys.edx.keys` module for specific key types (e.g., `from opaque_keys.edx.keys import CourseKey`).","cause":"Attempting to import deprecated `locators` module which might have been refactored or removed in recent versions.","error":"ModuleNotFoundError: No module named 'opaque_keys.locators'"},{"fix":"Review 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.","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.","error":"AttributeError: 'CourseKey' object has no attribute 'run' (or 'version_agnostic', etc.)"},{"fix":"Ensure 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.","cause":"A string provided to `CourseKey.from_string()` or a `CourseKeyField` in Django is not in the correct opaque key format.","error":"django.core.exceptions.ValidationError: ['\"invalid_key_string\" is not a valid OpaqueKey.']"}]}