Package: qenerate-custom
Fork of qenerateYou're probably not looking for this package.
Original:https://github.com/app-sre/qenerateChangesPutDEFINITIONin generated fragment files tooAllow fields withskiporincludeto be omitted from the query responseqenerateqenerateis a pluggable code generator for GraphQL Query and Fragment Data Classes.
It works hand in hand with GraphQL clients likegql.
Clients like gql return nested untyped dictionaries as result to a query.qenerategenerated classes easily transform these nested untyped dictionaries into concrete classes.qenerateitself is not a GraphQL client and solely focuses on generating code
for transforming untyped dictionaries into concrete types.InstallationReleasesare published on pypi.pipinstallqenerateUsageIntrospectionIn a first step we must obtain the GQL schema in the form of an introspection query:qenerateintrospectionhttp://my-gql-instance:4000/graphql>introspection.jsonTheintrospection.jsonis used in a next step to map concrete types to your queries and fragments.Code Generationqeneratecode-iintrospection.jsondir/to/gql/filesAnintrospection.jsonand a (nested) directory holding all your*.gqlfiles are given.qeneratethen generates data classes for every*.gqlfile it encounters
while traversing the given directory.qenerateexpects that a.gqlfile contains exactly onequery,mutationorfragmentdefinition.Note, that the given directory and everygql.file in it share the same scope.
I.e., within this scope fragment and query names must be unique. Further, you can
freely use any fragment within queries, as long as the fragment is defined somewhere
within the scope (directory).Example for Single QuerySingle queryand itsgenerated classes.Example for Query using a FragmentWe define a re-usablefragmentwhich results in the following
generatedre-usable data classes.The fragment is used in aqueryand imported
in thegenerated python file.More Examplesqenerateis actively used in our qontract-reconcile project. There you can find a lot ofexampleson how generated classes look like in more detail.Pluginsqeneratefollows a plugin based approach. I.e., multiple code generators are supported.
Choosing a code generator is done inside the query file, e.g., the following example will
generate data classes using thepydantic_v1plugin:# qenerate: plugin=pydantic_v1query{...}By choosing a plugin based approach,qeneratecan extent its feature set creating new plugins
while at the same time keeping existing plugins stable and fully backwards compatible.Currently available plugins are:pydantic_v1for generatingPydanticdata classesFeature Flagsqenerateleverages feature flags to configure the behavior of the generator. Feature flags are passed to
the generator via comments in your .gql definition file.Plugin# qenerate: plugin=<plugin-id>This feature flag tellsqeneratewhich plugin it should use to generate the code for the given definition.Custom Type MappingYou can tell qenerate to map a primitive GQL type (a.k.a. Scalar) to something that you want. This can be handy if your codebase expects other primitive datatypes like, e.g.,strinstead ofJsonordatetime. This can be especially useful for custom GQL primitives.# qenerate: map_gql_scalar=JSON -> strThe above will tell qenerate to map the GQLJSONtype tostrinstead of pydantic'sJson. You can also map multiple types, e.g.,# qenerate: map_gql_scalar=JSON -> str# qenerate: map_gql_scalar=DateTime -> strNaming Collision Strategy# qenerate: naming_collision_strategy=[PARENT_CONTEXT | ENUMERATE]This feature flag tellsqeneratehow to deal with naming collisions in classes.
In GraphQL it is easy to query the same object in a nested fashion, which results
in re-definitions of the type. We call this naming collision. A naming collision
strategy defines how to adjust recurring names to make them unique.PARENT_CONTEXTThis is the default strategy if nothing else is specified. It uses the name of the
parent node in the query as a prefix.ENUMERATEThis strategy adds the number of occurrences of this name as a suffix.However, in most cases it might be cleaner to define a re-usable fragment instead of
relying on a collision strategy. Here are somefragment examples.LimitationsOverlapping propertiesAs of nowqeneratedoes not support operations with overlapping properties. E.g.,fragmentMyFragmentonNamespace{b{ef}}queryMyQuery{namespaces{a...MyFragmentb{c# This overlapps with properties in MyFragment}}}The above is valid GQL syntax and will merge properties defined inMyFragmentandb { c }intob {c,e,f}.
However, currentlyqeneratewill fail to deduce proper base classes for these overlapps.
Work on this is being conducted in#77.DevelopmentCICI happens on anapp-sreowned Jenkins instance.ReleasesPR ChecksBuild and Dependency Managementqenerateusespoetryas build and dependency management system.Formattingqenerateusesrufffor code checking and formatting.Generating setup.pypipinstallpoetry2setup
poetry2setup.ArchitectureThe architecture is described in more detail inthis document.