Copy an S3 object to another S3 location. Performs server-side copy of S3 objects, which is more efficient than downloading and re-uploading. Automatically chooses between simple copy and multipart copy based on object size. Args: path1: Source S3 path (
(
self, path1: str, path2: str, recursive=False, maxdepth=None, on_error=None, **kwargs
)
| 989 | return object_.to_dict() |
| 990 | |
| 991 | def cp_file( |
| 992 | self, path1: str, path2: str, recursive=False, maxdepth=None, on_error=None, **kwargs |
| 993 | ): |
| 994 | """Copy an S3 object to another S3 location. |
| 995 | |
| 996 | Performs server-side copy of S3 objects, which is more efficient than |
| 997 | downloading and re-uploading. Automatically chooses between simple copy |
| 998 | and multipart copy based on object size. |
| 999 | |
| 1000 | Args: |
| 1001 | path1: Source S3 path (s3://bucket/key). |
| 1002 | path2: Destination S3 path (s3://bucket/key). |
| 1003 | recursive: Unused parameter for fsspec compatibility. |
| 1004 | maxdepth: Unused parameter for fsspec compatibility. |
| 1005 | on_error: Unused parameter for fsspec compatibility. |
| 1006 | **kwargs: Additional S3 copy parameters (e.g., metadata, storage class). |
| 1007 | |
| 1008 | Raises: |
| 1009 | ValueError: If trying to copy to a versioned file or copy buckets. |
| 1010 | |
| 1011 | Note: |
| 1012 | Uses multipart copy for objects larger than the maximum part size |
| 1013 | to optimize performance for large files. The copy operation is |
| 1014 | performed entirely on the S3 service without data transfer. |
| 1015 | """ |
| 1016 | # fsspec < 2026.6.0: AbstractFileSystem.mv() passed the typo'd |
| 1017 | # "onerror" keyword (instead of "on_error", which copy() consumes), |
| 1018 | # so it leaked through copy(**kwargs) into cp_file and must not |
| 1019 | # reach the S3 API. Remove this once the fsspec requirement is |
| 1020 | # >= 2026.6.0, where mv() passes on_error correctly. |
| 1021 | # https://github.com/fsspec/filesystem_spec/commit/346a589fef9308550ffa3d0d510f2db67281bb05 |
| 1022 | kwargs.pop("onerror", None) |
| 1023 | bucket1, key1, version_id1 = self.parse_path(path1) |
| 1024 | bucket2, key2, version_id2 = self.parse_path(path2) |
| 1025 | if version_id2: |
| 1026 | raise ValueError("Cannot copy to a versioned file.") |
| 1027 | if not key1 or not key2: |
| 1028 | raise ValueError("Cannot copy buckets.") |
| 1029 | |
| 1030 | info1 = self.info(path1) |
| 1031 | size1 = info1.get("size", 0) |
| 1032 | if size1 <= self.MULTIPART_UPLOAD_MAX_PART_SIZE: |
| 1033 | self._copy_object( |
| 1034 | bucket1=bucket1, |
| 1035 | key1=key1, |
| 1036 | version_id1=version_id1, |
| 1037 | bucket2=bucket2, |
| 1038 | key2=key2, |
| 1039 | **kwargs, |
| 1040 | ) |
| 1041 | else: |
| 1042 | self._copy_object_with_multipart_upload( |
| 1043 | bucket1=bucket1, |
| 1044 | key1=key1, |
| 1045 | version_id1=version_id1, |
| 1046 | size1=size1, |
| 1047 | bucket2=bucket2, |
| 1048 | key2=key2, |