Repository navigation
Conversation
This was referenced Oct 8, 2026
ehennestad
marked this pull request as draft
October 8, 2026 18:24
ehennestad
force-pushed
the
copy-to-checks-source-and-target
branch
from
October 8, 2026 18:57
2f19feb to
0167f6a
Compare
The data-proxy answers 201 to every copy and reports a failure only by email, so copy_to() returned True for a copy of an object that no longer exists, and replaced an object at the destination without warning. copy_to() now raises DoesNotExist when the object is no longer in the bucket, and FileExistsError when the destination object exists, in the same bucket or in dst_bucket, unless overwrite=True. Both checks run before the request. send_success_email is passed to the endpoint and defaults to False; the data-proxy emails about a failed copy either way. This follows DataproxyFile.rename(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The source check runs whether or not overwrite is set, but only the case without overwrite was tested, so moving the check under "if not overwrite" passed every test. The missing-source test now also runs with the destination taken, and with overwrite=True. The stand-in for Bucket.get_file returned MagicMock(name=name), which names the mock rather than setting its name attribute; it now returns a SimpleNamespace with that name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ehennestad
force-pushed
the
copy-to-checks-source-and-target
branch
from
October 9, 2026 18:52
0167f6a to
612d578
Compare
ehennestad
marked this pull request as ready for review
October 9, 2026 18:56
ehennestad
added a commit
to ehennestad/EBRAINS-MATLAB
that referenced
this pull request
Nov 3, 2026
…he request (#90) The Data Proxy copies an object within the object store through `PUT /v1/buckets/{bucket}/{object}/copy?name=<target>`. `BucketsClient` gets a `copyObject` method for it and the namespace an `ebrains.bucket.copyObject` function, next to `renameObject`. A folder is copied with everything in it when both names end with `/`. The copy endpoint takes the name as one percent-encoded path segment. A folder name ends with `/`, and sent as path segments the request path holds `folder//copy`; the proxy collapses the double slash before it reads the name, copies a single object that does not exist, and reports the failure only by mail, as described in HumanBrainProject/ebrains-storage#60. The other endpoints keep the path segments, since the signed temporary URLs they return need real separators. Rename and copy answer `201 "Your copy is processing"` and complete in the background, and a failed operation is reported only by mail. Both functions therefore check that the source exists (`EBRAINS:Bucket:ObjectNotFound`) and that the target is free (`EBRAINS:Bucket:TargetExists`) before the request, with `Overwrite=true` to replace the target. Both pass `send_success_email=false` unless `SendSuccessEmail=true`. Before this change the rename required a 200, so it threw on every rename the proxy accepted, and each rename mailed the account. The options and defaults follow `DataproxyFile.rename()` and `copy_to()` in ebrains-storage (HumanBrainProject/ebrains-storage#55, HumanBrainProject/ebrains-storage#63). The live tests gain a folder copy, a single-object copy and a rename, each polling the listing until the proxy has completed the operation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The data-proxy copy endpoint answers 201 "Your copy is processing" to every request and completes the copy in the background. A copy that fails is reported only by email. I checked two cases on a production bucket: a copy of an object that no longer exists gets 201, creates nothing, and is reported by email, and a copy onto an existing object replaces it without warning. So
copy_to()returnedTruefor a copy that never happens, and replaced an object at the destination silently.copy_to(dst_name=None, *, dst_bucket=None, overwrite=False, send_success_email=False)now checks before the request:DoesNotExistif not;FileExistsErrorif one does, unlessoverwrite=True. The destination isdst_bucketwhen given, and the object's own bucket otherwise.Neither check sends the copy request, so a rejected copy produces no email.
send_success_emailis passed to the endpoint and defaults toFalse. The data-proxy emails about a failed copy either way. This follows the review ofDataproxyFile.rename()in #55, so both methods behave the same.Before this change,
copy_toreplaced an existing destination object without warning. In 0.7.0 every call raisedClientHttpError(#57), even though the copy was made, so released code is unlikely to depend on that behaviour. Code that caught the error and relied on the overwrite would now getFileExistsErrorand needoverwrite=True.The tests cover a copy within the bucket and to another bucket, a missing source with the destination free, taken, and with
overwrite=True, an existing destination in the same bucket and in another bucket, andoverwrite=True. The checks that reject a copy also assert that no request was sent. The tests from #58 that run a realBucketApiClientagainst 200, 201 and 403 replies are kept, withBucket.get_filestubbed for the new checks. The "Copy File" section ofdoc.mddescribes the new arguments and exceptions.Fixes #56
🤖 Generated with Claude Code