Writing a Provider¶
Writing a provider is fairly staightforward.
Define a provider class
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 query_sync(self, query, variables):
# Do stuff here
return graphql.ExecutionResult(
errors=[],
data={'spam': 'eggs'}
)
async def query_async(self, query, variables):
# Do stuff here, asynchronously
return graphql.ExecutionResult(
errors=[],
data={'spam': 'eggs'}
)
The arguments it takes are:
query
: (string) The query to give to the servervariables
: (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:
[options.entry_points]
graphql_providers =
starwars = gqlmod_starwars:StarWarsProvider
setup(
# ...
entry_points={
'graphql_providers': [
'starwars = gqlmod_starwars:StarWarsProvider'
]
},
# ...
)
# This is for poetry-based projects
[tool.poetry.plugins.graphql_providers]
"starwars" = "gqlmod_starwars:StarWarsProvider'"
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 questionschema
(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.)
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.
httpx¶
Helpers for using httpx
to build a provider.
Requires the http
extra.
-
class
gqlmod.helpers.httpx.
HttpxProvider
[source]¶ Help build an HTTP-based provider based on httpx.
You should fill in
endpoint
and possibly overridemodify_request_args()
.-
build_request
(query, variables)[source]¶ Build the Request object.
Override to add authentication and such.
-
timeout
: httpx.Timeout = None¶ Timeout policy to use, if any.
-
types¶
Functions to help with typing of queries.
-
gqlmod.helpers.types.
annotate
(ast, schema)[source]¶ Scans the AST and builds type information from the schema
utils¶
-
gqlmod.helpers.utils.
unwrap_type
(node)[source]¶ Gets the true type node from an schema node.
Returns the list of wrappers, the real type first and the outermost last
-
gqlmod.helpers.utils.
walk_query
(query_ast, schema)[source]¶ Walks a query (by AST), generating 3-tuples of:
the name path (Tuple[str])
the AST node of the field in the query (
graphql.language.ast.FieldNode
)the schema node of the field (
graphql.type.GraphQLField
)
-
gqlmod.helpers.utils.
walk_variables
(query_ast, schema)[source]¶ Walks the variables (by AST), generating 2-tuples of:
the name path (Tuple[str])
the schema node of the field (
graphql.type.GraphQLField
)
Note that the paths are rooted in the name of the variable, but the variable itself is not produced.