-
-
Save jasonphillips/d80642fc33d98cb34bad131adfcf6ed8 to your computer and use it in GitHub Desktop.
| import graphql | |
| # build_executable schema | |
| # | |
| # accepts schema_definition (string) and resolvers (object) in style of graphql-tools | |
| # returns a schema ready for execution | |
| def build_executable_schema(schema_definition, resolvers): | |
| ast = graphql.parse(schema_definition) | |
| schema = graphql.build_ast_schema(ast) | |
| for typeName in resolvers: | |
| fieldType = schema.get_type(typeName) | |
| for fieldName in resolvers[typeName]: | |
| if fieldType is graphql.GraphQLScalarType: | |
| fieldType.fields[fieldName].resolver = resolvers[typeName][fieldName] | |
| continue | |
| field = fieldType.fields[fieldName] | |
| field.resolver = resolvers[typeName][fieldName] | |
| if not fieldType.fields: continue | |
| for remaining in fieldType.fields: | |
| if not fieldType.fields[remaining].resolver: | |
| fieldType.fields[remaining].resolver = \ | |
| lambda value, info, _r=remaining, **args: value[_r] | |
| return schema |
| import graphql | |
| import json | |
| from graphql_tools import build_executable_schema | |
| source_schema = """ | |
| schema { | |
| query: RootQuery | |
| } | |
| type RootQuery { | |
| officers: [Officer] | |
| } | |
| type Officer { | |
| title: String | |
| first: String | |
| last: String | |
| uniform: Uniform | |
| } | |
| type Uniform { | |
| pips: Float | |
| } | |
| """ | |
| resolvers = { | |
| 'RootQuery': { | |
| # returning direct values, but would normally load fetch db with some info.context | |
| 'officers': lambda value, info, **args: [ | |
| dict(first='william', last='riker'), | |
| dict(first='geordi', last='laforge'), | |
| ] | |
| }, | |
| 'Officer': { | |
| # only declaring the field here which is computed | |
| 'title': lambda value, info, **args: 'Officer: %(first)s %(last)s' % value, | |
| # and the connection | |
| 'uniform': lambda value, info, **args: value['first']=='geordi' and {'i':2.5} or {'i':3}, | |
| }, | |
| 'Uniform': { | |
| 'pips': lambda value, info, **args: value['i'], | |
| } | |
| } | |
| my_schema = build_executable_schema(source_schema, resolvers) | |
| executed = graphql.graphql(my_schema, """ | |
| query Example { | |
| officers { | |
| first | |
| last | |
| title | |
| uniform { pips } | |
| } | |
| } | |
| """) | |
| print(json.dumps(executed.data, indent=4)) |
| { | |
| "officers": [ | |
| { | |
| "first": "william", | |
| "last": "riker", | |
| "title": "Officer: william riker", | |
| "uniform": { | |
| "pips": 3.0 | |
| } | |
| }, | |
| { | |
| "first": "geordi", | |
| "last": "laforge", | |
| "title": "Officer: geordi laforge", | |
| "uniform": { | |
| "pips": 2.5 | |
| } | |
| } | |
| ] | |
| } |
Why not publish it as a pip package?
And how to use with graphene?
How could I use it with graphene?
I've iterated on this idea a bit within a small project recently, and can hopefully find an opportunity from there to write it as a more complete package than the sketch above. I'll try to prioritize that in coming weeks and see what I can publish; will notify here when something comes to fruition.
(But as for usage with graphene, I'm not so sure -- this is more of an alternative to graphene's style of schema creation than an extension, as graphene's authors have likewise said, eg. here: graphql-python/graphene#704 )
Great Job!
I opened the issue graphql-python/graphene#704 .
I think it's a better idea to design schema by DSL format. I don't know much about why we have to get a extra graphene schema layer. Even though the graphene schema layer is necessary, we still must have a DSL => graphene schema parser.
I'm quite confused that why there are two types of definition. Graphene schema definition graphene.types.schema.Schema and graphql-core schema definition graphql.type.schema.GraphQLSchema.
Since graphene.types.schema.Schema is extended from graphql.type.schema.GraphQLSchema, how could I get graphene.types.schema.Schema from graphq.parse(DSL file)?
Minimal implementation of graphql-tools in Python.
Requires the graphql-core library (install with pip).