API reference
Following items are importable directly from ariadne
package:
EnumType
class EnumType(SchemaBindable):
...
Bindable mapping Python values to enumeration members in a GraphQL schema.
Constructor
def __init__(
self,
name: str,
values: Union[Dict[str, Any], Type[enum.Enum], Type[enum.IntEnum]],
):
...
Initializes the EnumType
with name
and values
mapping.
Required arguments
name
: a str
with the name of GraphQL enum type in GraphQL schema to
bind to.
values
: a dict
or enums.Enum
with values to use to represent GraphQL
enum's in Python logic.
Methods
bind_to_schema
def bind_to_schema(self, schema: GraphQLSchema) -> None:
...
Binds this EnumType
instance to the instance of GraphQL schema.
bind_to_default_values
def bind_to_default_values(self, _schema: GraphQLSchema) -> None:
...
Populates default values of input fields and args in the GraphQL schema.
This step is required because GraphQL query executor doesn't perform a
lookup for default values defined in schema. Instead it simply pulls the
value from fields and arguments default_value
attribute, which is
None
by default.
Deprecated: Ariadne versions before 0.22 used
EnumType.bind_to_default_values
method to fix default enum values embedded in the GraphQL schema. Ariadne 0.22 release introduces universalrepair_schema_default_enum_values
utility in its place.
validate_graphql_type
def validate_graphql_type(
self,
graphql_type: Optional[GraphQLNamedType],
) -> None:
...
Validates that schema's GraphQL type associated with this EnumType
is an enum
.
Example
Given following GraphQL enum:
enum UserRole {
MEMBER
MODERATOR
ADMIN
}
You can use EnumType
to map it's members to Python Enum
:
user_role_type = EnumType(
"UserRole",
{
"MEMBER": 0,
"MODERATOR": 1,
"ADMIN": 2,
}
)
EnumType
also works with dictionaries:
user_role_type = EnumType(
"UserRole",
{
"MEMBER": 0,
"MODERATOR": 1,
"ADMIN": 2,
}
)
Extension
class Extension:
...
Base class for extensions.
Subclasses of this class should override default methods to run custom logic during Query execution.
Methods
request_started
def request_started(self, context: ContextValue) -> None:
...
Extension hook executed at request's start.
request_finished
def request_finished(self, context: ContextValue) -> None:
...
Extension hook executed at request's end.
resolve
def resolve(
self,
next_: Resolver,
obj: Any,
info: GraphQLResolveInfo,
**kwargs,
) -> Any:
...
Extension hook wrapping field's value resolution.
Arguments
next_
: a resolver
or next extension's resolve
method.
obj
: a Python data structure to resolve value from.
info
: a GraphQLResolveInfo
instance for executed resolver.
**kwargs
: extra arguments from GraphQL to pass to resolver.
Example
resolve
should handle both sync and async next_
:
from inspect import iscoroutinefunction
from time import time
from ariadne.types import Extension, Resolver
from graphql import GraphQLResolveInfo
from graphql.pyutils import is_awaitable
class MyExtension(Extension):
def __init__(self):
self.paths = []
def resolve(
self, next_: Resolver, obj: Any, info: GraphQLResolveInfo, **kwargs
) -> Any:
path = ".".join(map(str, info.path.as_list()))
# Fast implementation for synchronous resolvers
if not iscoroutinefunction(next_):
start_time = time()
result = next_(obj, info, **kwargs)
self.paths.append((path, time() - start_time))
return result
# Create async closure for async `next_` that GraphQL
# query executor will handle for us.
async def async_my_extension():
start_time = time()
result = await next_(obj, info, **kwargs)
if is_awaitable(result):
result = await result
self.paths.append((path, time() - start_time))
return result
# GraphQL query executor will execute this closure for us
return async_my_extension()
has_errors
def has_errors(
self,
errors: List[GraphQLError],
context: ContextValue,
) -> None:
...
Extension hook executed when GraphQL encountered errors.
format
def format(self, context: ContextValue) -> Optional[dict]:
...
Extension hook executed to retrieve extra data to include in result's
extensions
data.
ExtensionManager
class ExtensionManager:
...
Container and runner for extensions and middleware, used by the GraphQL servers.
Attributes
context
: the ContextValue
of type specific to the server.
extensions
: a tuple
with instances of initialized extensions.
extensions_reversed
: a tuple
created from reversing extensions
.
Constructor
def __init__(
self,
extensions: Optional[ExtensionList] = None,
context: Optional[ContextValue] = None,
):
...
Initializes extensions and stores them with context on instance.
Optional arguments
extensions
: a list
of Extension
types to initialize.
context
: the ContextValue
of type specific to the server.
Methods
as_middleware_manager
def as_middleware_manager(
self,
middleware: MiddlewareList = None,
manager_class: Optional[Type[MiddlewareManager]] = None,
) -> Optional[MiddlewareManager]:
...
Creates middleware manager instance combining middleware and extensions.
Returns instance of the type passed in manager_class
argument
or MiddlewareManager
that query executor then uses.
Optional arguments
middleware
: a list
of Middleware
instances
manager_class
a type
of middleware manager to use. MiddlewareManager
is used if this argument is passed None
or omitted.
request
def request(self) -> None:
...
A context manager that should wrap request processing.
Runs request_started
hook at beginning and request_finished
at
the end of request processing, enabling APM extensions like ApolloTracing.
has_errors
def has_errors(self, errors: List[GraphQLError]) -> None:
...
Propagates GraphQL errors returned by GraphQL server to extensions.
Should be called only when there are errors.
format
def format(self) -> dict:
...
Gathers data from extensions for inclusion in server's response JSON.
This data can be retrieved from the extensions
key in response JSON.
Returns dict
with JSON-serializable data.
FallbackResolversSetter
class FallbackResolversSetter(SchemaBindable):
...
Bindable that recursively scans GraphQL schema for fields and explicitly
sets their resolver to graphql.default_field_resolver
package if
they don't have any resolver set yet.
Deprecated: This class doesn't provide any utility for developers and only serves as a base for
SnakeCaseFallbackResolversSetter
which is being replaced by what we believe to be a better solution.Because of this we are deprecating this utility. It will be removed in future Ariadne release.
Methods
bind_to_schema
def bind_to_schema(self, schema: GraphQLSchema) -> None:
...
Scans GraphQL schema for types with fields that don't have set resolver.
add_resolvers_to_object_fields
def add_resolvers_to_object_fields(
self,
type_object: GraphQLObjectType,
) -> None:
...
Sets explicit default resolver on a fields of an object that don't have any.
add_resolver_to_field
def add_resolver_to_field(self, _: str, field_object: GraphQLField) -> None:
...
Sets default_field_resolver
as a resolver on a field that doesn't have any.
InputType
class InputType(SchemaBindable):
...
Bindable populating input types in a GraphQL schema with Python logic.
Constructor
def __init__(
self,
name: str,
out_type: Optional[GraphQLInputFieldOutType] = None,
out_names: Optional[Dict[str, str]] = None,
):
...
Initializes the InputType
with a name
and optionally out type
and out names.
Required arguments
name
: a str
with the name of GraphQL object type in GraphQL schema to
bind to.
Optional arguments
out_type
: a GraphQLInputFieldOutType
, Python callable accepting single
argument, a dict with data from GraphQL query, required to return
a Python representation of input type.
out_names
: a Dict[str, str]
with mappings from GraphQL field names
to dict keys in a Python dictionary used to contain a data passed as
input.
Methods
bind_to_schema
def bind_to_schema(self, schema: GraphQLSchema) -> None:
...
Binds this InputType
instance to the instance of GraphQL schema.
if it has an out type function, it assigns it to GraphQL type's
out_type
attribute. If type already has other function set on
it's out_type
attribute, this type is replaced with new one.
If it has any out names set, it assigns those to GraphQL type's
fields out_name
attributes. If field already has other out name set on
its out_name
attribute, this name is replaced with the new one.
validate_graphql_type
def validate_graphql_type(
self,
graphql_type: Optional[GraphQLNamedType],
) -> None:
...
Validates that schema's GraphQL type associated with this InputType
is an input
.
Example input value represented as dataclass
Following code creates a GraphQL schema with object type named Query
with single field which has an argument of an input type. It then uses
the InputType
to set ExampleInput
dataclass as Python representation
of this GraphQL type:
from dataclasses import dataclass
from ariadne import InputType, QueryType, make_executable_schema
@dataclass
class ExampleInput:
id: str
message: str
query_type = QueryType()
@query_type.field("repr")
def resolve_repr(*_, input: ExampleInput):
return repr(input)
schema = make_executable_schema(
"""
type Query {
repr(input: ExampleInput): String!
}
input ExampleInput {
id: ID!
message: String!
}
""",
query_type,
# Lambda is used because out type (second argument of InputType)
# is called with single dict and dataclass requires each value as
# separate argument.
InputType("ExampleInput", lambda data: ExampleInput(**data)),
)
Example input with its fields mapped to custom dict keys
Following code creates a GraphQL schema with object type named Query
with single field which has an argument of an input type. It then uses
the InputType
to set custom "out names" values, mapping GraphQL
shortMessage
to message
key in Python dict:
from ariadne import InputType, QueryType, make_executable_schema
query_type = QueryType()
@query_type.field("repr")
def resolve_repr(*_, input: dict):
# Dict will have `id` and `message` keys
input_id = input["id"]
input_message = input["message"]
return f"id: {input_id}, message: {input_message}"
schema = make_executable_schema(
"""
type Query {
repr(input: ExampleInput): String!
}
input ExampleInput {
id: ID!
shortMessage: String!
}
""",
query_type,
InputType("ExampleInput", out_names={"shortMessage": "message"}),
)
Example input value as dataclass with custom named fields
Following code creates a GraphQL schema with object type named Query
with single field which has an argument of an input type. It then uses
the InputType
to set ExampleInput
dataclass as Python representation
of this GraphQL type, and maps shortMessage
input field to it's
message
attribute:
from dataclasses import dataclass
from ariadne import InputType, QueryType, make_executable_schema
@dataclass
class ExampleInput:
id: str
message: str
query_type = QueryType()
@query_type.field("repr")
def resolve_repr(*_, input: ExampleInput):
return repr(input)
schema = make_executable_schema(
"""
type Query {
repr(input: ExampleInput): String!
}
input ExampleInput {
id: ID!
shortMessage: String!
}
""",
query_type,
InputType(
"ExampleInput",
lambda data: ExampleInput(**data),
{"shortMessage": "message"},
),
)
InterfaceType
class InterfaceType(ObjectType):
...
Bindable populating interfaces in a GraphQL schema with Python logic.
Extends ObjectType
, providing field
decorator and set_field
and set_alias
methods. If those are used to set resolvers for interface's fields, those
resolvers will instead be set on fields of GraphQL types implementing this
interface, but only if those fields don't already have resolver of their own set
by the ObjectType
.
Type resolver
Because GraphQL fields using interface as their returning type can return any Python value from their resolver, GraphQL interfaces require special type of resolver called "type resolver" to function.
This resolver is called with the value returned by field's resolver and is required to return a string with a name of GraphQL type represented by Python value from the field:
def example_type_resolver(obj: Any, *_) -> str:
if isinstance(obj, PythonReprOfUser):
return "User"
if isinstance(obj, PythonReprOfComment):
return "Comment"
raise ValueError(f"Don't know GraphQL type for '{obj}'!")
This resolver is not required if the GraphQL field returns a value that has
the __typename
attribute or dict
key with a name of the GraphQL type:
user_data_dict = {"__typename": "User", ...}
# or...
class UserRepr:
__typename: str = "User"
Constructor
def __init__(
self,
name: str,
type_resolver: Optional[Resolver] = None,
):
...
Initializes the InterfaceType
with a name
and optional type_resolver
.
Type resolver is required by InterfaceType
to function properly, but can
be set later using either set_type_resolver(type_resolver)
setter or type_resolver
decorator.
Required arguments
name
: a str
with the name of GraphQL interface type in GraphQL schema to
bind to.
Optional arguments
type_resolver
: a Resolver
used to resolve a str with name of GraphQL type
from it's Python representation.
Methods
set_type_resolver
def set_type_resolver(self, type_resolver: Resolver) -> Resolver:
...
Sets function as type resolver for this interface.
Can be used as a decorator. Also available through type_resolver
alias:
interface_type = InterfaceType("MyInterface")
@interface_type.type_resolver
def type_resolver(obj: Any, *_) -> str:
...
bind_to_schema
def bind_to_schema(self, schema: GraphQLSchema) -> None:
...
Binds this InterfaceType
instance to the instance of GraphQL schema.
Sets resolve_type
attribute on GraphQL interface. If this attribute was
previously set, it will be replaced to new value.
If this interface has any resolvers set, it also scans GraphQL schema for types implementing this interface and sets those resolvers on those types fields, but only if those fields don't already have other resolver set.
validate_graphql_type
def validate_graphql_type(
self,
graphql_type: Optional[GraphQLNamedType],
) -> None:
...
Validates that schema's GraphQL type associated with this InterfaceType
is an interface
.
Example
Following code creates a GraphQL schema with a field that returns random
result of either User
or Post
GraphQL type. It also supports dict with
__typename
key that explicitly declares its GraphQL type:
import random
from dataclasses import dataclass
from ariadne import QueryType, InterfaceType, make_executable_schema
@dataclass
class UserModel:
id: str
name: str
@dataclass
class PostModel:
id: str
message: str
results = (
UserModel(id=1, name="Bob"),
UserModel(id=2, name="Alice"),
UserModel(id=3, name="Jon"),
PostModel(id=1, message="Hello world!"),
PostModel(id=2, message="How's going?"),
PostModel(id=3, message="Sure thing!"),
{"__typename": "User", "id": 4, "name": "Polito"},
{"__typename": "User", "id": 5, "name": "Aerith"},
{"__typename": "Post", "id": 4, "message": "Good day!"},
{"__typename": "Post", "id": 5, "message": "Whats up?"},
)
query_type = QueryType()
@query_type.field("result")
def resolve_random_result(*_):
return random.choice(results)
result_type = InterfaceType("Result")
@result_type.type_resolver
def resolve_result_type(obj: UserModel | PostModel | dict, *_) -> str:
if isinstance(obj, UserModel):
return "User"
if isinstance(obj, PostModel):
return "Post"
if isinstance(obj, dict) and obj.get("__typename"):
return obj["__typename"]
raise ValueError(f"Don't know GraphQL type for '{obj}'!")
schema = make_executable_schema(
"""
type Query {
result: Result!
}
interface Result {
id: ID!
}
type User implements Result {
id: ID!
name: String!
}
type Post implements Result {
id: ID!
message: String!
}
""",
query_type,
result_type,
)
MutationType
class MutationType(ObjectType):
...
An convenience class for defining Mutation type.
Constructor
def __init__(self):
...
Initializes the MutationType
with a GraphQL name set to Mutation
.
Example
Both of those code samples have same result:
mutation_type = MutationType()
mutation_type = ObjectType("Mutation")
ObjectType
class ObjectType(SchemaBindable):
...
Bindable populating object types in a GraphQL schema with Python logic.
Constructor
def __init__(self, name: str):
...
Initializes the ObjectType
with a name
.
Required arguments
name
: a str
with the name of GraphQL object type in GraphQL schema to
bind to.
Methods
field
def field(self, name: str) -> Callable[[Resolver], Resolver]:
...
Return a decorator that sets decorated function as a resolver for named field.
Wrapper for create_register_resolver
that on runtime validates name
to be a
string.
Required arguments
name
: a str
with a name of the GraphQL object's field in GraphQL schema to
bind decorated resolver to.
create_register_resolver
def create_register_resolver(
self,
name: str,
) -> Callable[[Resolver], Resolver]:
...
Return a decorator that sets decorated function as a resolver for named field.
Required arguments
name
: a str
with a name of the GraphQL object's field in GraphQL schema to
bind decorated resolver to.
set_field
def set_field(self, name, resolver: Resolver) -> Resolver:
...
Set a resolver for the field name.
Required arguments
name
: a str
with a name of the GraphQL object's field in GraphQL schema to
set this resolver for.
resolver
: a Resolver
function to use.
set_alias
def set_alias(self, name: str, to: str) -> None:
...
Set an alias resolver for the field name to given Python name.
Required arguments
name
: a str
with a name of the GraphQL object's field in GraphQL schema to
set this resolver for.
to
: a str
of an attribute or dict key to resolve this field to.
bind_to_schema
def bind_to_schema(self, schema: GraphQLSchema) -> None:
...
Binds this ObjectType
instance to the instance of GraphQL schema.
If it has any resolver functions set, it assigns those to GraphQL type's
fields resolve
attributes. If field already has other resolver set on
its resolve
attribute, this resolver is replaced with the new one.
validate_graphql_type
def validate_graphql_type(
self,
graphql_type: Optional[GraphQLNamedType],
) -> None:
...
Validates that schema's GraphQL type associated with this ObjectType
is a type
.
bind_resolvers_to_graphql_type
def bind_resolvers_to_graphql_type(
self,
graphql_type,
replace_existing = True,
) -> None:
...
Binds this ObjectType
instance to the instance of GraphQL schema.
Example
Following code creates a GraphQL schema with single object type named Query
and uses ObjectType
to set resolvers on its fields:
import random
from datetime import datetime
from ariadne import ObjectType, make_executable_schema
query_type = ObjectType("Query")
@query_type.field("diceRoll")
def resolve_dice_roll(*_):
return random.int(1, 6)
@query_type.field("year")
def resolve_year(*_):
return datetime.today().year
schema = make_executable_schema(
"""
type Query {
diceRoll: Int!
year: Int!
}
""",
query_type,
)
Example with objects in objects
When a field in the schema returns other GraphQL object, this object's
resolvers are called with value returned from field's resolver. For example
if there's an user
field on the Query
type that returns the User
type,
you don't have to resolve User
fields in user
resolver. In below example
fullName
field on User
type is resolved from data on UserModel
object
that user
field resolver on Query
type returned:
import dataclasses
from ariadne import ObjectType, make_executable_schema
@dataclasses.dataclass
class UserModel:
id: int
username: str
first_name: str
last_name: str
users = [
UserModel(
id=1,
username="Dany",
first_name="Daenerys",
last_name="Targaryen",
),
UserModel(
id=2,
username="BlackKnight19",
first_name="Cahir",
last_name="Mawr Dyffryn aep Ceallach",
),
UserModel(
id=3,
username="TheLady",
first_name="Dorotea",
last_name="Senjak",
),
]
# Query type resolvers return users, but don't care about fields
# of User type
query_type = ObjectType("Query")
@query_type.field("users")
def resolve_users(*_) -> list[UserModel]:
# In real world applications this would be a database query
# returning iterable with user results
return users
@query_type.field("user")
def resolve_user(*_, id: str) -> UserModel | None:
# In real world applications this would be a database query
# returning single user or None
try:
# GraphQL ids are always strings
clean_id = int(id)
except (ValueError, TypeError):
# We could raise "ValueError" instead
return None
for user in users:
if user.id == id:
return user
return None
# User type resolvers don't know how to retrieve User, but know how to
# resolve User type fields from UserModel instance
user_type = ObjectType("User")
# Resolve "name" GraphQL field to "username" attribute
user_type.set_alias("name", "username")
# Resolve "fullName" field to combined first and last name
# `obj` argument will be populated by GraphQL with a value from
# resolver for field returning "User" type
@user_type.field("fullName")
def resolve_user_full_name(obj: UserModel, *_):
return f"{obj.first_name} {obj.last_name}"
schema = make_executable_schema(
"""
type Query {
users: [User!]!
user(id: ID!): User
}
type User {
id: ID!
name: String!
fullName: String!
}
""",
query_type,
user_type,
)
QueryType
class QueryType(ObjectType):
...
An convenience class for defining Query type.
Constructor
def __init__(self):
...
Initializes the QueryType
with a GraphQL name set to Query
.
Example
Both of those code samples have same effect:
query_type = QueryType()
query_type = ObjectType("Query")
ScalarType
class ScalarType(SchemaBindable):
...
Bindable populating scalars in a GraphQL schema with Python logic.
GraphQL scalars implement default serialization and deserialization logic. This class is only useful when custom logic is needed, most commonly when Python representation of scalar's value is not JSON-serializable by default.
This logic can be customized for three steps:
Serialization
Serialization step converts Python representation of scalar's value to a JSON serializable format.
Serializer function takes single argument and returns a single, JSON serializable value:
def serialize_date(value: date) -> str:
# Serialize dates as "YYYY-MM-DD" string
return date.strftime("%Y-%m-%d")
Value parsing
Value parsing step converts value from deserialized JSON to Python representation.
Value parser function takes single argument and returns a single value:
def parse_date_str(value: str) -> date:
try:
# Parse "YYYY-MM-DD" string into date
return datetime.strptime(value, "%Y-%m-%d").date()
except (ValueError, TypeError):
raise ValueError(
f'"{value}" is not a date string in YYYY-MM-DD format.'
)
Literal parsing
Literal parsing step converts value from GraphQL abstract syntax tree (AST) to Python representation.
Literal parser function takes two arguments, an AST node and a dict with query's variables and returns Python value:
def parse_date_literal(
value: str, variable_values: dict[str, Any] = None
) -> date:
if not isinstance(ast, StringValueNode):
raise ValueError()
try:
# Parse "YYYY-MM-DD" string into date
return datetime.strptime(ast.value, "%Y-%m-%d").date()
except (ValueError, TypeError):
raise ValueError(
f'"{value}" is not a date string in YYYY-MM-DD format.'
)
When scalar has custom value parser set, but not the literal parser, the GraphQL query executor will use default literal parser, and then call the value parser with it's return value. This mechanism makes custom literal parser unnecessary for majority of scalar implementations.
Scalar literals are always parsed twice: on query validation and during query execution.
Constructor
def __init__(
self,
name: str,
*,
serializer: Optional[GraphQLScalarSerializer],
value_parser: Optional[GraphQLScalarValueParser],
literal_parser: Optional[GraphQLScalarLiteralParser],
):
...
Initializes the ScalarType
with a name
.
Required arguments
name
: a str
with the name of GraphQL scalar in GraphQL schema to
bind to.
Optional arguments
serializer
: a function called to convert Python representation of
scalar's value to JSON serializable format.
value_parser
: a function called to convert a JSON deserialized value
from query's "variables" JSON into scalar's Python representation.
literal_parser
: a function called to convert an AST value
from parsed query into scalar's Python representation.
Methods
set_serializer
def set_serializer(
self,
f: GraphQLScalarSerializer,
) -> GraphQLScalarSerializer:
...
Sets function as serializer for this scalar.
Can be used as a decorator. Also available through serializer
alias:
date_scalar = ScalarType("Date")
@date_scalar.serializer
def serialize_date(value: date) -> str:
# Serialize dates as "YYYY-MM-DD" string
return date.strftime("%Y-%m-%d")
set_value_parser
def set_value_parser(
self,
f: GraphQLScalarValueParser,
) -> GraphQLScalarValueParser:
...
Sets function as value parser for this scalar.
Can be used as a decorator. Also available through value_parser
alias:
date_scalar = ScalarType("Date")
@date_scalar.value_parser
def parse_date_str(value: str) -> date:
try:
# Parse "YYYY-MM-DD" string into date
return datetime.strptime(value, "%Y-%m-%d").date()
except (ValueError, TypeError):
raise ValueError(
f'"{value}" is not a date string in YYYY-MM-DD format.'
)
set_literal_parser
def set_literal_parser(
self,
f: GraphQLScalarLiteralParser,
) -> GraphQLScalarLiteralParser:
...
Sets function as literal parser for this scalar.
Can be used as a decorator. Also available through literal_parser
alias:
date_scalar = ScalarType("Date")
@date_scalar.literal_parser
def parse_date_literal(
value: str, variable_values: Optional[dict[str, Any]] = None
) -> date:
if not isinstance(ast, StringValueNode):
raise ValueError()
try:
# Parse "YYYY-MM-DD" string into date
return datetime.strptime(ast.value, "%Y-%m-%d").date()
except (ValueError, TypeError):
raise ValueError(
f'"{value}" is not a date string in YYYY-MM-DD format.'
)
bind_to_schema
def bind_to_schema(self, schema: GraphQLSchema) -> None:
...
Binds this ScalarType
instance to the instance of GraphQL schema.
If it has serializer or parser functions set, it assigns those to GraphQL scalar's attributes. If scalar's attribute already has other function set, this function is replaced with the new one.
validate_graphql_type
def validate_graphql_type(
self,
graphql_type: Optional[GraphQLNamedType],
) -> None:
...
Validates that schema's GraphQL type associated with this ScalarType
is a scalar
.
Example datetime scalar
Following code defines a datetime scalar which converts Python datetime object to and from a string. Note that it without custom literal scalar:
from datetime import datetime
from ariadne import QueryType, ScalarType, make_executable_schema
scalar_type = ScalarType("DateTime")
@scalar_type.serializer
def serialize_value(val: datetime) -> str:
return datetime.strftime(val, "%Y-%m-%d %H:%M:%S")
@scalar_type.value_parser
def parse_value(val) -> datetime:
if not isinstance(val, str):
raise ValueError(
f"'{val}' is not a valid JSON representation "
)
return datetime.strptime(val, "%Y-%m-%d %H:%M:%S")
query_type = QueryType()
@query_type.field("now")
def resolve_now(*_):
return datetime.now()
@query_type.field("diff")
def resolve_diff(*_, value):
delta = datetime.now() - value
return int(delta.total_seconds())
schema = make_executable_schema(
"""
scalar DateTime
type Query {
now: DateTime!
diff(value: DateTime): Int!
}
""",
scalar_type,
query_type,
)
Example generic scalar
Generic scalar is a pass-through scalar that doesn't perform any value
conversion. Most common use case for those is for GraphQL fields that
return unstructured JSON to the client. To create a scalar like this,
you can simply include scalar Generic
in your GraphQL schema:
from ariadne import QueryType, make_executable_schema
query_type = QueryType()
@query_type.field("rawJSON")
def resolve_raw_json(*_):
# Note: this value needs to be JSON serializable
return {
"map": {
"0": "Hello!",
"1": "World!",
},
"list": [
2,
1,
3,
7,
],
}
schema = make_executable_schema(
"""
scalar Generic
type Query {
rawJSON: Generic!
}
""",
query_type,
)
SchemaBindable
class SchemaBindable(Protocol):
...
Base class for bindable types.
Subclasses should extend the bind_to_schema
method with custom logic for
populating an instance of GraphQL schema with Python logic and values.
Methods
bind_to_schema
def bind_to_schema(self, schema: GraphQLSchema) -> None:
...
Binds this Schema[Bindable
](/docs/bindables) instance to the instance of GraphQL schema.
Example
Example InputType
bindable that sets Python names for fields of GraphQL input:
from ariadne import SchemaBindable
from graphql import GraphQLInputType
class InputType(SchemaBindable):
_name: str
_fields: dict[str, str]
def __init__(self, name: str, fields: dict[str, str] | None):
self._name = name
self._fields = fields or {}
def set_field_out_name(self, field: str, out_name: str):
self._fields[field] = out_name
def bind_to_schema(self, schema: GraphQLSchema) -> None:
graphql_type = schema.get_type(self._name)
if not graphql_type:
raise ValueError(
"Type %s is not defined in the schema" % self.name
)
if not isinstance(graphql_type, GraphQLInputType):
raise ValueError(
"%s is defined in the schema, but it is instance of %s (expected %s)"
% (self.name, type(graphql_type).__name__, GraphQLInputType.__name__)
)
for field, out_name in self._fields.items():
schema_field = graphql_type.fields.get(field)
if not schema_field:
raise ValueError(
"Type %s does not define the %s field" % (self.name, field)
)
schema_field.out_name = out_name
Usage:
from ariadne import QueryType, make_executable_schema
from .input_type import InputType
from .users.models import User
input_type = InputType(
"UserInput",
{
"fullName": "full_name",
"yearOfBirth": "year_of_birth",
}
)
query_type = QueryType()
@query_type.field("countUsers")
def resolve_count_users(*_, input):
qs = User.objects
if input:
if input["full_name"]:
qs = qs.filter(full_name__ilike=input["full_name"])
if input["year_of_birth"]:
qs = qs.filter(dob__year=input["year_of_birth"])
return qs.count()
schema = make_executable_schema(
"""
type Query {
countUsers(input: UserInput!): Int!
}
input UserInput {
fullName: String
yearOfBirth: Int
}
""",
query_type,
input_type,
)
SchemaDirectiveVisitor
class SchemaDirectiveVisitor(SchemaVisitor):
...
Base class for custom GraphQL directives.
Also implements class methods with container and management logic for
directives at schema creation time, used by make_executable_schema
.
Lifecycle
Separate instances of the GraphQL directive are created for each GraphQL schema item with the directive set on it. If directive is set on two fields, two separate instances of a directive will be created.
Constructor
def __init__(self, name, args, visited_type, schema, context):
...
Instantiates the directive for schema object.
Required arguments
name
: a str
with directive's name.
args
: a dict
with directive's arguments.
visited_type
: an GraphQL type this directive is set on.
schema
: the GraphQL schema instance.
context
: None
, unused but present for historic reasons.
Methods
get_directive_declaration
def get_directive_declaration(
cls,
directive_name: str,
schema: GraphQLSchema,
) -> Optional[GraphQLDirective]:
...
Get GraphQL directive declaration from GraphQL schema by it's name.
Returns GraphQLDirective
object or None
.
Required arguments
directive_name
: a str
with name of directive in the GraphQL schema.
schema
: a GraphQLSchema
instance to retrieve the directive
declaration from.
get_declared_directives
def get_declared_directives(
cls,
schema: GraphQLSchema,
directive_visitors: Dict[str, Type['SchemaDirectiveVisitor']],
) -> Dict[str, GraphQLDirective]:
...
Get GraphQL directives declaration from GraphQL schema by their names.
Returns a dict
where keys are strings with directive names in schema
and values are GraphQLDirective
objects with their declarations in the
GraphQL schema.
Required arguments
directive_name
: a str
with name of directive in the GraphQL schema.
schema
: a GraphQLSchema
instance to retrieve the directive
declaration from.
visit_schema_directives
def visit_schema_directives(
cls,
schema: GraphQLSchema,
directive_visitors: Dict[str, Type['SchemaDirectiveVisitor']],
*,
context: Optional[Dict[str, Any]],
) -> Mapping[str, List['SchemaDirectiveVisitor']]:
...
Apply directives to the GraphQL schema.
Applied directives mutate the GraphQL schema in place.
Returns dict with names of GraphQL directives as keys and list of directive instances created for each directive name.
Required arguments
schema
: a GraphQL schema to which directives should be applied.
directive_visitors
: a dict
with str
and
Type[SchemaDirectiveVisitor]
pairs defining mapping of
SchemaDirectiveVisitor
types to their names in the GraphQL schema.
Optional arguments
context
: None
, unused but present for historic reasons.
Example schema visitors
SchemaDirectiveVisitor
subclasses can implement any of below methods
that will be called when directive is applied to different elements of
GraphQL schema:
from ariadne import SchemaDirectiveVisitor
from graphql import (
GraphQLArgument,
GraphQLEnumType,
GraphQLEnumValue,
GraphQLField,
GraphQLInputField,
GraphQLInputObjectType,
GraphQLInterfaceType,
GraphQLObjectType,
GraphQLScalarType,
GraphQLSchema,
GraphQLUnionType,
)
class MyDirective(SchemaDirectiveVisitor):
def visit_schema(self, schema: GraphQLSchema) -> None:
pass
def visit_scalar(self, scalar: GraphQLScalarType) -> GraphQLScalarType:
pass
def visit_object(self, object_: GraphQLObjectType) -> GraphQLObjectType:
pass
def visit_field_definition(
self,
field: GraphQLField,
object_type: Union[GraphQLObjectType, GraphQLInterfaceType],
) -> GraphQLField:
pass
def visit_argument_definition(
self,
argument: GraphQLArgument,
field: GraphQLField,
object_type: Union[GraphQLObjectType, GraphQLInterfaceType],
) -> GraphQLArgument:
pass
def visit_interface(self, interface: GraphQLInterfaceType) -> GraphQLInterfaceType:
pass
def visit_union(self, union: GraphQLUnionType) -> GraphQLUnionType:
pass
def visit_enum(self, type_: GraphQLEnumType) -> GraphQLEnumType:
pass
def visit_enum_value(
self, value: GraphQLEnumValue, enum_type: GraphQLEnumType
) -> GraphQLEnumValue:
pass
def visit_input_object(
self, object_: GraphQLInputObjectType
) -> GraphQLInputObjectType:
pass
def visit_input_field_definition(
self, field: GraphQLInputField, object_type: GraphQLInputObjectType
) -> GraphQLInputField:
pass
SchemaNameConverter
SchemaNameConverter = Callable[[str, GraphQLSchema, Tuple[str, ...]], str]
A type of a function implementing a strategy for names conversion in schema. Passed as an option to make_executable_schema
and convert_schema_names
functions.
Takes three arguments:
name
: a str
with schema name to convert.
schema
: the GraphQL schema in which names are converted.
path
: a tuple of str
representing a path to the schema item which name is being converted.
Returns a string with the Python name to use.
SnakeCaseFallbackResolversSetter
class SnakeCaseFallbackResolversSetter(FallbackResolversSetter):
...
Subclass of FallbackResolversSetter
that uses case-converting resolver
instead of default_field_resolver
.
Deprecated: Use
convert_names_case
frommake_executable_schema
instead.
Methods
add_resolver_to_field
def add_resolver_to_field(
self,
field_name: str,
field_object: GraphQLField,
) -> None:
...
Sets case converting resolver on a field that doesn't have any.
SubscriptionType
class SubscriptionType(ObjectType):
...
Bindable populating the Subscription type in a GraphQL schema with Python logic.
Extends ObjectType
, providing source
decorator and set_source
method, used
to set subscription sources for it's fields.
Subscription sources ("subscribers")
Subscription source is a function that is an async generator. This function is used to subscribe to source of events or messages. It can also filter the messages by not yielding them.
Its signature is same as resolver:
async def source_fn(
root_value: Any, info: GraphQLResolveInfo, **field_args
) -> Any:
yield ...
Subscription resolvers
Subscription resolvers are called with message returned from the source. Their role is to convert this message into Python representation of a type associated with subscription's field in GraphQL schema. Its called with message yielded from source function as first argument.
def resolver_fn(
message: Any, info: GraphQLResolveInfo, **field_args
) -> Any:
# Subscription resolver can be sync and async.
return ...
GraphQL arguments
When subscription field has arguments those arguments values are passed to both source and resolver functions.
Constructor
def __init__(self):
...
Initializes the SubscriptionType
with a GraphQL name set to Subscription
.
Methods
source
def source(self, name: str) -> Callable[[Subscriber], Subscriber]:
...
Return a decorator that sets decorated function as a source for named field.
Wrapper for create_register_subscriber
that on runtime validates name
to be a
string.
Required arguments
name
: a str
with a name of the GraphQL object's field in GraphQL schema to
bind decorated source to.
create_register_subscriber
def create_register_subscriber(
self,
name: str,
) -> Callable[[Subscriber], Subscriber]:
...
Return a decorator that sets decorated function as a source for named field.
Required arguments
name
: a str
with a name of the GraphQL object's field in GraphQL schema to
bind decorated source to.
set_source
def set_source(self, name, generator: Subscriber) -> Subscriber:
...
Set a source for the field name.
Required arguments
name
: a str
with a name of the GraphQL object's field in GraphQL schema to
set this source for.
generator
: a Subscriber
function to use as an source.
bind_to_schema
def bind_to_schema(self, schema: GraphQLSchema) -> None:
...
Binds this SubscriptionType
instance to the instance of GraphQL schema.
If it has any previously set subscription resolvers or source functions, those will be replaced with new ones from this instance.
bind_subscribers_to_graphql_type
def bind_subscribers_to_graphql_type(self, graphql_type) -> None:
...
Binds this SubscriptionType
instance's source functions.
Source functions are set to fields subscribe
attributes.
Example source and resolver
from ariadne import SubscriptionType, make_executable_schema
from broadcast import broadcast
from .models import Post
subscription_type = SubscriptionType()
@subscription_type.source("post")
async def source_post(*_, category: Optional[str] = None) -> dict:
async with broadcast.subscribe(channel="NEW_POSTS") as subscriber:
async for event in subscriber:
message = json.loads(event.message)
# Send message to resolver if we don't filter
if not category or message["category"] == category:
yield message
@subscription_type.field("post")
async def resolve_post(
message: dict, *_, category: Optional[str] = None
) -> Post:
# Convert message to Post object that resolvers for Post type in
# GraphQL schema understand.
return await Post.get_one(id=message["post_id"])
schema = make_executable_schema(
"""
type Query {
"Valid schema must define the Query type"
none: Int
}
type Subscription {
post(category: ID): Post!
}
type Post {
id: ID!
author: String!
text: String!
}
""",
subscription_type
)
Example chat
Ariadne GraphQL Chat Example is the Github repository with GraphQL chat application, using Redis message backend, Broadcaster library for publishing and subscribing to messages and React.js client using Apollo-Client subscriptions.
UnionType
class UnionType(SchemaBindable):
...
Bindable populating interfaces in a GraphQL schema with Python logic.
Type resolver
Because GraphQL fields using union as their returning type can return any Python value from their resolver, GraphQL unions require special type of resolver called "type resolver" to function.
This resolver is called with the value returned by field's resolver and is required to return a string with a name of GraphQL type represented by Python value from the field:
def example_type_resolver(obj: Any, *_) -> str:
if isinstance(obj, PythonReprOfUser):
return "USer"
if isinstance(obj, PythonReprOfComment):
return "Comment"
raise ValueError(f"Don't know GraphQL type for '{obj}'!")
This resolver is not required if the GraphQL field returns a value that has
the __typename
attribute or dict
key with a name of the GraphQL type:
user_data_dict = {"__typename": "User", ...}
# or...
class UserRepr:
__typename: str = "User"
Constructor
def __init__(
self,
name: str,
type_resolver: Optional[Resolver] = None,
):
...
Initializes the UnionType
with a name
and optional type_resolver
.
Type resolver is required by UnionType
to function properly, but can
be set later using either set_type_resolver(type_resolver)
setter or type_resolver
decorator.
Required arguments
name
: a str
with the name of GraphQL union type in GraphQL schema to
bind to.
Optional arguments
type_resolver
: a Resolver
used to resolve a str with name of GraphQL type
from it's Python representation.
Methods
set_type_resolver
def set_type_resolver(self, type_resolver: Resolver) -> Resolver:
...
Sets function as type resolver for this union.
Can be used as a decorator. Also available through type_resolver
alias:
union_type = UnionType("MyUnion")
@union_type.type_resolver
def type_resolver(obj: Any, *_) -> str:
...
bind_to_schema
def bind_to_schema(self, schema: GraphQLSchema) -> None:
...
Binds this UnionType
instance to the instance of GraphQL schema.
Sets resolve_type
attribute on GraphQL union. If this attribute was
previously set, it will be replaced to new value.
validate_graphql_type
def validate_graphql_type(
self,
graphql_type: Optional[GraphQLNamedType],
) -> None:
...
Validates that schema's GraphQL type associated with this UnionType
is an union
.
Example
Following code creates a GraphQL schema with a field that returns random
result of either User
or Post
GraphQL type. It also supports dict with
__typename
key that explicitly declares its GraphQL type:
import random
from dataclasses import dataclass
from ariadne import QueryType, UnionType, make_executable_schema
@dataclass
class UserModel:
id: str
name: str
@dataclass
class PostModel:
id: str
message: str
results = (
UserModel(id=1, name="Bob"),
UserModel(id=2, name="Alice"),
UserModel(id=3, name="Jon"),
PostModel(id=1, message="Hello world!"),
PostModel(id=2, message="How's going?"),
PostModel(id=3, message="Sure thing!"),
{"__typename": "User", "id": 4, "name": "Polito"},
{"__typename": "User", "id": 5, "name": "Aerith"},
{"__typename": "Post", "id": 4, "message": "Good day!"},
{"__typename": "Post", "id": 5, "message": "Whats up?"},
)
query_type = QueryType()
@query_type.field("result")
def resolve_random_result(*_):
return random.choice(results)
result_type = UnionType("Result")
@result_type.type_resolver
def resolve_result_type(obj: UserModel | PostModel | dict, *_) -> str:
if isinstance(obj, UserModel):
return "User"
if isinstance(obj, PostModel):
return "Post"
if isinstance(obj, dict) and obj.get("__typename"):
return obj["__typename"]
raise ValueError(f"Don't know GraphQL type for '{obj}'!")
schema = make_executable_schema(
"""
type Query {
result: Result!
}
union Result = User | Post
type User {
id: ID!
name: String!
}
type Post {
id: ID!
message: String!
}
""",
query_type,
result_type,
)
combine_multipart_data
def combine_multipart_data(
operations: Union[dict, list],
files_map: dict,
files: FilesDict,
) -> Union[dict, list]:
...
Populates operations
variables with files
using the files_map
.
Utility function for integration developers.
Mutates operations
in place, but also returns it.
Requires arguments
operations
: a list
or dict
with GraphQL operations to populate the file
variables in. It contains operationName
, query
and variables
keys, but
implementation only cares about variables
being present.
files_map
: a dict
with mapping of files
to operations
. Keys correspond
to keys in files dict
, values are lists of strings with paths (eg.:
variables.key.0
maps to operations["variables"]["key"]["0"]
).
files
: a dict
of files. Keys are strings, values are environment specific
representations of uploaded files.
Example
Following example uses combine_multipart_data
to populate the image
variable with file object from files
, using the files_map
to know
which variable to replace.
# Single GraphQL operation
operations = {
"operationName": "AvatarUpload",
"query": """
mutation AvatarUpload($type: String!, $image: Upload!) {
avatarUpload(type: $type, image: $image) {
success
errors
}
}
""",
"variables": {"type": "SQUARE", "image": None}
}
files_map = {"0": ["variables.image"]}
files = {"0": UploadedFile(....)}
combine_multipart_data(operations, files_map, files
assert operations == {
"variables": {"type": "SQUARE", "image": UploadedFile(....)}
}
convert_camel_case_to_snake
def convert_camel_case_to_snake(graphql_name: str) -> str:
...
Converts a string with camelCase
name to snake_case
.
Utility function used by Ariadne's name conversion logic for mapping GraphQL
names using the camelCase
convention to Python counterparts in snake_case
.
Returns a string with converted name.
Required arguments
graphql_name
: a str
with name to convert.
Example
All characters in converted name are lowercased:
assert convert_camel_case_to_snake("URL") == "url"
_
is inserted before every uppercase character that's not first and is not
preceded by other uppercase character:
assert convert_camel_case_to_snake("testURL") == "test_url"
_
is inserted before every uppercase character succeeded by lowercased
character:
assert convert_camel_case_to_snake("URLTest") == "url_test"
_
is inserted before every digit that's not first and is not preceded by
other digit:
assert convert_camel_case_to_snake("Rfc123") == "rfc_123"
convert_kwargs_to_snake_case
def convert_kwargs_to_snake_case(func: Callable) -> Callable:
...
Decorator for resolvers recursively converting their kwargs to snake_case
.
Converts keys in kwargs
dict from camelCase
to snake_case
using the
convert_camel_case_to_snake
function. Walks values recursively, applying
same conversion to keys of nested dicts and dicts in lists of elements.
Returns decorated resolver function.
Deprecated: This decorator is deprecated and will be deleted in future version of Ariadne. Set
out_name
s explicitly in your GraphQL schema or use theconvert_schema_names
option onmake_executable_schema
.
convert_schema_names
def convert_schema_names(
schema: GraphQLSchema,
name_converter: Optional[SchemaNameConverter],
) -> None:
...
Set mappings in GraphQL schema from camelCase
names to snake_case
.
This function scans GraphQL schema and:
If objects field has name in camelCase
and this field doesn't have a
resolver already set on it, new resolver is assigned to it that resolves
it's value from object attribute or dict key named like snake_case
version of field's name.
If object's field has argument in camelCase
and this argument doesn't have
the out_name
attribute already set, this attribute is populated with
argument's name converted to snake_case
If input's field has name in camelCase
and it's out_name
attribute is
not already set, this attribute is populated with field's name converted
to snake_case
.
Schema is mutated in place.
Generally you shouldn't call this function yourself, as its part of
make_executable_schema
logic, but its part of public API for other
libraries to use.
Required arguments
schema
: a GraphQL schema to update.
name_converter
: an SchemaNameConverter
function to use to convert the
names from camelCase
to snake_case
. If not provided, default one
based on convert_camel_case_to_snake
is used.
fallback_resolvers
fallback_resolvers = FallbackResolversSetter()
Bindable instance of FallbackResolversSetter
.
Deprecated: This utility will be removed in future Ariadne release.
See
FallbackResolversSetter
for details.
format_error
def format_error(error: GraphQLError, debug: bool = False) -> dict:
...
Format the GraphQL error into JSON serializable format.
If debug
is set to True
, error's JSON will also include the extensions
key with exception
object containing error's context
and stacktrace
.
Returns a JSON-serializable dict
with error representation.
Required arguments
error
: an GraphQLError
to convert into JSON serializable format.
Optional arguments
debug
: a bool
that controls if debug data should be included in
result dict
. Defaults to False
.
get_error_extension
def get_error_extension(error: GraphQLError) -> Optional[dict]:
...
Get a JSON-serializable dict
containing error's stacktrace and context.
Returns a JSON-serializable dict
with stacktrace
and context
to include
under error's extensions
key in JSON response. Returns None
if error
has no stacktrace or wraps no exception.
Required arguments
error
: an GraphQLError
to return context and stacktrace for.
get_formatted_error_context
def get_formatted_error_context(error: Exception) -> Optional[dict]:
...
Get JSON-serializable context from Exception
.
Returns a dict
of strings, with every key being value name and value
being repr()
of it's Python value. Returns None
if context is not
available.
Required arguments
error
: an Exception
to return formatted context for.
get_formatted_error_traceback
def get_formatted_error_traceback(error: Exception) -> List[str]:
...
Get JSON-serializable stacktrace from Exception
.
Returns list of strings, with every item being separate line from stacktrace.
This approach produces better results in GraphQL explorers which display every line under previous one but not always format linebreak characters for blocks of text.
Required arguments
error
: an Exception
to return formatted stacktrace for.
gql
def gql(value: str) -> str:
...
Verifies that given string is a valid GraphQL.
Provides definition time validation for GraphQL strings. Returns unmodified string. Some IDEs provide GraphQL syntax for highlighting those strings.
Examples
Python string in this code snippet will use GraphQL's syntax highlighting when viewed in VSCode:
type_defs = gql(
"""
type Query {
hello: String!
}
"""
)
This code will raise a GraphQL parsing error:
type_defs = gql(
"""
type Query {
hello String!
}
"""
)
graphql
async def graphql(
schema: GraphQLSchema,
data: Any,
*,
context_value: Optional[Any],
root_value: Optional[RootValue],
query_parser: Optional[QueryParser],
query_validator: Optional[QueryValidator],
query_document: Optional[DocumentNode],
debug: bool,
introspection: bool,
logger: Union[None, str, Logger, LoggerAdapter],
validation_rules: Optional[ValidationRules],
require_query: bool,
error_formatter: ErrorFormatter,
middleware: MiddlewareList,
middleware_manager_class: Optional[Type[MiddlewareManager]],
extensions: Optional[ExtensionList],
execution_context_class: Optional[Type[ExecutionContext]],
**kwargs,
) -> GraphQLResult:
...
Execute GraphQL query asynchronously.
Returns a tuple with two items:
bool
: True
when no errors occurred, False
otherwise.
dict
: an JSON-serializable dict
with query result
(defining either data
, error
, or both keys) that should be returned to
client.
Required arguments
schema
: a GraphQL schema instance that defines Query
type.
data
: a dict
with query data (query
string, optionally operationName
string and variables
dictionary).
Optional arguments
context_value
: a context value to make accessible as 'context' attribute
of second argument (info
) passed to resolvers.
root_value
: a RootValue
to pass as first argument to resolvers set on
Query
and Mutation
types.
query_parser
: a QueryParser
to use instead of default one. Is called
with two arguments: context_value
, and data
dict.
query_validator
: a QueryValidator
to use instead of default one. Is called
with five arguments: schema
, 'document_ast', 'rules', 'max_errors' and 'type_info'.
query_document
: an already parsed GraphQL query. Setting this option will
prevent graphql
from parsing query
string from data
second time.
debug
: a bool
for enabling debug mode. Controls presence of debug data
in errors reported to client.
introspection
: a bool
for disabling introspection queries.
logger
: a str
with name of logger or logger instance to use for logging
errors.
validation_rules
: a list
of or callable returning list of custom
validation rules to use to validate query before it's executed.
require_query
: a bool
controlling if GraphQL operation to execute must be
a query (vs. mutation or subscription).
error_formatter
: an ErrorFormatter
callable to use to convert GraphQL
errors encountered during query execution to JSON-serializable format.
middleware
: a list
of or callable returning list of GraphQL middleware
to use by query executor.
middleware_manager_class
: a MiddlewareManager
class to use by query
executor.
extensions
: a list
of or callable returning list of extensions
to use during query execution.
execution_context_class
: ExecutionContext
class to use by query
executor.
**kwargs
: any kwargs not used by graphql
are passed to
graphql.graphql
.
graphql_sync
def graphql_sync(
schema: GraphQLSchema,
data: Any,
*,
context_value: Optional[Any],
root_value: Optional[RootValue],
query_parser: Optional[QueryParser],
query_validator: Optional[QueryValidator],
query_document: Optional[DocumentNode],
debug: bool,
introspection: bool,
logger: Union[None, str, Logger, LoggerAdapter],
validation_rules: Optional[ValidationRules],
require_query: bool,
error_formatter: ErrorFormatter,
middleware: MiddlewareList,
middleware_manager_class: Optional[Type[MiddlewareManager]],
extensions: Optional[ExtensionList],
execution_context_class: Optional[Type[ExecutionContext]],
**kwargs,
) -> GraphQLResult:
...
Execute GraphQL query synchronously.
Returns a tuple with two items:
bool
: True
when no errors occurred, False
otherwise.
dict
: an JSON-serializable dict
with query result
(defining either data
, error
, or both keys) that should be returned to
client.
Required arguments
schema
: a GraphQL schema instance that defines Query
type.
data
: a dict
with query data (query
string, optionally operationName
string and variables
dictionary).
Optional arguments
context_value
: a context value to make accessible as 'context' attribute
of second argument (info
) passed to resolvers.
root_value
: a RootValue
to pass as first argument to resolvers set on
Query
and Mutation
types.
query_parser
: a QueryParser
to use instead of default one. Is called
with two arguments: context_value
, and data
dict.
query_validator
: a QueryValidator
to use instead of default one. Is called
with five arguments: schema
, 'document_ast', 'rules', 'max_errors' and 'type_info'.
query_document
: an already parsed GraphQL query. Setting this option will
prevent graphql_sync
from parsing query
string from data
second time.
debug
: a bool
for enabling debug mode. Controls presence of debug data
in errors reported to client.
introspection
: a bool
for disabling introspection queries.
logger
: a str
with name of logger or logger instance to use for logging
errors.
validation_rules
: a list
of or callable returning list of custom
validation rules to use to validate query before it's executed.
require_query
: a bool
controlling if GraphQL operation to execute must be
a query (vs. mutation or subscription).
error_formatter
: an ErrorFormatter
callable to use to convert GraphQL
errors encountered during query execution to JSON-serializable format.
middleware
: a list
of or callable returning list of GraphQL middleware
to use by query executor.
middleware_manager_class
: a MiddlewareManager
class to use by query
executor.
extensions
: a list
of or callable returning list of extensions
to use during query execution.
execution_context_class
: ExecutionContext
class to use by query
executor.
**kwargs
: any kwargs not used by graphql_sync
are passed to
graphql.graphql_sync
.
is_default_resolver
def is_default_resolver(resolver: Optional[Resolver]) -> bool:
...
Test if resolver function is default resolver implemented by
graphql-core
or Ariadne.
Returns True
if resolver function is None
, graphql.default_field_resolver
or was created by Ariadne's resolve_to
utility. Returns False
otherwise.
True
is returned for None
because query executor defaults to the
graphql.default_field_resolver
is there's no resolver function set on a
field.
Required arguments
resolver
: an function None
to test or None
.
load_schema_from_path
def load_schema_from_path(path: Union[str, os.PathLike]) -> str:
...
Load schema definition in Schema Definition Language from file or directory.
If path
argument points to a file, this file's contents are read, validated
and returned as str
. If its a directory, its walked recursively and every
file with .graphql
, .graphqls
or .gql
extension is read and validated,
and all files are then concatenated into single str
that is then returned.
Returns a str
with schema definition that was already validated to be valid
GraphQL SDL. Raises GraphQLFileSyntaxError
is any of loaded files fails to
parse.
Required arguments
path
: a str
or PathLike
object pointing to either file or directory
with files to load.
make_executable_schema
def make_executable_schema(
type_defs: Union[str, List[str]],
*bindables: SchemaBindables,
directives: Optional[Dict[str, Type[SchemaDirectiveVisitor]]],
convert_names_case: Union[bool, SchemaNameConverter],
) -> GraphQLSchema:
...
Create a GraphQLSchema
instance that can be used to execute queries.
Returns a GraphQLSchema
instance with attributes populated with Python
values and functions.
Required arguments
type_defs
: a str
or list of str
with GraphQL types definitions in
schema definition language (SDL
).
Optional arguments
bindables
: instances or lists of instances of schema bindables. Order in
which bindables are passed to make_executable_schema
matters depending on
individual bindable's implementation.
directives
: a dict of GraphQL directives to apply to schema. Dict's keys must
correspond to directives names in GraphQL schema and values should be
SchemaDirectiveVisitor
classes (not instances) implementing their logic.
convert_names_case
: a bool
or function of SchemaNameConverter
type to
use to convert names in GraphQL schema between camelCase
used by GraphQL
and snake_case
used by Python. Defaults to False
, making all conversion
explicit and up to developer to implement. Set True
to use
default strategy using convert_camel_case_to_snake
for name conversions or
set to custom function to customize this behavior.
Example with minimal schema
Below code creates minimal executable schema that doesn't implement any Python
logic, but still executes queries using root_value
:
from ariadne import graphql_sync, make_executable_schema
schema = make_executable_schema(
"""
type Query {
helloWorld: String!
}
"""
)
no_errors, result = graphql_sync(
schema,
{"query": "{ helloWorld }"},
root_value={"helloWorld": "Hello world!"},
)
assert no_errors
assert result == {
"data": {
"helloWorld": "Hello world!",
},
}
Example with bindables
Below code creates executable schema that combines different ways of passing bindables to add Python logic to schema:
from dataclasses import dataclass
from enum import Enum
from ariadne import ObjectType, QueryType, UnionType, graphql_sync, make_executable_schema
# Define some types representing database models in real applications
class UserLevel(str, Enum):
USER = "user"
ADMIN = "admin"
@dataclass
class UserModel:
id: str
name: str
level: UserLevel
@dataclass
class PostModel:
id: str
body: str
# Create fake "database"
results = (
UserModel(id=1, name="Bob", level=UserLevel.USER),
UserModel(id=2, name="Alice", level=UserLevel.ADMIN),
UserModel(id=3, name="Jon", level=UserLevel.USER),
PostModel(id=1, body="Hello world!"),
PostModel(id=2, body="How's going?"),
PostModel(id=3, body="Sure thing!"),
)
# Resolve username field in GraphQL schema to user.name attribute
user_type = ObjectType("User")
user_type.set_alias("username", "name")
# Resolve message field in GraphQL schema to post.body attribute
post_type = ObjectType("Post")
post_type.set_alias("message", "body")
# Resolve results field in GraphQL schema to results array
query_type = QueryType()
@query_type.field("results")
def resolve_results(*_):
return results
# Resolve GraphQL type of individual result from it's Python class
result_type = UnionType("Result")
@result_type.type_resolver
def resolve_result_type(obj: UserModel | PostModel | dict, *_) -> str:
if isinstance(obj, UserModel):
return "User"
if isinstance(obj, PostModel):
return "Post"
raise ValueError(f"Don't know GraphQL type for '{obj}'!")
# Create executable schema that returns list of results
schema = make_executable_schema(
"""
type Query {
results: [Result!]!
}
union Result = User | Post
type User {
id: ID!
username: String!
level: UserLevel!
}
type Post {
id: ID!
message: String!
}
enum UserLevel {
USER
ADMIN
}
""",
# Bindables *args accept single instances:
query_type,
result_type,
# Bindables *args accepts lists of instances:
[user_type, post_type],
# Both approaches can be mixed
# Python Enums are also valid bindables:
UserLevel,
)
# Query the schema for results
no_errors, result = graphql_sync(
schema,
{
"query": (
"""
{
results {
... on Post {
id
message
}
... on User {
id
username
level
}
}
}
"""
),
},
)
# Verify that it works
assert no_errors
assert result == {
"data": {
"results": [
{
"id": "1",
"username": "Bob",
"level": "USER",
},
{
"id": "2",
"username": "Alice",
"level": "ADMIN",
},
{
"id": "3",
"username": "Jon",
"level": "USER",
},
{
"id": "1",
"message": "Hello world!",
},
{
"id": "2",
"message": "How's going?",
},
{
"id": "3",
"message": "Sure thing!",
},
],
},
}
Example with directive
Below code uses directives
option to set custom directive on schema:
from functools import wraps
from ariadne import SchemaDirectiveVisitor, graphql_sync, make_executable_schema
from graphql import default_field_resolver
class UppercaseDirective(SchemaDirectiveVisitor):
def visit_field_definition(self, field, object_type):
org_resolver = field.resolve or default_field_resolver
@wraps(org_resolver)
def uppercase_resolved_value(*args, **kwargs):
value = org_resolver(*args, **kwargs)
if isinstance(value, str):
return value.upper()
return value
# Extend field's behavior by wrapping it's resolver in custom one
field.resolve = uppercase_resolved_value
return field
schema = make_executable_schema(
"""
directive @uppercase on FIELD_DEFINITION
type Query {
helloWorld: String! @uppercase
}
""",
directives={"uppercase": UppercaseDirective},
)
no_errors, result = graphql_sync(
schema,
{"query": "{ helloWorld }"},
root_value={"helloWorld": "Hello world!"},
)
assert no_errors
assert result == {
"data": {
"helloWorld": "HELLO WORLD!",
},
}
Example with converted names
Below code uses convert_names_case=True
option to resolve helloWorld
field to hello_world
key from root_value
:
from ariadne import graphql_sync, make_executable_schema
schema = make_executable_schema(
"""
type Query {
helloWorld: String!
}
""",
convert_names_case=True,
)
no_errors, result = graphql_sync(
schema,
{"query": "{ helloWorld }"},
root_value={"hello_world": "Hello world!"},
)
assert no_errors
assert result == {
"data": {
"helloWorld": "Hello world!",
},
}
repair_schema_default_enum_values
def repair_schema_default_enum_values(schema: GraphQLSchema) -> None:
...
Repairs Python values of default enums embedded in the GraphQL schema.
Default enum values in the GraphQL schemas are represented as strings with enum
member names in Python. Assigning custom Python values to members of the
GraphQLEnumType
doesn't change those defaults.
This function walks the GraphQL schema, finds default enum values strings and, if this string is a valid GraphQL member name, swaps it out for a valid Python value.
resolve_to
def resolve_to(attr_name: str) -> Resolver:
...
Create a resolver that resolves to given attribute or dict key.
Returns a resolver function that can be used as resolver.
Usually not used directly but through higher level features like aliases or schema names conversion.
Required arguments
attr_name
: a str
with name of attribute or dict
key to return from
resolved object.
snake_case_fallback_resolvers
snake_case_fallback_resolvers = SnakeCaseFallbackResolversSetter()
Bindable instance of SnakeCaseFallbackResolversSetter
.
Deprecated: Use
convert_names_case
frommake_executable_schema
instead.
subscribe
async def subscribe(
schema: GraphQLSchema,
data: Any,
*,
context_value: Optional[Any],
root_value: Optional[RootValue],
query_parser: Optional[QueryParser],
query_validator: Optional[QueryValidator],
query_document: Optional[DocumentNode],
debug: bool,
introspection: bool,
logger: Union[None, str, Logger, LoggerAdapter],
validation_rules: Optional[ValidationRules],
error_formatter: ErrorFormatter,
**kwargs,
) -> SubscriptionResult:
...
Subscribe to GraphQL updates.
Returns a tuple with two items:
bool
: True
when no errors occurred, False
otherwise.
AsyncGenerator
: an async generator that server implementation should
consume to retrieve messages to send to client.
Required arguments
'schema': a GraphQL schema instance that defines Subscription
type.
data
: a dict
with query data (query
string, optionally operationName
string and variables
dictionary).
Optional arguments
context_value
: a context value to make accessible as 'context' attribute
of second argument (info
) passed to resolvers and source functions.
root_value
: a RootValue
to pass as first argument to resolvers and
source functions set on Subscription
type.
query_parser
: a QueryParser
to use instead of default one. Is called
with two arguments: context_value
, and data
dict.
query_validator
: a QueryValidator
to use instead of default one. Is called
with five arguments: schema
, 'document_ast', 'rules', 'max_errors' and 'type_info'.
query_document
: an already parsed GraphQL query. Setting this option will
prevent subscribe
from parsing query
string from data
second time.
debug
: a bool
for enabling debug mode. Controls presence of debug data
in errors reported to client.
introspection
: a bool
for disabling introspection queries.
logger
: a str
with name of logger or logger instance to use for logging
errors.
validation_rules
: a list
of or callable returning list of custom
validation rules to use to validate query before it's executed.
error_formatter
: an ErrorFormatter
callable to use to convert GraphQL
errors encountered during query execution to JSON-serializable format.
**kwargs
: any kwargs not used by subscribe
are passed to
graphql.subscribe
.
type_implements_interface
def type_implements_interface(
interface: str,
graphql_type: GraphQLType,
) -> bool:
...
Test if type definition from GraphQL schema implements an interface.
Returns True
if type implements interface and False
if it doesn't.
Required arguments
interface
: a str
with name of interface in GraphQL schema.
graphql_type
: a GraphQLType
interface to test. It may or may not have
the interfaces
attribute.
unwrap_graphql_error
def unwrap_graphql_error(
error: Union[GraphQLError, Optional[Exception]],
) -> Optional[Exception]:
...
Recursively unwrap exception when its instance of GraphQLError.
GraphQL query executor wraps exceptions in GraphQLError
instances which
contain information about exception's origin in GraphQL query or it's result.
Original exception is available through GraphQLError
's original_error
attribute, but sometimes GraphQLError
can be wrapped in other GraphQLError
.
Returns unwrapped exception or None
if no original exception was found.
Example
Below code unwraps original KeyError
from multiple GraphQLError
instances:
error = KeyError("I am a test!")
assert unwrap_graphql_error(
GraphQLError(
"Error 1",
GraphQLError(
"Error 2",
GraphQLError(
"Error 3",
original_error=error
)
)
)
) == error
Passing other exception to unwrap_graphql_error
results in same exception
being returned:
error = ValueError("I am a test!")
assert unwrap_graphql_error(error) == error
upload_scalar
upload_scalar = ScalarType('Upload')
Optional Python logic for Upload
scalar.
Upload
scalar doesn't require any custom Python logic to work, but this utility sets serializer
and literal_parser
to raise ValueErrors when Upload
is used either as return type for field or passed as literal value in GraphQL query.
Example
Below code defines a schema with Upload
scalar using upload_scalar
utility:
from ariadne import MutationType, make_executable_schema, upload_scalar
mutation_type = MutationType()
@mutation_type.field("handleUpload")
def resolve_handle_upload(*_, upload):
return repr(upload)
schema = make_executable_schema(
"""
scalar Upload
type Query {
empty: String
}
type Mutation {
handleUpload(upload: Upload!): String
}
""",
upload_scalar,
mutation_type,
)
validate_schema_default_enum_values
def validate_schema_default_enum_values(schema: GraphQLSchema) -> None:
...
Raises ValueError
if GraphQL schema has input fields or arguments with
default values that are undefined enum values.
Example schema with invalid field argument
This schema fails to validate because argument role
on field users
specifies REVIEWER
as default value and REVIEWER
is not a member of
the UserRole
enum:
type Query {
users(role: UserRole = REVIEWER): [User!]!
}
enum UserRole {
MEMBER
MODERATOR
ADMIN
}
type User {
id: ID!
}
Example schema with invalid input field
This schema fails to validate because field role
on input UserFilters
specifies REVIEWER
as default value and REVIEWER
is not a member of
the UserRole
enum:
type Query {
users(filter: UserFilters): [User!]!
}
input UserFilters {
name: String
role: UserRole = REVIEWER
}
enum UserRole {
MEMBER
MODERATOR
ADMIN
}
type User {
id: ID!
}
Example schema with invalid default input field argument
This schema fails to validate because field field
on input ChildInput
specifies INVALID
as default value and INVALID
is not a member of
the Role
enum:
type Query {
field(arg: Input = {field: {field: INVALID}}): String
}
input Input {
field: ChildInput
}
input ChildInput {
field: Role
}
enum Role {
USER
ADMIN
}