Skip to content

Modify create_next_component_version to accept file bytes data #241

Description

@ormsbee

In Learning Core, Content is raw file data with a media type. It has no filename or association to a ComponentVersion by itself. Content is joined to ComponentVersion via the ComponentVersionContent model, which is where the filename is located (as the key field).

This leads to some cumbersome code for callers, like the following for adding a new asset to a component block in edx-platform:

    media_type_str, _encoding = mimetypes.guess_type(file_path)
    # We use "application/octet-stream" as a generic fallback media type, per
    # RFC 2046: https://datatracker.ietf.org/doc/html/rfc2046
    # TODO: This probably makes sense to push down to openedx-learning?
    media_type_str = media_type_str or "application/octet-stream"

    now = datetime.now(tz=timezone.utc)

    with transaction.atomic():
        media_type = authoring_api.get_or_create_media_type(media_type_str)
        content = authoring_api.get_or_create_file_content(
            component.publishable_entity.learning_package.id,
            media_type.id,
            data=file_content,
            created=now,
        )
        component_version = authoring_api.create_next_component_version(
            component.pk,
            content_to_replace={file_path: content.id},
            created=now,
            created_by=user.id if user else None,
        )

If create_next_component_version were instead modified so that the values in content_to_replace could be either integers (the Content id) or bytes, then the above code could look like this:

    with transaction.atomic():
        component_version = authoring_api.create_next_component_version(
            component.pk,
            content_to_replace={file_path: file_content},
            created=datetime.now(tz=timezone.utc),
            created_by=user.id if user else None,
        )

That would allow developers using openedx-learning to add, update, and delete normal assets without having to really think about the underlying data relationship between Content and ComponentVersion–doing the media type guessing and implicit Content lookup/creation would be taken care of by create_next_component_version.

Using Content IDs should still be supported, since we sometimes want fine-grained control over the media type (each XBlock type defines its own), or whether it's backed by a file system or a database field. This ticket is about implementing a small enhancement to create_next_component_version to cover the 90% use case of people wanting to add file-backed content that can rely on the file_path to guess the media type.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions