Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JsonArtifact #937

Merged
merged 5 commits into from
Aug 15, 2024
Merged

Add JsonArtifact #937

merged 5 commits into from
Aug 15, 2024

Conversation

vachillo
Copy link
Member

@vachillo vachillo commented Jul 3, 2024

Describe your changes

  • adding JsonArtifact for de/serializing values automatically

Issue ticket number and link

closes #935


📚 Documentation preview 📚: https://griptape--937.org.readthedocs.build//937/

Copy link

codecov bot commented Jul 3, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

📢 Thoughts on this report? Let us know!

@collindutter
Copy link
Member

Could you throw in a JsonLoader to knock out #439?


@property
def value(self) -> Any:
return json.loads(self.value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The codecov warning here seems worth testing.

pyproject.toml Outdated
@@ -28,6 +28,7 @@ stringcase = "^1.2.0"
docker = "^7.1.0"
sqlalchemy = "~=1.0"
requests = "^2.32.0"
jsonalias = "^0.1.2"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is even worth including since its usage is so limited. Can you just include the type in JsonArtifact?

def test_value_type_conversion(self):
assert JsonArtifact({"foo": "bar"}).value == json.loads(json.dumps({"foo": "bar"}))
string = json.dumps({"foo": {}})
print(string)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove

string = json.dumps({"foo": {}})
print(string)
string = json.loads(string)
print(string)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove

@vachillo vachillo marked this pull request as draft July 4, 2024 17:23
@vachillo vachillo force-pushed the json_artifact branch 2 times, most recently from 9782878 to 6c894d9 Compare August 15, 2024 16:13
@vachillo vachillo marked this pull request as ready for review August 15, 2024 16:33
@@ -58,3 +58,7 @@ A [BooleanArtifact](../../reference/griptape/artifacts/boolean_artifact.md) is u
A [GenericArtifact](../../reference/griptape/artifacts/generic_artifact.md) can be used as an escape hatch for passing any type of data around the framework.
It is generally not recommended to use this Artifact type, but it can be used in a handful of situations where no other Artifact type fits the data being passed.
See [talking to a video](../../examples/talk-to-a-video.md) for an example of using a `GenericArtifact` to pass a Gemini-specific video file.

## JsonArtifact
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Header should just be Json

@define
class JsonArtifact(BaseArtifact):
_obj: Any = field(metadata={"serializable": True}, alias="obj")
value: dict = field(init=False, metadata={"serializable": True})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be value: Json?

def __attrs_post_init__(self) -> None:
if self._obj is None:
self._obj = {}
self._json_str = json.dumps(self._obj)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need a field for this? Can we just dumps in to_text?


@define
class JsonArtifact(BaseArtifact):
_obj: Any = field(metadata={"serializable": True}, alias="obj")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this field provide?

Copy link
Member Author

@vachillo vachillo Aug 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is just the original object being converted. different than value. consistent with json.dumps signature.

Comment on lines 1 to 25
import json

import pytest

from griptape.artifacts import JsonArtifact, TextArtifact


class TestJsonArtifact:
def test_value_type_conversion(self):
assert JsonArtifact({"foo": "bar"}).value == json.loads(json.dumps({"foo": "bar"}))

def test___add__(self):
assert (JsonArtifact({"foo": "bar"}) + JsonArtifact({"value": "baz"})).value == JsonArtifact(
{"foo": "bar", "value": "baz"}
).value

new = JsonArtifact({"foo": "bar"}) + JsonArtifact({"value": "baz"})
assert new.value == {"foo": "bar", "value": "baz"}

assert (JsonArtifact({"foo": "bar"}) + JsonArtifact({"foo": "baz"})).value == JsonArtifact({"foo": "baz"}).value
with pytest.raises(ValueError):
JsonArtifact({"foo": "bar"}) + TextArtifact("invalid json")

def test_to_text(self):
assert JsonArtifact({"foo": "bar"}).to_text() == json.dumps({"foo": "bar"})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add tests for all the types that Json can be? dict[str, "Json"], list["Json"], str, int, float, bool, None

@vachillo vachillo requested a review from collindutter August 15, 2024 16:52
collindutter
collindutter previously approved these changes Aug 15, 2024
@collindutter collindutter merged commit 714109b into dev Aug 15, 2024
13 checks passed
@collindutter collindutter deleted the json_artifact branch August 15, 2024 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add JsonArtifact
2 participants