Skip to content

Conversation

@rpenido
Copy link
Contributor

@rpenido rpenido commented Jul 11, 2025

Description

This PR adds support for copying (any container) and pasting (for now, only units) on a course.

  • Which edX user roles will this change impact? "Developer"

Supporting information

Testing instructions

  • To copy a container, you need to make a POST call to http://studio.local.openedx.io:8001/api/libraries/v2/containers/{key}/copy/. You could use a Unit with an HTML component containing some images to test the static file copy.
    Tip: To get it right from your browser, you can rename a container and edit the PATCH URL, changing the method to POST and appending copy/ to the end of the URL.
  • Open the content staging admin and check the generated OLX (http://studio.local.openedx.io:8001/admin/content_staging/stagedcontent/)
  • Currently, the paste UI is only supported for Units. Try to paste a copied unit into a section using the current UI
  • The paste feature sections/subsections works, but you need to edit the paste call to change the parent manually.

Deadline

None


Private ref: FAL-4221

@openedx-webhooks
Copy link

openedx-webhooks commented Jul 11, 2025

Thanks for the pull request, @rpenido!

This repository is currently maintained by @openedx/wg-maintenance-edx-platform.

Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.
🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads
🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

Details
Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Jul 11, 2025
@github-project-automation github-project-automation bot moved this to Needs Triage in Contributions Jul 11, 2025
@rpenido rpenido force-pushed the rpenido/fal-4221/copy-paste-containers branch 5 times, most recently from ae3c3dd to 8da2d48 Compare July 11, 2025 16:07
@mphilbrick211 mphilbrick211 moved this from Needs Triage to Waiting on Author in Contributions Jul 15, 2025
@rpenido rpenido force-pushed the rpenido/fal-4221/copy-paste-containers branch 16 times, most recently from 6fdce69 to e61a47e Compare July 21, 2025 20:42
@rpenido rpenido force-pushed the rpenido/fal-4221/copy-paste-containers branch from e61a47e to 4ee9ce7 Compare July 21, 2025 21:20
Copy link
Contributor

@navinkarkera navinkarkera left a comment

Choose a reason for hiding this comment

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

@rpenido Nice work! It mostly works with some issues like

  • I had to remove these two lines to make copy work with units containing html blocks.
  • And we need to handle static content while copying.

Comment on lines +112 to +113
from openedx.core.djangoapps.content_libraries import api as lib_api

Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason for moving this here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

https://github.com/openedx/edx-platform/blob/47d253a1fee52b76b7dd583e63c0bc8074fb8a7e/openedx/core/djangoapps/content_staging/views.py#L85-L90

We should stop importing the content_libraries here in the future, but we probably need to import the other way around. I moved it here to avoid circular imports.

@rpenido rpenido force-pushed the rpenido/fal-4221/copy-paste-containers branch from 4e705eb to 50de6b0 Compare July 24, 2025 19:28
Copy link
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.

Great work! I think this is almost ready.

rpenido and others added 2 commits August 8, 2025 14:59
Co-authored-by: Braden MacDonald <mail@bradenm.com>
@rpenido rpenido force-pushed the rpenido/fal-4221/copy-paste-containers branch from 07ec126 to 78fca3b Compare August 8, 2025 18:34
@rpenido rpenido force-pushed the rpenido/fal-4221/copy-paste-containers branch from 78fca3b to 9b4efbd Compare August 8, 2025 19:40
@rpenido
Copy link
Contributor Author

rpenido commented Aug 8, 2025

Hi @bradenmacdonald @kdmccormick!

https://github.com/openedx/edx-platform/blob/7c2acdca8416a77b704cdb01da3144a2e1e282fe/openedx/core/djangoapps/content_libraries/tests/test_runtime.py#L110-L113

Adding the source_version to the OLX is breaking #2, as we are publishing a new version, even if the content doesn't change.
Do you think this is a problem?

@bradenmacdonald
Copy link
Contributor

@rpenido If you set write_source_key=False, then that test should continue to pass unchanged, right? I think we should just do that.

Comment on lines 38 to 39
olx.attrib["source_key"] = str(container_key)
olx.attrib["source_version"] = str(container_metadata.draft_version_num)
Copy link
Member

Choose a reason for hiding this comment

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

Sorry for the drive-by comment, but is there a reason not to use the established attributes copied_from_block{_version} and/or upstream{_version} which we use for components that are copy-pasted or linked?

Copy link
Member

Choose a reason for hiding this comment

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

Oh wait, source_key is for the container itself, not for the container it was copied from, right? Sorry, I'm out of the loop, if there's a thread or something where source_key was discussed I'm happy to read through that and catch myself up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry for the drive-by comment, but is there a reason not to use the established attributes copied_from_block{_version}

It could use copied_from_block (instead of souce_key). While working on this, I don't remember finding a copy_from_block in the OLX, but it makes sense since we are using it on the (pasted) XBlock. I was trying to avoid referencing as blocks since these are Containers from libraries.

and/or upstream{_version}, which we use for components that are copy-pasted or linked?
Oh wait, source_key is for the container itself, not for the container it was copied from, right?

Exactly. This serializer is used when copying items from the library, so we probably won't have the upstream field here. But, if we expand the current code that copies from courses to use it, we will probably have both upstream (meaning that the source item is linked to an upstream library item) and souce_key, referencing the items that is being copied.

Sorry, I'm out of the loop, if there's a thread or something where source_key was discussed

I don't think we have had a thorough discussion beyond what we've included in this PR. Please let me know if you have any concerns!

Copy link
Member

Choose a reason for hiding this comment

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

It could use copied_from_block (instead of souce_key). While working on this, I don't remember finding a copy_from_block in the OLX, but it makes sense since we are using it on the (pasted) XBlock. I was trying to avoid referencing as blocks since these are Containers from libraries.

Ah, I see. Currently, copied_from_block is mixed into CMS xblocks, and it is set when pasting an xblock. I agree that it'd be ideal if the field didn't include the word "block" (I wish it were just copied_from) but IMO consistency beats semantic correctness here. So, personally I'd prefer copied_from_block over source_key, but let me know if you disagree.

Exactly. This serializer is used when copying items from the library, so we probably won't have the upstream field here. But, if we expand the current code that copies from courses to use it, we will probably have both upstream (meaning that the source item is linked to an upstream library item) and souce_key, referencing the items that is being copied.

Yes, I think that matches the current behavior, which is:

  • upstream is set iff it's linked to the library
  • copied_from_block is set iff it was pasted without link OR linked and then unlinked.

I don't think we need to set both upstream and copied_from_block at the same time.

@rpenido rpenido force-pushed the rpenido/fal-4221/copy-paste-containers branch 3 times, most recently from 9eabb47 to 9a267ec Compare August 12, 2025 19:16
@rpenido rpenido force-pushed the rpenido/fal-4221/copy-paste-containers branch from 9a267ec to 0754d08 Compare August 12, 2025 19:25
@rpenido rpenido force-pushed the rpenido/fal-4221/copy-paste-containers branch from 0754d08 to 6f1fecc Compare August 12, 2025 19:43
@rpenido
Copy link
Contributor Author

rpenido commented Aug 13, 2025

Hi @bradenmacdonald! Do you think we are ready to merge now?

Copy link
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.

Yep, I think this looks good. Thanks!

if node_copied_from:
_fetch_and_set_upstream_link(node_copied_from, node_copied_version, temp_xblock, user)
elif copied_from_block:
# Use the copied_from_block param only if the copied_from_block from the OLX is not set.
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we explain this slightly more? This says what we're doing but not why.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed this fallback elif here 4f3e0bc

@bradenmacdonald bradenmacdonald merged commit 1a9f6e1 into openedx:master Aug 14, 2025
49 checks passed
@bradenmacdonald bradenmacdonald deleted the rpenido/fal-4221/copy-paste-containers branch August 14, 2025 15:06
@github-project-automation github-project-automation bot moved this from Waiting on Author to Done in Contributions Aug 14, 2025
@edx-pipeline-bot
Copy link
Contributor

2U Release Notice: This PR has been deployed to the edX staging environment in preparation for a release to production.

@edx-pipeline-bot
Copy link
Contributor

2U Release Notice: This PR has been deployed to the edX production environment.

salman2013 pushed a commit to salman2013/edx-platform that referenced this pull request Sep 10, 2025
…penedx#37008)

* feat: copy endpoint for Library Containers

* fix: make source_usage_key optional and removing upstram info for xblock olx

* test: add tests

* refactor: remove unecessary changes to reduce diff

* fix: change assert

* feat: add `write_upstream` field to ContainerSerializer

* fix: remove comment

* refactor: change `source_usage_key` type and more

* fix: try to infer the source version

* fix: InvalidKeyError while copying container with assets

* fix: read source_version from OLX

* fix: remove store check

* fix: change ident

Co-authored-by: Braden MacDonald <mail@bradenm.com>

* feat: fill source_version and make get_component_version_from_block public

* refactor: rename `source_key` to `copied_from_block`

* test: add test to `write_copied_from=false`

* fix: removing unused fallback elif

* fix: remove `copied_from_block` param

---------

Co-authored-by: Braden MacDonald <mail@bradenm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

open-source-contribution PR author is not from Axim or 2U

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

8 participants