Relay library for graphql-core
graphql-relay-py is the Python port of the JavaScript Relay library for GraphQL, designed to facilitate the creation of Relay-compliant GraphQL servers using graphql-core. It provides utilities for global object identification (Nodes) and cursor-based pagination (Connections). The library maintains a regular release cadence, often aligning with updates to graphql-core and the upstream graphql-relay-js specification. The current version is 3.2.0.
Warnings
- breaking Version 3.0.0 introduced significant breaking changes to align with graphql-core version 3.x. Code written for graphql-relay-py v2.x (compatible with graphql-core v2.x) will not work with v3.x without migration.
- breaking Versions 2.0.0 and 0.5.0 introduced breaking changes relating to compatibility with specific major versions of `graphql-core`. `v2.0.0` was compatible with `graphql-core < 3`, and `v0.5.0` with `graphql-core < 2`.
- gotcha The internal `arrayconnection` module was temporarily renamed to `array_connection` in `v3.1.1` as part of a `snake_case` consistency drive, which could break direct imports. It was later re-added for backward compatibility in `v3.1.5`.
- gotcha The behavior of `unbase64` changed in `v3.1.2` to return an empty string on errors instead of potentially raising an exception, and `from_global_id` behavior was adjusted in `v3.1.3` to match `relay-js`.
Install
-
pip install graphql-relay graphql-core
Imports
- connection_args
from graphql_relay import connection_args
- connection_definitions
from graphql_relay import connection_definitions
- connection_from_array
from graphql_relay import connection_from_array
- from_global_id
from graphql_relay import from_global_id
- to_global_id
from graphql_relay import to_global_id
- global_id_field
from graphql_relay import global_id_field
- node_definitions
from graphql_relay import node_definitions
- arrayconnection
from graphql_relay.connection.arrayconnection import connection_from_array_slice
Quickstart
import graphene
from graphql.execution.execute import execute
from graphql.language.parser import parse
from graphql_relay import node_definitions, global_id_field, connection_definitions, connection_from_array, connection_args, from_global_id
class User:
def __init__(self, id, name):
self.id = id
self.name = name
users_data = {
"1": User("1", "Alice"),
"2": User("2", "Bob"),
}
def get_user(id):
return users_data.get(id)
def get_object_from_global_id(global_id, info):
type_name, id = from_global_id(global_id)
if type_name == 'User':
return get_user(id)
return None
node_interface, node_field = node_definitions(
get_object_from_global_id, lambda obj, info: UserNode if isinstance(obj, User) else None
)
class UserNode(graphene.ObjectType):
class Meta:
name = 'User'
interfaces = (node_interface,)
id = global_id_field('User')
name = graphene.String()
UserConnection = connection_definitions(UserNode, 'UserConnection').connection_type
class Query(graphene.ObjectType):
node = node_field
users = graphene.Field(
UserConnection,
args=connection_args,
resolve=lambda obj, info, **args:
connection_from_array(list(users_data.values()), args)
)
schema = graphene.Schema(query=Query)
# Example Usage:
query_str = '''
query {
users (first: 1) {
edges {
node {
id
name
}
}
}
node(id: "VXNlcjox") {
id
... on User {
name
}
}
}
'''
# Assuming "VXNlcjox" is the global ID for User:1 (to_global_id('User', '1'))
# Use 'User:1' -> base64 -> 'VXNlcjox'
result = execute(schema, parse(query_str))
print(result.data)