Writing a Provider

Writing a provider is fairly staightforward.

  1. Define a provider class

  2. Add an entry point declaration

Provider Classes

A provider class is only required to be callable with a specific signature.

import graphql


class MyProvider:
    def __init__(self, token=None):
        self.token = token

    def __call__(self, query, variables):
        # Do stuff here

        return graphql.ExecutionResult(
            errors=[],
            data={'spam': 'eggs'}
        )

The arguments it takes are:

  • query: (string) The query to give to the server

  • variables: (dict) The variables for that query

The provider should return a graphql.ExecutionResult as shown above.

Entry point

In order to be discoverable by gqlmod, providers must define entrypoints. Specifically, in the graphql_providers group under the name you want .gql files to use. This can take a few different forms, depending on your project. A few examples:

setup.cfg
[options.entry_points]
graphql_providers =
    starwars = gqlmod_starwars:StarWarsProvider
setup.py
setup(
    # ...
    entry_points={
        'graphql_providers': [
            'starwars = gqlmod_starwars:StarWarsProvider'
        ]
    },
    # ...
)
pyproject.toml
# This is for poetry-based projects
[tool.poetry.plugins.graphql_providers]
"starwars" = "gqlmod_starwars:StarWarsProvider'"

Helpers

In order to help with common cases, gqlmod ships with several helpers

Note that many of them have additional requirements, which are encapsulated in extras.

urllib

Helpers for using urllib to build a provider. You probably want UrllibJsonProvider.

Requires the no extras.

class gqlmod.helpers.urllib.UrllibJsonProvider[source]

A UrllibProvider that uses a JSON-based POST

class gqlmod.helpers.urllib.UrllibProvider[source]

Help build an HTTP-based provider based on requests.

You should fill in endpoint and possibly override modify_request().

endpoint: str = None

The URL to send requests to

modify_request(req, variables)[source]

Apply policies about the request, primarily authentication.

Accepts a urllib.request.Request object.

aiohttp

Helpers for using aiohttp to build a provider.

Requires the aiohttp extra.

class gqlmod.helpers.aiohttp.AiohttpProvider[source]

Help build an HTTP-based provider based on aiohttp.

You should fill in endpoint and possibly override modify_request_args().

endpoint: str = None

The URL to send requests to.

modify_request_args(variables, kwargs)[source]

Apply policies about the request, primarily authentication.

timeout: aiohttp.client.ClientTimeout = None

Timeout policy to use, if any.

use_json: bool = False

Whether a JSON-based or form-like request should be used.

Extensions

In addition to the core querying interface, providers may influence the import process in a few different ways. These are all implemented as optional methods on the provider instance.

get_schema_str()

Providers may override the standard schema discovery mechanism by implementing get_schema_str(). This is useful for providers that don’t have a primary service or don’t allow anonymous access at all.

This method must be synchronous. An async variation is not supported.

Default behavior: Issue a GraphQL introspection query via the standard query path.

Parameters: None.

Returns: A str of the schema, in standard GraphQL schema language.

codegen_extra_kwargs()

Providers may add keyword arguments (variables) to the query call inside the generated module. These will be passed through the query pipeline back to the provider.

Default behavior: No additional variables are inserted.

Parameters:

  • graphql_ast (positional, graphql.language.OperationDefinitionNode): The AST of the GraphQL query in question

  • schema (positional, graphql.type.GraphQLSchema): The schema of the service

Returns: A dict of the names mapping to either simple values or ast.AST instances. (Note that the returned AST will be embedded into a right-hand expression context.)