Skip to content

Graphite Engine API Reference

A database with its own data. Can be used multiple times to create multiple databases.

Create a new instance with:

import graphite

engine = graphite.engine()

Methods:

  • all_shortest_paths

    All shortest paths from from_node to to_end.

  • bfs

    Highly Customizable BFS

  • clear

    Clears all current structure and data.

  • connected_components

    Splits given nodes to connected components.

  • create_node

    Creates a node instance.

  • create_relation

    Creates a relation instance.

  • define_node

    Defines a node type from DSL or directly. In DSL mode (when you just pass node_type

  • define_relation

    Defines a relation type from DSL or direct creation. In DSL mode (when you just pass

  • get_node

    Returns a node with its ID.

  • get_nodes_of_type

    Get all nodes of a specific type.

  • get_relations_from

    Returns relations from a node.

  • get_relations_to

    Returns relations to a node.

  • is_node_from_type

    Returns True if given node is from given type.

  • load

    Load database from a JSON file with security checks.

  • load_dsl

    Loads Graphite DSL to the engine.

  • neighborhood

    Returns neighbors of start in given max_distance.

  • parse

    Parses and loads data from Graphite DSL to engine.

  • remove_node

    Removes given nodes.

  • remove_nodes

    Removes given nodes and all their relations.

  • remove_relation

    Removes given relations.

  • remove_relations

    Removes given relations.

  • save

    Save the database to a single JSON file.

  • shortest_path

    Finds shortest path from from_node to to_end.

  • stats

    Reports count of each type of data in database.

  • undefine_node

    Undefines a node type, remove all referenced node types, nodes, relations type,

  • undefine_relation

    Undefines a relation type and its reverse relation type (if any) and relations.

Attributes:

  • query (QueryBuilder) –

    Provides a fast and standard way to query on the engine.

Attributes

query instance-attribute

query: QueryBuilder = QueryBuilder(self)

Provides a fast and standard way to query on the engine. Use engine.query.all() to query from all nodes, or engine.query.ExampleNodeType to start query from all nodes with ExampleNodeType (or another) type. In both cases, returned value is a new instance of ready-to-used QueryResult that can be chained to build complex queries. See Query Engine Tutorials for more information.

Functions

all_shortest_paths

all_shortest_paths(from_node: Node | str, to_end: Node | str | Callable[[list[tuple[Relation, Node]]], bool] | None = None, direction: Direction = OUTGOING, relation_type: str | None = None, max_depth: int | None = None, allow_direction_switch: bool = False, ignore_nodes: set[str] | None = None, weight: str | None = None, max_results: int | None = None) -> list[tuple[str, int, list[tuple[Relation, Node]]]]

All shortest paths from from_node to to_end.

Non-weighted mode uses bfs() internally.

Wrapper

This method is a wrapper for algorithms.all_shortest_paths().

Not Implemented Completely

Weighted mode is not implemented yet.

Parameters:

  • from_node (Node | str) –

    Starting node ID or object.

  • to_end (Node | str | Callable[[list[tuple[Relation, Node]]], bool] | None, default: None ) –

    One of below:

    • None: Match on all nodes in the result. It means all (or max_results) nearest neighbors.
    • Node ID or object: Match on all paths to given node.
    • Callable ((path) -> bool): Match on a path when given callable returns True.
  • direction (Direction, default: OUTGOING ) –

    Direction to traverse.

  • relation_type (str | None, default: None ) –

    Type of relations to limit traverse.

  • max_depth (int | None, default: None ) –

    Maximum depth to traverse.

  • allow_direction_switch (bool, default: False ) –

    If True allow direction switch in a path when direction=Direction.BOTH.

  • ignore_nodes (set[str] | None, default: None ) –

    Visited set of node IDs to ignore.

  • weight (str | None, default: None ) –

    Optional field name to weighted pathfinding.

  • max_results (int | None, default: None ) –

    Maximum number of results to return.

Returns:

  • list[tuple[str, int, list[tuple[Relation, Node]]]]

    An empty list or a list of found paths sorted by distance with each item as:

    (destination_node_id, path_depth, [(step_relation_obj, step_node_obj), ...])
                                      ^^^^^^^  path_to_destination_node  ^^^^^^^
    
    path_depth is 0 for starting node, it means this is equal to the size of path_to_destination_node.

bfs

bfs(start: Node | str, end: Node | str | Callable[[list[tuple[Relation, Node]]], bool] | None = None, stop_at_first: bool = True, direction: Direction = OUTGOING, relation_type: str | None = None, max_depth: int | None = None, include_start: bool = False, allow_direction_switch: bool = False, visited: set[str] | None = None, max_results: int | None = None) -> list[tuple[str, int, list[tuple[Relation, Node]]]]

Highly Customizable BFS (Breadth-First Search) in the graph.

Note

Steps are sorted by distance in returned result.

Wrapper

This method is a wrapper for algorithms.bfs().

Parameters:

  • start (Node | str) –

    Starting node ID or object.

  • end (Node | str | Callable[[list[tuple[Relation, Node]]], bool] | None, default: None ) –

    One of below:

    • None: Match on all nodes in the result.
    • Node ID or object: Match on all paths to given node.
    • Callable ((path) -> bool): Match on a path when given callable returns True.
  • stop_at_first (bool, default: True ) –

    If True and end is provided, stops at first match.

  • direction (Direction, default: OUTGOING ) –

    Direction to traverse.

  • relation_type (str | None, default: None ) –

    Type of relations to limit traverse.

  • max_depth (int | None, default: None ) –

    Maximum depth to traverse.

  • include_start (bool, default: False ) –

    If True check starting node on result.

  • allow_direction_switch (bool, default: False ) –

    If True allow direction switch in a path when direction=Direction.BOTH.

  • visited (set[str] | None, default: None ) –

    Visited set of node IDs to ignore.

  • max_results (int | None, default: None ) –

    Maximum number of results to return.

Returns:

  • list[tuple[str, int, list[tuple[Relation, Node]]]]

    An empty list or a list of found paths sorted by distance with each item as:

    (destination_node_id, path_depth, [(step_relation_obj, step_node_obj), ...])
                                      ^^^^^^^  path_to_destination_node  ^^^^^^^
    
    path_depth is 0 for starting node, it means this is equal to the size of path_to_destination_node.

clear

clear() -> None

Clears all current structure and data.

connected_components

connected_components(nodes: Node | str | set[Node | str] | None = None, return_all_nodes: bool = False, direction: Direction = OUTGOING, relation_type: str | None = None, allow_direction_switch: bool = False, ignore_nodes: set[str] | None = None) -> list[set[str]]

Splits given nodes to connected components.

Wrapper

This method is a wrapper for algorithms.connected_components().

Note

Uses bfs() internally.

Parameters:

  • nodes (Node | str | set[Node | str] | None, default: None ) –

    One or a set of node (objects or IDs) to group, or None to get all nodes from engine.

  • return_all_nodes (bool, default: False ) –

    If True, includes all nodes in each component, not just intersection of them with input nodes. Has no effect when nodes = None. False is unusual when using a single node.

  • direction (Direction, default: OUTGOING ) –

    Direction to traverse.

  • relation_type (str | None, default: None ) –

    Type of relations to allow traverse.

  • allow_direction_switch (bool, default: False ) –

    If True, allow direction switch in a path when direction = Direction.BOTH.

  • ignore_nodes (set[str] | None, default: None ) –

    Node IDs to ignore.

Returns:

create_node

create_node(node_type: str, node_id: str, *values: Any, parse_fields: bool = False) -> Node

Creates a node instance.

Note

You can use DSL to create nodes, with parse() method:

engine.parse("""
    Person, alice, 'Alice', 32, 'alice@emial.com'
    Person, bob, "Bob", 28, 'bob.mail@email.com'
""")
This is same as:
engine.create_node("Person", "alice", "Alice", 32, "alice@emial.com")
engine.create_node("Person", "bob", "Bob", 28, "bob.mail@email.com")
Advantage is that you can do any number of node creation and other data manipulation with passing a multi-line value to parse().

Parameters:

  • node_type (str) –

    Node type name, defined with define_node() or parse().

  • node_id (str) –

    Node ID.

  • *values (Any, default: () ) –

    Values for node fields.

    Note

    Count of values passed to values must be same as node type definition. Node types inheritance from base types define with from ... or parent parameter in define_node(); So if you have a Person node type and a User node type inherited from it like this:

    node Person
            name: string
            age: int
    
    node User from Person
            username: string
            email: string
    
    You should pass values as <name>, <age>, <username>, <email> (4 values) when you need to create a node from User type.

  • parse_fields (bool, default: False ) –

    If True, parse field values from raw strings.

    Note

    Date values will be parsed automatically, even when parse_fields is False.

Returns:

  • Node

    Node instance added to engine.

Raises:

  • NotFoundError

    If node_type not defined.

  • InvalidPropertiesError

    If values count is not same as node type field count.

  • FieldError

    If values fail in parsing, converting, or validation.

create_relation

create_relation(from_id: str, to_id: str, rel_type: str, *values: Any, parse_fields: bool = False) -> Relation

Creates a relation instance.

Note

You can use DSL to create relations, with parse() method:

engine.parse("alice -[WORKS_AT, 'Designer', 120000, 2026-01-07]-> google")
This is same as:
engine.create_relation(
    "alice",
    "google",
    "WORKS_AT",
    "Designer", 120000, 2026-01-07 # or date(2026, 1, 7), will be parsed automatically.
)
Advantage is that you can do any number of relation creation and other data manipulation with passing a multi-line value to parse().

Parameters:

  • from_id (str) –

    Source node's ID.

  • to_id (str) –

    Target node's ID.

  • rel_type (str) –

    Relation type name, defined with define_relation() or parse().

  • *values (Any, default: () ) –

    Values for relation fields.

  • parse_fields (bool, default: False ) –

    If True, parse field values from raw strings.

    Note

    Date values will be parsed automatically, even when parse_fields is False.

Returns:

  • Relation

    Created relation instance, added to editor.

Raises:

  • NotFoundError

    If rel_type, from_id, or to_id not defined.

  • InvalidRelationError

    When the type of source or target node doesn't match relation

  • InvalidPropertiesError

    If values count is not same as relation type field count.

    Note

    Relation types doesn't support inheritance, so instance's value count match the exact number of relation type's fields.

  • FieldError

    If values fail in parsing, converting, or validation.

define_node

define_node(node_type: str, *fields: tuple[str, str], parent: str | None = None) -> None

Defines a node type from DSL or directly. In DSL mode (when you just pass node_type parameter), only supports one block starting with "node ..." (Use parse() for multiple blocks).

Example
engine.define_node("""
    node Person
        name: string
        age: int
""")
# Same as above:
engine.define_node(
    "Person",
    ("name", "string"),
    ("age", "int")
)

Parameters:

  • node_type (str) –

    Node definition string in Graphite DSL or type name.

  • fields (tuple[str, str], default: () ) –

    Fields of node type: (name, type).

  • parent (str | None, default: None ) –

    Parent node type name, You must pass it positional.

Raises:

  • ParseError

    If node type definition is not valid (When passing DSL string as node_type).

  • NotFoundError

    If parent node type (from ...) is not found.

  • NotFoundError

    If any type (second) item of any fields values not found.

define_relation

define_relation(relation_type: str, source_type: str | None = None, target_type: str | None = None, *fields: tuple[str, str], reverse_name: str | None = None, is_bidirectional: bool = False) -> None

Defines a relation type from DSL or direct creation. In DSL mode (when you just pass relation_type parameter), only supports one block starting with "relation ..." (Use parse() for multiple blocks).

Example
engine.define_relation("""
    node WORKS_AT
        Person -> Company
        position: string
        salary: int
        since: date
""")
# Same as above:
engine.define_relation(
    "WORKS_AT",
    "Person",
    "Company",
    ("position", "string"),
    ("salary", "int"),
    ("since", "date")
)

Parameters:

  • relation_type (str) –

    Relation definition string in Graphite DSL or type name.

  • source_type (str | None, default: None ) –

    Valid source node type name.

  • target_type (str | None, default: None ) –

    Valid target node type name.

  • *fields (tuple[str, str], default: () ) –

    Fields of relation type: (name, type).

  • reverse_name (str | None, default: None ) –

    Reverse relation name (if any).

  • is_bidirectional (bool, default: False ) –

    Is bidirectional relation or not.

Raises:

  • ParseError

    If relation definition is not valid.

  • ParseError

    If omit source_type or target_type outside DSL mode.

  • RelationTypeDefineError

    If relation type DSL have both reverse ... section and both flag.

  • NotFoundError

    If source or target node types are not found.

  • NotFoundError

    If any type (second) item of any fields values not found.

get_node

get_node(node_id: str) -> Node

Returns a node with its ID.

Parameters:

  • node_id (str) –

    Target node ID string.

Returns:

  • Node

    Node object.

Raises:

  • NotFoundError

    If node_id not defined.

get_nodes_of_type

get_nodes_of_type(node_type: str, with_subtypes: bool = True) -> set[Node]

Get all nodes of a specific type.

Parameters:

  • node_type (str) –

    Node type name.

  • with_subtypes (bool, default: True ) –

    If with_subtypes is True, adds all subtypes of given node type recursively to the result.

Returns:

  • set[Node]

    Set of node objects

Raises:

  • NotFoundError

    If node_type not defined.

get_relations_from

get_relations_from(node_id: str, rel_type: str | None = None) -> set[Relation]

Returns relations from a node.

Parameters:

  • node_id (str) –

    Node ID string.

  • rel_type (str | None, default: None ) –

    Relation type to filter on, or None to accept all types.

Returns:

Raises:

  • NotFoundError

    If rel_type or node_id not defined.

get_relations_to

get_relations_to(node_id: str, rel_type: str | None = None) -> set[Relation]

Returns relations to a node.

Parameters:

  • node_id (str) –

    Node ID string.

  • rel_type (str | None, default: None ) –

    Relation type to filter on, or None to accept all types.

Returns:

Raises:

  • NotFoundError

    if rel_type or node_id not defined

is_node_from_type

is_node_from_type(node_id: str, node_type: str) -> bool

Returns True if given node is from given type.

Note

This method considers type inheritance, so in this database:

type Person
    → type User
        → instance alice
Alice is from User type and any User is a Person, so is_node_from_type( 'alice', 'Person') returns True. If you need a direct inheritance check use alice.type_name == ..., which returns False for "Person".

Parameters:

  • node_id (str) –

    Node ID.

  • node_type (str) –

    Node type name.

Returns:

  • bool

    True if given node is from given type otherwise False.

Raises:

  • NotFoundError

    If given node_id or node_type not defined.

load

load(file_path: str, max_size_mb: int | float | None = 100, validate_schema: bool = True, accept_any_extension: bool = False) -> None

Load database from a JSON file with security checks.

Caution

This method will call clear() before loading data to database, it means all current data will be removed.

Parameters:

  • file_path (str) –

    File path to load.

  • max_size_mb (int | float | None, default: 100 ) –

    Maximum allowed file size in MB, or None to disable check.

  • validate_schema (bool, default: True ) –

    Validates schema consistency if True.

  • accept_any_extension (bool, default: False ) –

    If True, accept any file extension, otherwise just .json is valid.

Raises:

  • FileSizeError

    For files bigger than max_size_mb when provided.

  • SafeLoadExtensionError

    For files without .json extension when accept_any_extension is True.

  • InvalidJSONError

    For error at decoding process.

  • TooNestedJSONError

    For recursion error (is almost impossible).

  • ValidationError

    For invalid schema when schema validate_schema is True.

load_dsl

load_dsl(dsl: str) -> None

Loads Graphite DSL to the engine.

Deprecated

This method is deprecated, use parse() instead. Internally uses new method.

neighborhood

neighborhood(start: Node | str, max_distance: int | None = None, filter_method: Callable[[list[tuple[Relation, Node]]], bool] | None = None, max_results: int | None = None, direction: Direction = OUTGOING, relation_type: str | None = None, allow_direction_switch: bool = False, ignore_nodes: set[str] | None = None) -> tuple[set[tuple[Node, int]], set[Relation]]

Returns neighbors of start in given max_distance.

Wrapper

This method is a wrapper for algorithms.neighborhood().

Note

Uses bfs() internally.

Parameters:

  • start (Node | str) –

    Starting node object or ID.

  • max_distance (int | None, default: None ) –

    Maximum distance to traverse.

  • filter_method (Callable[[list[tuple[Relation, Node]]], bool] | None, default: None ) –

    Optional callable to filter neighbors ((path) -> bool).

  • max_results (int | None, default: None ) –

    Maximum number of results to return.

  • direction (Direction, default: OUTGOING ) –

    Direction to traverse.

  • relation_type (str | None, default: None ) –

    Type of relations to allow traverse.

  • allow_direction_switch (bool, default: False ) –

    If True, allow direction switch in a path when direction = Direction.BOTH.

  • ignore_nodes (set[str] | None, default: None ) –

    Node IDs to ignore.

Returns:

parse

parse(data: str) -> None

Parses and loads data from Graphite DSL to engine.

See DSL Reference for syntax and specification.

Parameters:

  • data (str) –

    Data as Graphite DSL string.

Raises:

  • ParseError

    When failed to parse data.

    Note

    This method is semi-atomic, it means it will apply changes for each block and then goes to next block. When any errors occur in a block , blocks above it are applied to the engine. So it's recommend to use this method just once for an engine.

  • NotFoundError

    If parent node type (from ...) is not found when defining a node type. NotFoundError: If any invalid data type used in fields when defining a node type or relation type.

  • RelationTypeDefineError

    If relation type DSL have both reverse ... section and both flag when defining a relation type..

  • NotFoundError

    If source or target node types are not found when defining a relation type.

  • InvalidPropertiesError

    If values count is not same as node type or relation type field count when creating a node or relation.

  • FieldError

    If values fail in parsing, converting, or validation when creating a node or relation.

  • NotFoundError

    If relation type, source node ID, or target node ID not found when creating a relation.

  • InvalidRelationError

    When the type of source or target node doesn't match relation type signature when creating a relation.

remove_node

remove_node(node: Node | str | list[Node | str]) -> None

Removes given nodes.

Deprecated

This method is deprecated, use remove_nodes() instead. Internally uses new method.

remove_nodes

remove_nodes(nodes: Node | str | set[Node | str] | list[Node | str] | set[Node] | set[str] | list[Node] | list[str]) -> None

Removes given nodes and all their relations.

Important

When removing multiple nodes, this method is significantly faster than calling it repeatedly because indexes are rebuilt only once.

Parameters:

Raises:

  • NotFoundError

    If any node is not found.

remove_relation

remove_relation(relation: Relation | set[Relation] | list[Relation]) -> None

Removes given relations.

Deprecated

This method is deprecated, use remove_relations() instead. Internally uses new method.

remove_relations

remove_relations(relations: Relation | set[Relation] | list[Relation]) -> None

Removes given relations.

Parameters:

Raises:

  • NotFoundError

    If any relation is not found.

save

save(file_path: str) -> None

Save the database to a single JSON file.

Parameters:

  • file_path (str) –

    File path to save.

shortest_path

shortest_path(from_node: Node | str, to_end: Node | str | Callable[[list[tuple[Relation, Node]]], bool] | None = None, direction: Direction = OUTGOING, relation_type: str | None = None, max_depth: int | None = None, allow_direction_switch: bool = False, ignore_nodes: set[str] | None = None, weight: str | None = None) -> tuple[str, int, list[tuple[Relation, Node]]] | None

Finds shortest path from from_node to to_end.

Non-weighted mode uses bfs() internally.

Wrapper

This method is a wrapper for algorithms.shortest_path().

Not Implemented Completely

Weighted mode is not implemented yet.

Parameters:

  • from_node (Node | str) –

    Starting node Id or object.

  • to_end (Node | str | Callable[[list[tuple[Relation, Node]]], bool] | None, default: None ) –

    One of below:

    • None: Match on all nodes in the result. It means nearest neighbor.
    • Node ID or object: Match on all paths to given node.
    • Callable ((path) -> bool): Match on a path when given callable returns True.
  • direction (Direction, default: OUTGOING ) –

    Direction to traverse.

  • relation_type (str | None, default: None ) –

    Type of relations to allow traverse.

  • max_depth (int | None, default: None ) –

    Maximum depth to traverse.

  • allow_direction_switch (bool, default: False ) –

    If True allow direction switch in a path when direction = Direction.BOTH.

  • ignore_nodes (set[str] | None, default: None ) –

    Node IDs to ignore.

  • weight (str | None, default: None ) –

    Optional field name to weighted pathfinding. (Not implemented yet)

Returns:

  • tuple[str, int, list[tuple[Relation, Node]]] | None

    None or the shortest found path as:

    (destination_node_id, path_depth, [(step_relation_obj, step_node_obj), ...])
                                      ^^^^^^^  path_to_destination_node  ^^^^^^^
    
    path_depth is 0 for starting node, it means this is equal to the size of path_to_destination_node.

stats

stats() -> dict[str, Any]

Reports count of each type of data in database.

Returns:

undefine_node

undefine_node(node_type: str) -> None

Undefines a node type, remove all referenced node types, nodes, relations type, and relations.

Parameters:

  • node_type (str) –

    Node type name.

Raises:

  • NotFoundError

    If node_type not defined.

undefine_relation

undefine_relation(relation_type: str, _is_reverse: bool = False) -> None

Undefines a relation type and its reverse relation type (if any) and relations.

Parameters:

  • relation_type (str) –

    Relation type name.

Other Parameters:

  • _is_reverse (bool) –

    For internal use to remove reverse direction relation type.

    Hack: Undefine a type without undefining its reverse relation type

    You can disable deletion of reverse relation type with passing True to this parameter, but this can lead to unpredictable results.

Raises:

  • NotFoundError

    if relation_type not defined