diff --git a/CHANGELOG.md b/CHANGELOG.md index 42246aa52..7bcde2665 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Structure.conversation_memory_strategy` for setting whether Conversation Memory Runs should be created on a per-Structure or per-Task basis. Default is `Structure.ConversationMemoryStrategy.PER_STRUCTURE`. - `BranchTask` for selecting which Tasks (if any) to run based on a condition. - Support for `BranchTask` in `StructureVisualizer`. +- `BaseFileLoader.save()` method for saving an Artifact to a destination. ### Changed diff --git a/griptape/loaders/base_file_loader.py b/griptape/loaders/base_file_loader.py index 57197f0b6..a42fb30b0 100644 --- a/griptape/loaders/base_file_loader.py +++ b/griptape/loaders/base_file_loader.py @@ -27,3 +27,9 @@ def fetch(self, source: str | PathLike) -> bytes: return data.encode(self.encoding) else: return data + + def save(self, destination: str | PathLike, artifact: A) -> None: + """Saves the Artifact to a destination.""" + data = artifact.value if isinstance(artifact.value, bytes) else artifact.value.encode(self.encoding) + + self.file_manager_driver.save_file(str(destination), data) diff --git a/tests/unit/loaders/test_base_file_loader.py b/tests/unit/loaders/test_base_file_loader.py new file mode 100644 index 000000000..b015f0f14 --- /dev/null +++ b/tests/unit/loaders/test_base_file_loader.py @@ -0,0 +1,37 @@ +import pytest + +from griptape.loaders.text_loader import TextLoader + + +class TestBaseFileLoader: + @pytest.fixture(params=["ascii", "utf-8", None]) + def loader(self, request): + encoding = request.param + if encoding is None: + return TextLoader() + else: + return TextLoader(encoding=encoding) + + @pytest.fixture(params=["path_from_resource_path"]) + def create_source(self, request): + return request.getfixturevalue(request.param) + + def test_fetch(self, loader, create_source): + source = create_source("test.txt") + + data = loader.fetch(source) + + assert data.startswith(b"foobar foobar foobar") + + def test_save(self, loader, create_source): + source = create_source("test.txt") + + data = loader.load(source) + + destination = create_source("test_copy.txt") + + loader.save(destination, data) + + data_copy = loader.load(destination) + + assert data.value == data_copy.value