Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify create_next_component_version to accept file bytes data #241

Open
ormsbee opened this issue Oct 12, 2024 · 0 comments · May be fixed by #248 or openedx/edx-platform#35730
Open

Modify create_next_component_version to accept file bytes data #241

ormsbee opened this issue Oct 12, 2024 · 0 comments · May be fixed by #248 or openedx/edx-platform#35730
Assignees

Comments

@ormsbee
Copy link
Contributor

ormsbee commented Oct 12, 2024

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.

@ormsbee ormsbee changed the title More convenient file creation APIs Modify create_next_component_version to accept file bytes data Oct 25, 2024
@Ian2012 Ian2012 self-assigned this Oct 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Progress
2 participants