Skip to content

strawberry schema-codegen feedback + suggestions #4050

@magicmark

Description

@magicmark

👋 looking into pairing https://strawberry.rocks/docs/codegen/query-codegen and https://github.com/graphql-python/gql

specifically, I want the client application (another python service) to do everything, rather than "generating clientlibs" and maintaining a pipeline for that. (this approach is similar to web clients)

Here's the current workflow

  • download the schema.graphql of the service I want to call from the registry
  • use $ strawberry schema-codegen schema.graphql to generate a schema.py
  • use $ strawberry codegen --schema schema ... to generate operation result files
  • find and replace to add @dataclass to all generated classes
  • use from dataclass_wizard import fromdict to recursively convert the raw dict response into the dataclasses

...which I think works pretty well!

Here's some improvements I'd love to add to add to strawberry to reduce the amount of logic on our side - let me know if you'd be open to some PRs for this!

  1. for $ strawberry codegen, allow a --sdl flag as a (mutually exclusive) alternative to --schema which accepts the schema in SDL format. (Internally, strawberry could still run schema-codegen). This will make it easier for external services and tooling to do codegen, rather than assuming it all happens in the server's codebase.

  2. $ strawberry codegen currently uses the basename of the input file, rather than the name of the query, as the name of the output file. This potentially leads to conflicts when run in parallel if there are two files named get_foo.py but in different locations. An option to use the query name, or arbitrarily specify would be good. Former pairs well with the common rule of "no duplicated query names" within a codebase. This would let us just xargs into the codegen command.

  3. use dataclasses (or ability to specify this) rather than raw classes

  4. add some __post_init__ logic to allow dict unpacking into a dataclass for nested types. This would remove the need to use from dataclass_wizard import fromdict.

    Something like this(?):

    from dataclasses import dataclass
    
    @dataclass
    class ReviewResultUser:
        name: str
    
    @dataclass
    class ReviewResultReview:
        id: str
        author: User
    
        def __post_init__(self):
            if isinstance(self.author, dict):
                self.author = ReviewResultUser(**self.author)
    
    @dataclass
    class ReviewResult:
        review: ReviewResultReview
    
        def __post_init__(self):
            if isinstance(self.review, dict):
                self.review = ReviewResultReview(**self.review)
    
    # raw dict response from https://github.com/graphql-python/gql
    raw_result = {"review": {"id": "123", "author": {"name": "alice"}}}
    
    # parsed into dataclasses generated by strawberry
    result = ReviewResult(**raw_result)

wdyt?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions