hiku.graph

Graphs are defined by nodes, fields and links. Simple functions are used to fetch any data from any data source.

class hiku.graph.Nothing

Special constant that is used by links with Optional type in order to indicate that there is nothing to link to

class hiku.graph.Option(name: str, type_: ~hiku.types.GenericMeta | None, *, default: ~typing.Any = <class 'hiku.graph.Nothing'>, description: str | None = None)

Defines an option, used to customize results of the fields and links

Options without default value are required.

Example of a required option:

Option('id', Integer)

Example of an optional option:

Option('size', Integer, default=100)

Example with TypeRef type(ref can point either to Node or data type):

Option('filter', TypeRef['FilterInput'])
Parameters:
  • name – name of the option

  • type – type of the option or None

  • default – default option value

  • description – description of the option

__init__(name: str, type_: ~hiku.types.GenericMeta | None, *, default: ~typing.Any = <class 'hiku.graph.Nothing'>, description: str | None = None)
Parameters:
  • name – name of the option

  • type – type of the option or None

  • default – default option value

  • description – description of the option

class hiku.graph.Field(name: str, type_: GenericMeta | ScalarMeta | None, func: Callable[[List[Field]], List[Any] | Awaitable[List[Any]]] | Callable[[List[Field], List[Any]], List[List[Any]] | Awaitable[List[List[Any]]]] | Callable[[Any, List[Field], List[Any]], List[List[Any]] | Awaitable[List[List[Any]]]] | SubGraph | BoundExpr, *, options: Sequence[Option] | None = None, description: str | None = None, directives: List[SchemaDirective] | None = None, deprecated: str | None = None)

Defines a field of the node

Example:

graph = Graph([
    Node('user', [
        Field('name', String, func),
    ]),
])

Example with options:

graph = Graph([
    Root([
        Field('lorem-ipsum', String, func,
              options=[Option('words', Integer, default=50)]),
    ]),
])

Example with directives:

graph = Graph([
    Root([
        Field('lorem-ipsum', String, func,
              options=[Option('words', Integer, default=50)],
              directives=[Deprecated('use another field')]),
    ]),
])

Data loading protocol:

# root node fields
def func(fields) -> List[T]

# non-root node fields
def func(fields, ids) -> List[List[T]]

Where:

Parameters:
  • name (str) – name of the field

  • type – type of the field or None

  • func – function to load field’s data

  • options – list of acceptable options

  • description – description of the field

  • directives – list of directives for the field

  • deprecated – deprecation reason

__init__(name: str, type_: GenericMeta | ScalarMeta | None, func: Callable[[List[Field]], List[Any] | Awaitable[List[Any]]] | Callable[[List[Field], List[Any]], List[List[Any]] | Awaitable[List[List[Any]]]] | Callable[[Any, List[Field], List[Any]], List[List[Any]] | Awaitable[List[List[Any]]]] | SubGraph | BoundExpr, *, options: Sequence[Option] | None = None, description: str | None = None, directives: List[SchemaDirective] | None = None, deprecated: str | None = None)
Parameters:
  • name (str) – name of the field

  • type – type of the field or None

  • func – function to load field’s data

  • options – list of acceptable options

  • description – description of the field

  • directives – list of directives for the field

  • deprecated – deprecation reason

class hiku.graph.Link(name: str, type_: Type[UnionRef | InterfaceRef], func: Callable[[], LR | Awaitable[LR]] | Callable[[Any], LR | Awaitable[LR]] | Callable[[Any, Any], LR | Awaitable[LR]] | Callable[[List[LT]], List[LR] | Awaitable[List[LR]]] | Callable[[List[LT], Any], List[LR] | Awaitable[List[LR]]] | Callable[[Any, List[LT]], List[LR] | Awaitable[List[LR]]] | Callable[[Any, List[LT], Dict], List[LR] | Awaitable[List[LR]]], *, requires: str | List[str] | None, options: Sequence[Option] | None = None, description: str | None = None, directives: List[SchemaDirective] | None = None, deprecated: str | None = None)
class hiku.graph.Link(name: str, type_: Type[Optional], func: Callable[[], LR | Const | Awaitable[LR | Const]] | Callable[[Any], LR | Const | Awaitable[LR | Const]] | Callable[[Any, Any], LR | Const | Awaitable[LR | Const]] | Callable[[List[LT]], List[LR | Const] | Awaitable[List[LR | Const]]] | Callable[[List[LT], Any], List[LR | Const] | Awaitable[List[LR | Const]]] | Callable[[Any, List[LT]], List[LR | Const] | Awaitable[List[LR | Const]]] | Callable[[Any, List[LT], Dict], List[LR | Const] | Awaitable[List[LR | Const]]], *, requires: str | List[str] | None, options: Sequence[Option] | None = None, description: str | None = None, directives: List[SchemaDirective] | None = None, deprecated: str | None = None)
class hiku.graph.Link(name: str, type_: Type[Sequence], func: Callable[[], List[LR] | Awaitable[List[LR]]] | Callable[[Any], List[LR] | Awaitable[List[LR]]] | Callable[[Any, Any], List[LR] | Awaitable[List[LR]]] | Callable[[List[LT]], List[List[LR]] | Awaitable[List[List[LR]]]] | Callable[[List[LT], Any], List[List[LR]] | Awaitable[List[List[LR]]]] | Callable[[Any, List[LT]], List[List[LR]] | Awaitable[List[List[LR]]]] | Callable[[Any, List[LT], Dict], List[List[LR]] | Awaitable[List[List[LR]]]], *, requires: str | List[str] | None, options: Sequence[Option] | None = None, description: str | None = None, directives: List[SchemaDirective] | None = None, deprecated: str | None = None)

Defines a link to the node

Example:

graph = Graph([
    Node('user', [...]),
    Root([
        Link('users', Sequence[TypeRef['user']], func, requires=None),
    ]),
])

Example with requirements:

graph = Graph([
    Node('character', [...]),
    Node('actor', [
        Field('id', Integer, field_func),
        Link('characters', Sequence[TypeRef['character']],
             link_func, requires='id'),
    ])
])

Requirements are needed when link points from non-root node.

Example with options:

graph = Graph([
    Node('user', [...]),
    Root([
        Link('users', Sequence[TypeRef['user']], func, requires=None,
             options=[Option('limit', Integer, default=100)]),
    ]),
])

Example with directives:

graph = Graph([
    Node('user', [...]),
    Root([
        Link('users', Sequence[TypeRef['user']], func, requires=None,
             options=[Option('limit', Integer, default=100)],
             directives=[Deprecated('do not use')]),
    ]),
])

Identifiers loading function protocol:

# From root node or if requires is None:

# ... if type is TypeRef['foo']
def func() -> T

# ... if type is Optional[TypeRef['foo']]
def func() -> Union[T, Nothing]

# ... if type is Sequence[TypeRef['foo']]
def func() -> List[T]

# From non-root node and requires is not None:

# ... if type is TypeRef['foo']
def func(ids) -> List[T]

# ... if type is Optional[TypeRef['foo']]
def func(ids) -> List[Union[T, Nothing]]

# ... if type is Sequence[TypeRef['foo']]
def func(ids) -> List[List[T]]

See also hiku.graph.Nothing.

If link was defined with options, then link function should accept one additional positional argument:

# many to many link with options
def func(ids, options) -> List[List[T]]

Where options is a mapping str: value of provided in the query options.

Parameters:
  • name – name of the link

  • type – type of the link

  • func – function to load identifiers of the linked node

  • requires – field name(s) from the current node, required to compute identifiers of the linked node

  • options – list of acceptable options

  • description – description of the link

  • directives – list of directives for the link

  • deprecated – deprecation reason for the link

__init__(name: str, type_: Type[TypeRef], func: Callable[[], LR | Awaitable[LR]] | Callable[[Any], LR | Awaitable[LR]] | Callable[[Any, Any], LR | Awaitable[LR]] | Callable[[List[LT]], List[LR] | Awaitable[List[LR]]] | Callable[[List[LT], Any], List[LR] | Awaitable[List[LR]]] | Callable[[Any, List[LT]], List[LR] | Awaitable[List[LR]]] | Callable[[Any, List[LT], Dict], List[LR] | Awaitable[List[LR]]], *, requires: str | List[str] | None, options: Sequence[Option] | None = None, description: str | None = None, directives: List[SchemaDirective] | None = None, deprecated: str | None = None)
__init__(name: str, type_: Type[UnionRef | InterfaceRef], func: Callable[[], LR | Awaitable[LR]] | Callable[[Any], LR | Awaitable[LR]] | Callable[[Any, Any], LR | Awaitable[LR]] | Callable[[List[LT]], List[LR] | Awaitable[List[LR]]] | Callable[[List[LT], Any], List[LR] | Awaitable[List[LR]]] | Callable[[Any, List[LT]], List[LR] | Awaitable[List[LR]]] | Callable[[Any, List[LT], Dict], List[LR] | Awaitable[List[LR]]], *, requires: str | List[str] | None, options: Sequence[Option] | None = None, description: str | None = None, directives: List[SchemaDirective] | None = None, deprecated: str | None = None)
__init__(name: str, type_: Type[Optional], func: Callable[[], LR | Const | Awaitable[LR | Const]] | Callable[[Any], LR | Const | Awaitable[LR | Const]] | Callable[[Any, Any], LR | Const | Awaitable[LR | Const]] | Callable[[List[LT]], List[LR | Const] | Awaitable[List[LR | Const]]] | Callable[[List[LT], Any], List[LR | Const] | Awaitable[List[LR | Const]]] | Callable[[Any, List[LT]], List[LR | Const] | Awaitable[List[LR | Const]]] | Callable[[Any, List[LT], Dict], List[LR | Const] | Awaitable[List[LR | Const]]], *, requires: str | List[str] | None, options: Sequence[Option] | None = None, description: str | None = None, directives: List[SchemaDirective] | None = None, deprecated: str | None = None)
__init__(name: str, type_: Type[Sequence], func: Callable[[], List[LR] | Awaitable[List[LR]]] | Callable[[Any], List[LR] | Awaitable[List[LR]]] | Callable[[Any, Any], List[LR] | Awaitable[List[LR]]] | Callable[[List[LT]], List[List[LR]] | Awaitable[List[List[LR]]]] | Callable[[List[LT], Any], List[List[LR]] | Awaitable[List[List[LR]]]] | Callable[[Any, List[LT]], List[List[LR]] | Awaitable[List[List[LR]]]] | Callable[[Any, List[LT], Dict], List[List[LR]] | Awaitable[List[List[LR]]]], *, requires: str | List[str] | None, options: Sequence[Option] | None = None, description: str | None = None, directives: List[SchemaDirective] | None = None, deprecated: str | None = None)
Parameters:
  • name – name of the link

  • type – type of the link

  • func – function to load identifiers of the linked node

  • requires – field name(s) from the current node, required to compute identifiers of the linked node

  • options – list of acceptable options

  • description – description of the link

  • directives – list of directives for the link

  • deprecated – deprecation reason for the link

class hiku.graph.Node(name: str | None, fields: List[Field | Link], *, description: str | None = None, directives: Sequence[SchemaDirective] | None = None, implements: Sequence[str] | None = None)

Collection of the fields and links, which describes some entity and relations with other entities

Example:

graph = Graph([
    Node('user', [
        Field('id', Integer, field_func),
        Field('name', String, field_func),
        Link('roles', Sequence[TypeRef['role']],
             link_func, requires='id'),
    ]),
])
Parameters:
  • name – name of the node (None if Root node)

  • fields – list of fields and links

  • description – description of the node

  • directives – list of directives for the node

  • implements – list of interfaces implemented by the node

__init__(name: str | None, fields: List[Field | Link], *, description: str | None = None, directives: Sequence[SchemaDirective] | None = None, implements: Sequence[str] | None = None)
Parameters:
  • name – name of the node (None if Root node)

  • fields – list of fields and links

  • description – description of the node

  • directives – list of directives for the node

  • implements – list of interfaces implemented by the node

class hiku.graph.Root(items: List[Field | Link])

Special implicit root node, starting point of the query execution

Example:

graph = Graph([
    Node('baz', [...]),
    Root([
        Field('foo', String, root_fields_func),
        Link('bar', Sequence[TypeRef['baz']],
             to_baz_func, requires=None),
    ]),
])
Parameters:

items – list of fields, links and singleton nodes

__init__(items: List[Field | Link])
Parameters:

items – list of fields, links and singleton nodes

class hiku.graph.Graph(items: List[Node], data_types: Dict[str, Type[Record]] | None = None, directives: Sequence[Type[SchemaDirective]] | None = None, unions: List[Union] | None = None, interfaces: List[Interface] | None = None, enums: List[BaseEnum] | None = None, scalars: List[Type[Scalar]] | None = None)

Collection of nodes - definition of the graph

Example:

graph = Graph([
    Node('foo', [...]),
    Node('bar', [...]),
    Root([...]),
])
Parameters:

items – list of nodes

__init__(items: List[Node], data_types: Dict[str, Type[Record]] | None = None, directives: Sequence[Type[SchemaDirective]] | None = None, unions: List[Union] | None = None, interfaces: List[Interface] | None = None, enums: List[BaseEnum] | None = None, scalars: List[Type[Scalar]] | None = None)
Parameters:

items – list of nodes

iter_root() Iterator[Field | Link]

Iterate over nodes, and yield fields from all root nodes.

classmethod from_graph(other: G, root: Root) G

Create graph from other graph, with new root node. Useful for creating mutation graph from query graph.

Example:

MUTATION_GRAPH = Graph.from_graph(QUERY_GRAPH, Root([…]))

hiku.graph.apply(graph: G, transformers: List[GraphTransformer]) G

Helper function to apply graph transformations

Example:

graph = hiku.graph.apply(graph, [AsyncGraphQLIntrospection()])