Write bytes into the path. Writes data up to the block size with a single PutObject request instead of the inherited ``open()`` + ``write()`` path. Larger data and writes inside an fsspec transaction go through the buffered path, which uploads the data as a parallel
(
self, path: str, value: bytes | bytearray | memoryview, mode: str = "overwrite", **kwargs
)
| 1136 | ) |
| 1137 | |
| 1138 | def pipe_file( |
| 1139 | self, path: str, value: bytes | bytearray | memoryview, mode: str = "overwrite", **kwargs |
| 1140 | ) -> None: |
| 1141 | """Write bytes into the path. |
| 1142 | |
| 1143 | Writes data up to the block size with a single PutObject request |
| 1144 | instead of the inherited ``open()`` + ``write()`` path. Larger data |
| 1145 | and writes inside an fsspec transaction go through the buffered |
| 1146 | path, which uploads the data as a parallel multipart upload and |
| 1147 | keeps the deferred-commit semantics of transactions. |
| 1148 | |
| 1149 | Args: |
| 1150 | path: S3 path (s3://bucket/key) to write to. |
| 1151 | value: The bytes to write. |
| 1152 | mode: "overwrite" (default) or "create". With "create", raise |
| 1153 | FileExistsError when the object already exists. |
| 1154 | **kwargs: Additional parameters passed to the PutObject API |
| 1155 | (e.g., ContentType, StorageClass) on the single-request |
| 1156 | path. The ``block_size``, ``max_worker``, and |
| 1157 | ``s3_additional_kwargs`` parameters of the ``open()`` path |
| 1158 | are also accepted. |
| 1159 | |
| 1160 | Raises: |
| 1161 | FileExistsError: If the mode is "create" and the path already |
| 1162 | exists. |
| 1163 | ValueError: If the path does not contain a key or specifies a |
| 1164 | version. |
| 1165 | """ |
| 1166 | block_size = kwargs.get("block_size") or self.default_block_size |
| 1167 | if self._intrans or len(value) > min(block_size, self.MULTIPART_UPLOAD_MAX_PART_SIZE): |
| 1168 | # Defer to the buffered open() path, which keeps the |
| 1169 | # deferred-commit semantics of fsspec transactions and uploads |
| 1170 | # large data as a parallel multipart upload. |
| 1171 | super().pipe_file(path, value, mode=mode, **kwargs) |
| 1172 | return |
| 1173 | bucket, key, version_id = self.parse_path(path) |
| 1174 | if version_id: |
| 1175 | raise ValueError("Cannot write to the file with the version specified.") |
| 1176 | if not key: |
| 1177 | raise ValueError("Cannot write to a bucket.") |
| 1178 | if mode == "create" and self.exists(path): |
| 1179 | raise FileExistsError(path) |
| 1180 | if not isinstance(value, bytes): |
| 1181 | # Accept bytes-like values (bytearray, memoryview) as the |
| 1182 | # buffered path does. |
| 1183 | value = bytes(value) |
| 1184 | |
| 1185 | kwargs.pop("block_size", None) |
| 1186 | kwargs.pop("max_worker", None) |
| 1187 | request_kwargs = { |
| 1188 | **self.s3_additional_kwargs, |
| 1189 | **kwargs.pop("s3_additional_kwargs", {}), |
| 1190 | **kwargs, |
| 1191 | } |
| 1192 | self._put_object(bucket=bucket, key=key, body=value, **request_kwargs) |
| 1193 | self.invalidate_cache(path) |
| 1194 | |
| 1195 | def _finish_multipart_upload( |