Skip to content

feat!: Package and Entity keys are now opaque refs#546

Merged
kdmccormick merged 3 commits intomainfrom
kdmccormick/keys-ref
Apr 21, 2026
Merged

feat!: Package and Entity keys are now opaque refs#546
kdmccormick merged 3 commits intomainfrom
kdmccormick/keys-ref

Conversation

@kdmccormick
Copy link
Copy Markdown
Member

@kdmccormick kdmccormick commented Apr 15, 2026

Description

The {LearningPackage,PublishableEntity}.key fields were always meant to be externally-supplied refs whose format does not matter. However, they were effectively being used as parseable psuedo-keys for identifying containers and components, with more assumptions to their structure being baked in over time, both within and outside openedx-core.

This commit renames them to {package,entity}_ref, and removes all parsing of them from the API and from the internals (except for where required for backcompat with Ulmo ZIP backups). Instead, the pairings of (component_type,component_code) and (container_type,container_code) are used to identify components and containers; their respective entity_refs are derived from those by convention but the publishing app has no conception of this convention.

BREAKING CHANGES to openedx_django_lib:

  • Renamed key_field(...) -> ref_field(...) in openedx_django_lib.

BREAKING CHANGES to models API:

  • Renamed field LearningPackage.key -> LearningPackage.package_ref.
  • Renamed field PublishableEntity.key -> PublishableEntityKey.entity_ref
  • Renamed field PublishableEntityMixin.key -> PublishableEntityMixin.entity_ref
  • Renamed property PublishableEntityVersion.key -> PublishableEntityVersion.entity_ref

BREAKING CHANGES to publishing API:

  • In create_learning_package(...), renamed param key -> package_ref
  • In update_learning_package(...), renamed param key -> package_ref
  • In learning_package_exists(...), renamed param key -> package_ref
  • In create_publishable_entity(...), renamed param key -> entity_ref
  • Renamed get_publishable_entity_by_key(...) -> get_publishable_entity_by_ref(...), and renamed param key -> entity_ref
  • Renamed get_learning_package_by_key(...) -> get_learning_package_by_ref(...), and renamed param key -> package_ref

BREAKING CHANGES to components APIs:

  • Removed function get_or_create_component_type_by_entity_key()

BREAKING CHANGES to container APIs:

  • Renamed get_container_by_key(...) -> get_container_by_code(...), and renamed param key -> container_code
  • Rename get_container_children_entities_keys(...) -> get_container_children_entity_refs(...)
  • Renamed get_container_children_entities_keys(...) -> get_container_children_entity_refs(...)

BREAKING CHANGES to collections API:

  • In get_entity_collections(...), renamed param entity_key -> entity_ref

BREAKING CHANGES to media API:

  • In look_up_component_version_media(...):
    • Renamed param learning_package_key -> learning_package_ref
    • Renamed param component_key -> entity_ref
  • In add_assets_to_component management command:
    • Renamed argument learning_package_key -> learning_package_ref
    • Renamed argument component_key -> entity_ref

BREAKING CHANGES to backup_restore API:

  • BREAKING CHANGE In load_learning_package:
    • Renamed param key -> package_ref
    • In return dict, within sub-dict ["lp_restored_data"]:
      • Renamed ["key"] -> ["package_ref"]
      • Renamed ["archive_lp_key"] -> ["archive_package_ref"]
      • Renamed ["archive_org_key"] -> ["archive_org_code"]
      • Renamed ["archive_slug"] -> ["archive_package_code"]
    • If archive_package_ref cannot be parsed into "{_prefix}:{org_code}:{package_code}", then archvie_org_code and archive_package_code will both be None. Callers should handle this case. (Previously, a ValueError would be raised by backup-restore code.)

Backup-restore still write and reads entity_ref and package_ref to/from TOML files as key
for backwards compatibility. This may change in a future "v2" restore format.

Part of: #322

Full series of PRs:

  1. feat!: Collection.key -> Collection.collection_code #542
  2. feat!: Component.local_key -> Component.component_code #544
  3. feat!: Add Container.container_code field #545
  4. feat!: Package and Entity keys are now opaque refs #546
  5. feat!: ComponentVersionMedia.key -> ComponentVersionMedia.path #547

Testing, AI Usage, and Merge Considerations

See #322

Comment thread src/openedx_content/applets/subsections/api.py Outdated
@kdmccormick kdmccormick force-pushed the kdmccormick/keys-container branch from 266d7f3 to 5283857 Compare April 16, 2026 20:47
@kdmccormick kdmccormick force-pushed the kdmccormick/keys-ref branch from 52fe205 to b9d11db Compare April 16, 2026 20:48
@kdmccormick kdmccormick force-pushed the kdmccormick/keys-container branch 2 times, most recently from c32f78c to 94bd0e5 Compare April 17, 2026 16:36
@kdmccormick kdmccormick force-pushed the kdmccormick/keys-ref branch from 09bbd04 to 3f23389 Compare April 17, 2026 16:43
@kdmccormick kdmccormick force-pushed the kdmccormick/keys-container branch from 8434cbf to 64f0eeb Compare April 17, 2026 16:56
@kdmccormick kdmccormick force-pushed the kdmccormick/keys-ref branch from 29580c7 to 3a446d5 Compare April 17, 2026 17:01
@kdmccormick kdmccormick marked this pull request as ready for review April 17, 2026 17:58
@kdmccormick kdmccormick force-pushed the kdmccormick/keys-ref branch from fd76848 to 28197b9 Compare April 17, 2026 18:27
@kdmccormick kdmccormick force-pushed the kdmccormick/keys-container branch from 64f0eeb to f67afa4 Compare April 17, 2026 18:47
@kdmccormick kdmccormick force-pushed the kdmccormick/keys-ref branch from 28197b9 to 9d0ed28 Compare April 17, 2026 18:48
Comment thread src/openedx_content/applets/components/api.py Outdated
Comment thread src/openedx_content/applets/containers/api.py
Comment thread src/openedx_content/applets/components/admin.py Outdated
@kdmccormick kdmccormick force-pushed the kdmccormick/keys-container branch from f67afa4 to ed3aadc Compare April 20, 2026 18:50
Base automatically changed from kdmccormick/keys-container to main April 20, 2026 21:32
@kdmccormick kdmccormick force-pushed the kdmccormick/keys-ref branch from 9d0ed28 to f5e419d Compare April 21, 2026 13:23
@kdmccormick
Copy link
Copy Markdown
Member Author

kdmccormick commented Apr 21, 2026

This is almost ready, but I'm still wrestling with translation between the backup-restore terms (keys) and the model terms (refs).

EDIT: It's all ready now.

The `{LearningPackage,PublishableEntity}.key` fields were always meant to be
externally-supplied refs whose format does not matter. However, they were
effectively being used as parseable psuedo-keys for identifying containers and
components, with more assumptions to their structure being baked in over time,
both within and outside openedx-core.

This commit renames them to `{package,entity}_ref`, and removes all parsing of
them from the API and from the internals (except for where required for
backcompat with Ulmo ZIP backups). Instead, the pairings of
(component_type,component_code) and (container_type,container_code) are used to
identify components and containers; their respective entity_refs are derived
from those *by convention* but the publishing app has no conception of this
convention.

BREAKING CHANGES to **openedx_django_lib**:
* Renamed key_field(...) -> ref_field(...) in openedx_django_lib.

BREAKING CHANGES to **models** API:
* Renamed field LearningPackage.key -> LearningPackage.package_ref.
* Renamed field PublishableEntity.key -> PublishableEntityKey.entity_ref
* Renamed field PublishableEntityMixin.key -> PublishableEntityMixin.entity_ref
* Renamed property PublishableEntityVersion.key -> PublishableEntityVersion.entity_ref

BREAKING CHANGES to **publishing** API:
* In create_learning_package(...), renamed param key -> package_ref
* In update_learning_package(...), renamed param key -> package_ref
* In learning_package_exists(...), renamed param key -> package_ref
* In create_publishable_entity(...), renamed param key -> entity_ref
* Renamed get_publishable_entity_by_key(...) -> get_publishable_entity_by_ref(...),
  and renamed param key -> entity_ref
* Renamed get_learning_package_by_key(...) -> get_learning_package_by_ref(...),
  and renamed param key -> package_ref

BREAKING CHANGES to **components** APIs:
* Removed function get_or_create_component_type_by_entity_key()

BREAKING CHANGES to **container** APIs:
* Renamed get_container_by_key(...) -> get_container_by_code(...),
  and renamed param key -> container_code
* Rename get_container_children_entities_keys(...) -> get_container_children_entity_refs(...)
* Renamed get_container_children_entities_keys(...) -> get_container_children_entity_refs(...)

BREAKING CHANGES to **collections** API:
* In get_entity_collections(...), renamed param entity_key -> entity_ref

BREAKING CHANGES to **media** API:
* In look_up_component_version_media(...):
  * Renamed param learning_package_key -> learning_package_ref
  * Renamed param component_key -> entity_ref
* In add_assets_to_component management command:
  * Renamed argument learning_package_key -> learning_package_ref
  * Renamed argument component_key -> entity_ref

BREAKING CHANGES to **backup_restore** API:
* In load_learning_package(...):
  * Renamed  param key -> package_ref
  * In return dict, within sub-dict ["lp_restored_data"]:
    * Renamed ["key"] -> ["package_ref"]
    * Renamed ["archive_lp_key"] -> ["archive_package_ref"]
    * Renamed ["archive_org_key"] -> ["archive_org_code"]
    * Renamed ["archive_slug"] -> ["archive_package_code"]
  * If archive_package_ref cannot be parsed into
    "{_prefix}:{org_code}:{package_code}", then archvie_org_code and
    archive_package_code will both be None. Callers should handle this case.
    (Previously, a ValueError would be raised by backup-restore code.)

Backup-restore still write and reads entity_ref and package_ref to/from TOML files as `key`
for backwards compatibility. This may change in a future "v2" restore format.

Part of: #322

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@bradenmacdonald bradenmacdonald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read through the code and it looks great. Some very minor suggestions.
I did not test anything, but can do so when the platform PR is ready if you'd like.

Comment thread tests/openedx_content/applets/backup_restore/test_restore.py Outdated
Comment thread src/openedx_content/applets/backup_restore/zipper.py Outdated
Comment thread src/openedx_content/applets/backup_restore/zipper.py
Comment thread src/openedx_content/applets/backup_restore/zipper.py Outdated
kdmccormick and others added 2 commits April 21, 2026 12:45
Co-authored-by: Braden MacDonald <braden@opencraft.com>
@kdmccormick kdmccormick enabled auto-merge (squash) April 21, 2026 16:49
@kdmccormick kdmccormick merged commit 5d4fbf4 into main Apr 21, 2026
6 checks passed
@kdmccormick kdmccormick deleted the kdmccormick/keys-ref branch April 21, 2026 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants