Package: easy-graphql-server
Easy GraphQL Servereasy_graphql_serverprovides an easy way to expose a database in GraphQL, using ORM models and web frameworks (so far only Django is supported, but SQLAlchemy & Flask will soon come).Easy GraphQL ServerUsageExpose methodsCallingSchema.expose_query()andSchema.expose_mutation()SubclassingSchema.ExposedQueryandSchema.ExposedMutationSubclassingeasy_graphql_server.ExposedQueryandeasy_graphql_server.ExposedMutationAvailable options for exposing methodsExpose ORM modelsCallingSchema.expose_model()SubclassingSchema.ExposedModelSubclassingeasy_graphql_server.ExposedModelAvailable options for exposing modelsPerform GraphQL queriesCredits and historyLicenseeasy_graphql_servercan be installed from PyPI using the built-in pip command:pipinstalleasy-graphql-serverUsageExpose methodsThere are three ways to expose a method in the GraphQL schema.CallingSchema.expose_query()andSchema.expose_mutation()importeasy_graphql_serverasegsschema=egs.Schema()schema.expose_query(name='foo',input_format={'input_string':egs.Required(str),'input_integer':int,},output_format={'output_string':str,'output_integer':int,},method=lambdainput_string,input_integer=None:{'output_string':2*input_string,'output_integer':Noneifinput_integerisNoneelse2*input_integer,},)_internal_value=0defbar_mutation_method(value=None,increment_value=None):ifvalueisnotNone:_internal_value=valueifincrement_valueisnotNone:_internal_value+=increment_valuereturn{'value':_internal_value,}schema.expose_mutation(name='bar',input_format={'input_string':egs.Required(str),'input_integer':int,},output_format={'output_string':str,'output_integer':int,},method=bar_mutation_method,)SubclassingSchema.ExposedQueryandSchema.ExposedMutationimporteasy_graphql_serverasegsschema=egs.Schema()classFooQuery(schema.ExposedQuery):name='foo'input_format={'input_string':egs.Required(str),'input_integer':int,}output_format={'output_string':str,'output_integer':int,}@staticmethoddefmethod(input_string,input_integer=None):return{'output_string':2*input_string,'output_integer':Noneifinput_integerisNoneelse2*input_integer,}classBarMutation(schema.ExposedMutation):name='bar'_internal_value=0input_format={'value':int,'increment_value':int,}output_format={'value':int,}@classmethoddefmethod(cls,value=None,increment_value=None):ifvalueisnotNone:cls._internal_value=valueifincrement_valueisnotNone:cls._internal_value+=increment_valuereturn{'value':cls._internal_value,}Subclassingeasy_graphql_server.ExposedQueryandeasy_graphql_server.ExposedMutationThis is very similar to the previous way.importeasy_graphql_serverasegsclassFooQuery(schema.ExposedQuery):name='foo'input_format={'input_string':egs.Required(str),'input_integer':int,}output_format={'output_string':str,'output_integer':int,}@staticmethoddefmethod(input_string,input_integer=None):return{'output_string':2*input_string,'output_integer':Noneifinput_integerisNoneelse2*input_integer,}classBarMutation(schema.ExposedMutation):name='bar'_internal_value=0input_format={'value':int,'increment_value':int,}output_format={'value':int,}@classmethoddefmethod(cls,value=None,increment_value=None):ifvalueisnotNone:cls._internal_value=valueifincrement_valueisnotNone:cls._internal_value+=increment_valuereturn{'value':cls._internal_value,}schema=egs.Schema()schema.expose(FooQuery)schema.expose(BarMutation)Available options for exposing methodsThe same options can be passed either as class attributes for subclasses ofSchema.ExposedQueryandSchema.ExposedMutation, or as keyword arguments toSchema.expose_query()andSchema.expose_mutation()methods.Options forqueriesandmutationsare the same.nameis the name under which the method shall be exposedmethodis the callback function of your choiceinput_formatis the input format for the GraphQL method, passed as a (possibly recursive) mapping; if unspecified orNone, the defined GraphQL method will take no input; the mapping keys areoutput_formatis the output format of the GraphQL method, passed as a (possibly recursive) mapping or as alistcontaining one mappingpass_graphql_selectioncan either be aboolor astr; if set toTrue, thegraphql_selectionparameter will be passed to the callback method, indicating which fields are requested for output; if set to astr, the given string will be the name of the keyword parameter passed to the callback method instead ofgraphql_selectionpass_graphql_pathcan either be aboolor astr; if set toTrue, thegraphql_pathparameter will be passed to the callback method, indicating as alist[str]the GraphQL path in which the method is being executed; if set to astr, the given string will be the name of the keyword parameter passed to the callback method instead ofgraphql_pathpass_authenticated_usercan either be aboolor astr; if set toTrue, theauthenticated_userparameter will be passed to the callback method, indicating the user authenticated in the source HTTP request (orNoneif the request was unauthenticated); if set to astr, the given string will be the name of the keyword parameter passed to the callback method instead ofauthenticated_userrequire_authenticated_useris aboolindicating whether or not authentication is required for the exposed methodExpose ORM modelsWhat does it do?For instance, exposing a model calledThingwill expose the following queries...thing: fetch a single instance of the model given its unique identifierthings: fetch a collection of model instances, given filtering criteria, or unfiltered, paginated or not...and mutations:create_thing: create a single instance of the model given the data to be insertedupdate_thing: update a single instance of the model given its unique identifier and a mapping the new data to applydelete_thing: delete a single instance of the model given its unique identifierCallingSchema.expose_model()importeasy_graphql_serverfrommy_django_application.modelsimportPersonschema=easy_graphql_server.Schema()schema.expose_model(orm_model=Person,plural_name='people',can_expose=('id','first_name','last_name'),cannot_write=('id',),)SubclassingSchema.ExposedModelimporteasy_graphql_serverfrommy_django_application.modelsimportPersonschema=easy_graphql_server.Schema()classExposedPerson(schema.ExposedModel):orm_model=Personplural_name='people'can_expose=('id','first_name','last_name')cannot_write=('id',)Subclassingeasy_graphql_server.ExposedModelThis is very similar to the previous way.importeasy_graphql_serverfrommy_django_application.modelsimportPersonschema=easy_graphql_server.Schema()classExposedPerson(easy_graphql_server.ExposedModel):orm_model=Personplural_name='people'can_expose=('id','first_name','last_name')cannot_write=('id',)schema=easy_graphql_server.Schema()schema.expose(ExposedPerson)Available options for exposing modelsThe same options can be passed either as class attributes for subclasses ofExposedModel, or as keyword arguments toSchema.expose_model()method.cannot_exposeis either abool, or atuple[str]; defaults toFalse; if set toTrue, no query or mutation method will be exposed for the model; if set to a list of field names, those fields will be excluded from every query and mutationcan_createis either abool, or atuple[str]; defaults toTrue; if set toFalse, no creation mutation method will be exposed for the model; if set to a list of field names, only those fields will be possible field values passed at insertion time tocreate_...cannot_createis either abool, or atuple[str]; defaults toFalse; if set toTrue, no creation mutation method will be exposed for the model; if set to a list of field names, those fields will be excluded from possible field values passed at insertion time tocreate_...can_readis either abool, or atuple[str]; defaults toTrue; if set toFalse, no query method will be exposed for the model; if set to a list of field names, only those fields will be exposed for the...(show one instance) and...s(show a collection of instances) queries (it also defines which fields are available as mutations results)cannot_readis either abool, or atuple[str]; defaults toFalse; if set toTrue, no query method will be exposed for the model; if set to a list of field names, only those fields will be exposed for the...(show one instance) and...s(show a collection of instances) queries (it also defines which fields are not available as mutations results)can_updateis either abool, or atuple[str]; defaults toTrue; if set toTrue, nodelete_...mutation method will be exposed for the model; if set to a list of field names, those fields will be the only possible keys for the_parameter (new data for instance fields) of theupdate_...mutationcannot_updateis either abool, or atuple[str]; defaults toFalse; if set toTrue, noupdate_...mutation method will be exposed for the model; if set to a list of field names, those fields will be excluded from possible keys for the_parameter (new data for instance fields) of theupdate_...mutationcan_deleteis abool; defaults toTrue; if set toFalse, nodelete_...mutation method will be exposed for the modelcannot_deleteis abool; defaults toFalse; if set toTrue, nodelete_...mutation method will be exposed for the modelonly_when_child_ofis eitherNone(model does not have to be nested to be exposed),True(the model is not exposed if not nested), an ORM model class, or a tuple/list/set of ORM model classes (the defined model can only be exposed when nested directly under one of models passed asonly_when_child_ofparameter)require_authenticated_useris aboolindicating whether or not authentication is required for the exposed methodhas_permissionis eitherNone, or a callback method returning abool(Trueif operation is authorized,Falseotherwise), and taking as parametersauthenticated_user(self-explanatory),operation(a value of theeasy_graphql_server.Operationenum:CREATE,READ,UPDATEorDELETE) anddata(new data, only applies toCREATEandUPDATE)filter_for_useris eitherNone, or a callback method returning aqueryset, and taking as parametersquerysetandauthenticated_userPerform GraphQL queriesIf you want to perform GraphQL queries on the schema without going through a schema, you can useSchema.execute(). This method can take the following parameters:query: the GraphQL query, in the form of astrvariables: variables to go along with the query (optional), as adict[str,Any]operation_name: name of the operation to be executed within the query (optional)authenticated_user: parameter that will be passed to the callback functions of GraphQL methods that require it (optional)serializable_output: the output will be rendered as JSON-serializabledict, instead of agraphql.execution.execute.ExecutionResultinstanceCredits and historyTheeasy_graphql_serverlibrary was originally a subproject within theBridgerdevelopment
team, to provide an easy way to expose database models with GraphQL usingGraphene.The project was then rewritten withgraphq-coreand Graphene was dropped.Licenseeasy_graphql_serveris under MIT license.