diff --git a/fsspec/implementations/http.py b/fsspec/implementations/http.py index 9e5d20203..9699523cf 100644 --- a/fsspec/implementations/http.py +++ b/fsspec/implementations/http.py @@ -522,6 +522,30 @@ async def _isdir(self, path): except (FileNotFoundError, ValueError): return False + async def _pipe_file(self, path, value, mode="overwrite", **kwargs): + """ + Write bytes to a remote file over HTTP. + + Parameters + ---------- + path : str + Target URL where the data should be written + value : bytes + Data to be written + mode : str + How to write to the file - 'overwrite' or 'append' + **kwargs : dict + Additional parameters to pass to the HTTP request + """ + url = self._strip_protocol(path) + headers = kwargs.pop("headers", {}) + headers["Content-Length"] = str(len(value)) + + session = await self.get_session() + + async with session.put(url, data=value, headers=headers, **kwargs) as r: + r.raise_for_status() + class HTTPFile(AbstractBufferedFile): """ diff --git a/fsspec/implementations/tests/test_http.py b/fsspec/implementations/tests/test_http.py index 91b16ce99..b92984827 100644 --- a/fsspec/implementations/tests/test_http.py +++ b/fsspec/implementations/tests/test_http.py @@ -581,3 +581,43 @@ async def test_async_walk(server): pass await fs._session.close() + + +def test_pipe_file(server, tmpdir, reset_files): + """Test that the pipe_file method works correctly.""" + import io + + import fsspec + + # Create test data + test_content = b"This is test data to pipe to a file" + + # Initialize filesystem + fs = fsspec.filesystem("http", headers={"accept_put": "true"}) + + # Test that the file doesn't exist yet + with pytest.raises(FileNotFoundError): + fs.info(server.address + "/piped_file") + + # Pipe data to the file + fs.pipe_file(server.address + "/piped_file", test_content) + + # Verify the file exists now + assert fs.exists(server.address + "/piped_file") + + # Verify content + assert fs.cat(server.address + "/piped_file") == test_content + + # Test with different modes and headers + fs.pipe_file( + server.address + "/piped_file2", + test_content, + mode="overwrite", + headers={"Content-Type": "text/plain"}, + ) + assert fs.cat(server.address + "/piped_file2") == test_content + + # Test with byte-like object + bytesio = io.BytesIO(b"BytesIO content") + fs.pipe_file(server.address + "/piped_bytes", bytesio.getvalue()) + assert fs.cat(server.address + "/piped_bytes") == b"BytesIO content"