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

How to serialize Strawberry models #3565

Open
mecampbellsoup opened this issue Jul 10, 2024 · 4 comments
Open

How to serialize Strawberry models #3565

mecampbellsoup opened this issue Jul 10, 2024 · 4 comments

Comments

@mecampbellsoup
Copy link
Contributor

mecampbellsoup commented Jul 10, 2024

I'm writing some integration tests that use an HTTP client to hit our GQL API like so:

resp = await client.post(
        "/api/",
        headers={"Content-Type": "application/json"},
        json={
            "query": query,
            "variables": {"form": strawberry.asdict(saml_configuration_form)},
        },
    )

In this example, saml_configuration_form is a strawberry input type:

@strawberry.experimental.pydantic.input(model=SAMLConfigurationPyd, all_fields=True)
class SAMLConfigurationForm:
    pass

This gets me halfway there, but strawberry.asdict seems to be limited to snake-casing (or rather, limited to however the fields are cased on the SAMLConfigurationPyd model in this example).

Would it be possible to support something like:

from pydantic.alias_generators import to_camel

strawberry.asdict(saml_configuration_form, alias_generator=to_camel)

That way I can easily inflect the serialized form's keys.

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • We receive the funding once the issue is completed & confirmed by you.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@patrick91
Copy link
Member

@mecampbellsoup I think adding support for (un)snake casing would be nice, but we would need to do via a schema configuration, since that depends on how the schema has been configured 😊

@mecampbellsoup
Copy link
Contributor Author

@mecampbellsoup I think adding support for (un)snake casing would be nice, but we would need to do via a schema configuration, since that depends on how the schema has been configured 😊

What API are you envisioning? (I know I opened the issue so it's rich for me to ask you that but, humor me! 😆)

Then at the object type level might it be configurable similarly to Pydantic's model_config or something?

class StorageClassPyd(PydanticModel):
    model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

@patrick91
Copy link
Member

I was thinking something like this:

@strawberry.input
class Something:
    name: str
    something_else: str

data = Something(name="ABC", something_else="ABC")

strawberry.asdict(data, config={"auto_camel_case": True}) # this would be the same config passed to the schema

but while writing this I realised that asdict wasn't really made for this use case, the camelcase behaviour is something that's done on the schema level most of the time, so maybe we should have something like schema.serialize(data), but I'm not convinced it's a good/useful feature to have.

What's your reasoning behind not passing a dict to your test? 😊

@mecampbellsoup
Copy link
Contributor Author

What's your reasoning behind not passing a dict to your test? 😊

Laziness!

I just thought that this type of camel case to snake case conversion was happening internally quite a bit, since the FE JSON is typically formatted w/ camelCase keys, and all the Python BE types/code tends to assume snake_case, so I was hoping to grok an easy way to replicate that observed behavior.

I like using the strawberry types as a starting point though because that's the "public facing API", so in integration tests passing form data to GQL resolvers, it feels like the right thing (as opposed to e.g. using the Pydantic types).

To your point though, we can pass dictionaries in tests.

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

No branches or pull requests

2 participants