Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

easy-graphql-server

Package Overview
Dependencies
Maintainers
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

easy-graphql-server

Easy to use abstraction layer for GraphQL, with support for Django ORM.

  • 0.9.31
  • PyPI
  • Socket score

Maintainers
3

Easy GraphQL Server

easy_graphql_server provides 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_server can be installed from PyPI using the built-in pip command:

pip install easy-graphql-server

Usage

Expose methods

There are three ways to expose a method in the GraphQL schema.

Calling Schema.expose_query() and Schema.expose_mutation()
import easy_graphql_server as egs

schema = 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 = lambda input_string, input_integer=None: {
        'output_string': 2 * input_string,
        'output_integer': None if input_integer is None else 2 * input_integer,
    },
)

_internal_value = 0
def bar_mutation_method(value=None, increment_value=None):
    if value is not None:
        _internal_value = value
    if increment_value is not None:
        _internal_value += increment_value
    return {
        '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,
)
Subclassing Schema.ExposedQuery and Schema.ExposedMutation
import easy_graphql_server as egs

schema = egs.Schema()

class FooQuery(schema.ExposedQuery):
    name = 'foo'
    input_format = {
        'input_string': egs.Required(str),
        'input_integer': int,
    }
    output_format = {
        'output_string': str,
        'output_integer': int,
    }
    @staticmethod
    def method(input_string, input_integer=None):
        return {
            'output_string': 2 * input_string,
            'output_integer': None if input_integer is None else 2 * input_integer,
        }

class BarMutation(schema.ExposedMutation):
    name = 'bar'
    _internal_value = 0
    input_format = {
        'value': int,
        'increment_value': int,
    }
    output_format = {
        'value': int,
    }
    @classmethod
    def method(cls, value=None, increment_value=None):
        if value is not None:
            cls._internal_value = value
        if increment_value is not None:
            cls._internal_value += increment_value
        return {
            'value': cls._internal_value,
        }
Subclassing easy_graphql_server.ExposedQuery and easy_graphql_server.ExposedMutation

This is very similar to the previous way.

import easy_graphql_server as egs

class FooQuery(schema.ExposedQuery):
    name = 'foo'
    input_format = {
        'input_string': egs.Required(str),
        'input_integer': int,
    }
    output_format = {
        'output_string': str,
        'output_integer': int,
    }
    @staticmethod
    def method(input_string, input_integer=None):
        return {
            'output_string': 2 * input_string,
            'output_integer': None if input_integer is None else 2 * input_integer,
        }

class BarMutation(schema.ExposedMutation):
    name = 'bar'
    _internal_value = 0
    input_format = {
        'value': int,
        'increment_value': int,
    }
    output_format = {
        'value': int,
    }
    @classmethod
    def method(cls, value=None, increment_value=None):
        if value is not None:
            cls._internal_value = value
        if increment_value is not None:
            cls._internal_value += increment_value
        return {
            'value': cls._internal_value,
        }

schema = egs.Schema()
schema.expose(FooQuery)
schema.expose(BarMutation)
Available options for exposing methods

The same options can be passed either as class attributes for subclasses of Schema.ExposedQuery and Schema.ExposedMutation, or as keyword arguments to Schema.expose_query() and Schema.expose_mutation() methods.

Options for queries and mutations are the same.

  • name is the name under which the method shall be exposed

  • method is the callback function of your choice

  • input_format is the input format for the GraphQL method, passed as a (possibly recursive) mapping; if unspecified or None, the defined GraphQL method will take no input; the mapping keys are

  • output_format is the output format of the GraphQL method, passed as a (possibly recursive) mapping or as a list containing one mapping

  • pass_graphql_selection can either be a bool or a str; if set to True, the graphql_selection parameter will be passed to the callback method, indicating which fields are requested for output; if set to a str, the given string will be the name of the keyword parameter passed to the callback method instead of graphql_selection

  • pass_graphql_path can either be a bool or a str; if set to True, the graphql_path parameter will be passed to the callback method, indicating as a list[str] the GraphQL path in which the method is being executed; if set to a str, the given string will be the name of the keyword parameter passed to the callback method instead of graphql_path

  • pass_authenticated_user can either be a bool or a str; if set to True, the authenticated_user parameter will be passed to the callback method, indicating the user authenticated in the source HTTP request (or None if the request was unauthenticated); if set to a str, the given string will be the name of the keyword parameter passed to the callback method instead of authenticated_user

  • require_authenticated_user is a bool indicating whether or not authentication is required for the exposed method

Expose ORM models

What does it do?

For instance, exposing a model called Thing will expose the following queries...

  • thing: fetch a single instance of the model given its unique identifier
  • things: 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 inserted
  • update_thing: update a single instance of the model given its unique identifier and a mapping the new data to apply
  • delete_thing: delete a single instance of the model given its unique identifier
Calling Schema.expose_model()
import easy_graphql_server
from my_django_application.models import Person

schema = easy_graphql_server.Schema()

schema.expose_model(
	orm_model=Person,
	plural_name='people',
	can_expose=('id', 'first_name', 'last_name'),
	cannot_write=('id',),
)
Subclassing Schema.ExposedModel
import easy_graphql_server
from my_django_application.models import Person

schema = easy_graphql_server.Schema()

class ExposedPerson(schema.ExposedModel):
		orm_model = Person
		plural_name = 'people'
		can_expose = ('id', 'first_name', 'last_name')
		cannot_write = ('id',)
Subclassing easy_graphql_server.ExposedModel

This is very similar to the previous way.

import easy_graphql_server
from my_django_application.models import Person

schema = easy_graphql_server.Schema()

class ExposedPerson(easy_graphql_server.ExposedModel):
		orm_model = Person
		plural_name = 'people'
		can_expose = ('id', 'first_name', 'last_name')
		cannot_write = ('id',)

schema = easy_graphql_server.Schema()
schema.expose(ExposedPerson)
Available options for exposing models

The same options can be passed either as class attributes for subclasses of ExposedModel, or as keyword arguments to Schema.expose_model() method.

  • cannot_expose is either a bool, or a tuple[str]; defaults to False; if set to True, 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 mutation

  • can_create is either a bool, or a tuple[str]; defaults to True; if set to False, 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 to create_...

  • cannot_create is either a bool, or a tuple[str]; defaults to False; if set to True, 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 to create_...

  • can_read is either a bool, or a tuple[str]; defaults to True; if set to False, 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_read is either a bool, or a tuple[str]; defaults to False; if set to True, 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_update is either a bool, or a tuple[str]; defaults to True; if set to True, no delete_... 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 the update_... mutation

  • cannot_update is either a bool, or a tuple[str]; defaults to False; if set to True, no update_... 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 the update_... mutation

  • can_delete is a bool; defaults to True; if set to False, no delete_... mutation method will be exposed for the model

  • cannot_delete is a bool; defaults to False; if set to True, no delete_... mutation method will be exposed for the model

  • only_when_child_of is either None (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 as only_when_child_of parameter)

  • require_authenticated_user is a bool indicating whether or not authentication is required for the exposed method

  • has_permission is either None, or a callback method returning a bool (True if operation is authorized, False otherwise), and taking as parameters authenticated_user (self-explanatory), operation (a value of the easy_graphql_server.Operation enum: CREATE, READ, UPDATE or DELETE) and data (new data, only applies to CREATE and UPDATE)

  • filter_for_user is either None, or a callback method returning a queryset, and taking as parameters queryset and authenticated_user

Perform GraphQL queries

If you want to perform GraphQL queries on the schema without going through a schema, you can use Schema.execute(). This method can take the following parameters:

  • query: the GraphQL query, in the form of a str
  • variables: variables to go along with the query (optional), as a dict[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-serializable dict, instead of a graphql.execution.execute.ExecutionResult instance

Credits and history

The easy_graphql_server library was originally a subproject within the Bridger development team, to provide an easy way to expose database models with GraphQL using Graphene.

The project was then rewritten with graphq-core and Graphene was dropped.

License

easy_graphql_server is under MIT license.

Keywords

FAQs


Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc