Skip to content

Navigation API

Read-only, engine-abstracted traversal of the knowledge graph. For tutorials and recipes see the Graph Navigation user guide.

The graph store is pluggable, exactly like the storage layer: an engine-agnostic GraphNavigator ABC plus a concrete Neo4jGraphNavigator, selected by the graph_backend config field (env GRAPH_BACKEND, default "neo4j").

Factory

scinr.newton.navigation.factory

navigation/factory.py — Graph-navigator factory.

Mirrors storage/factory.py: the concrete backend is chosen from ScinrConfig.graph_backend (env GRAPH_BACKEND, default "neo4j"), so call sites never name an engine.

get_graph_navigator async

get_graph_navigator() -> GraphNavigator

Return a connected :class:GraphNavigator for the configured backend.

The connection is verified eagerly (connect()ping()).

Returns:

Type Description
GraphNavigator

A ready-to-use navigator. The caller is responsible for

GraphNavigator

meth:GraphNavigator.close — or use :func:graph_navigator instead.

Raises:

Type Description
ConfigurationError

If graph_backend is unknown, or the library is not configured.

GraphConnectionError

If the engine is unreachable.

graph_navigator async

graph_navigator() -> AsyncIterator[GraphNavigator]

Async context manager that yields a connected navigator and closes it.

Example

async with graph_navigator() as nav: ... roots = await nav.list_root_documents()

Base Interface

scinr.newton.navigation.base

navigation/base.py — GraphNavigator, the engine-agnostic navigation interface.

A :class:GraphNavigator is a read-only, fully async view over the knowledge graph produced by scinr.newton. Concrete backends translate each call to their native query language; the only backend today is navigation.neo4j.Neo4jGraphNavigator.

Nothing on this interface mutates the graph. The single non-portable seam is :meth:GraphNavigator.execute_raw (and its one-row sibling): an optional escape hatch whose query string is written in the backend's own dialect.

Conventions

  • Every method is async.
  • Return types come from navigation.models and are engine-neutral.
  • A single-get method returns SomeRef | None only when its arguments form a full unique key. Any looser selector returns a list.
  • Every method that walks a variable-length path takes depth: int | None. depth=None = "no explicit limit" → the backend applies :data:DEFAULT_MAX_DEPTH as a runaway-traversal guard (not a hard ceiling). depth=1 = direct only. An explicit n is used verbatim.
  • Filter values passed via where= / key selectors are used verbatim — the caller is responsible for any normalisation (instance-key values, for instance, are stored lower-cased and accent-stripped by ingestion).
  • List methods take limit: int | None = None and skip: int = 0 and order deterministically. Dynamic filters are only applied when supplied.

GraphNavigator

Bases: ABC

Engine-agnostic, read-only navigation over the scinr.newton graph.

Obtain an instance with :func:scinr.newton.navigation.get_graph_navigator or the :func:scinr.newton.navigation.graph_navigator async context manager rather than constructing a backend directly.

close abstractmethod async

close() -> None

Release any resources this navigator owns.

Never closes a connection handed in from outside (e.g. a shared driver).

connect abstractmethod async

connect() -> None

Acquire the backend connection and verify it is reachable.

Raises:

Type Description
GraphConnectionError

If the engine cannot be reached.

count_document_model_instances abstractmethod async

count_document_model_instances(
    document: _Selector,
    *,
    version: int | None = None,
    model_class: str | None = None,
    where: _Where = None,
    depth: int | None = None,
) -> int

Count the instances :meth:get_document_model_instances would return.

Accepts the same where= property filter (see :mod:scinr.newton.navigation.filters).

count_info_units abstractmethod async

count_info_units(
    document: _Selector,
    *,
    version: int | None = None,
    depth: int | None = None,
) -> int

Count the info units of document.

count_model_instances_by_class abstractmethod async

count_model_instances_by_class(
    model_class: str,
    *,
    where: _Where = None,
    document: _Selector | None = None,
) -> int

Count the instances :meth:get_model_instances_by_class would return.

Accepts the same where= property filter (see :mod:scinr.newton.navigation.filters).

count_root_documents abstractmethod async

count_root_documents(
    *,
    latest_only: bool = True,
    only_folders: bool = False,
    only_leaves: bool = False,
) -> int

Count the documents :meth:list_root_documents would return.

count_structure_nodes abstractmethod async

count_structure_nodes(
    document: _Selector,
    *,
    version: int | None = None,
    roles: Sequence[str] | None = None,
    depth: int | None = None,
) -> int

Count the structure nodes :meth:get_structure_nodes would return.

describe_node abstractmethod async

describe_node(
    node_id: str, *, include_source_text: bool = False
) -> NodeDescription | None

Return an aggregate view of node_id: info units, decision, extraction, ….

document_exists abstractmethod async

document_exists(
    path: str, *, version: int | None = None
) -> bool

Return whether a document exists at path (any version, or a specific one).

execute_raw async

execute_raw(
    query: str,
    params: Mapping[str, Any] | None = None,
    *,
    dialect: str | None = None,
) -> list[dict[str, Any]]

Run a raw, engine-native read query and return raw records.

NON-PORTABLE: query is written in :attr:dialect. Prefer a typed method; reach for this only for one-off queries the typed API cannot express.

Parameters:

Name Type Description Default
query str

An engine-native read query.

required
params Mapping[str, Any] | None

Query parameters (values are always sent parameterised).

None
dialect str | None

If given and it does not equal :attr:dialect, the call fails immediately.

None

Returns:

Type Description
list[dict[str, Any]]

A list of plain dict records (never *Ref models).

Raises:

Type Description
UnsupportedOperationError

If this backend has no raw-query path.

NavigationError

If query contains a write clause, or dialect does not match.

execute_raw_one async

execute_raw_one(
    query: str,
    params: Mapping[str, Any] | None = None,
    *,
    dialect: str | None = None,
) -> dict[str, Any] | None

Like :meth:execute_raw but return the first record or None.

find_shell_model_instances abstractmethod async

find_shell_model_instances(
    *,
    model_class: str | None = None,
    limit: int | None = None,
) -> list[ModelInstanceRef]

Return likely "shell" instances (only key properties populated).

find_structure_nodes abstractmethod async

find_structure_nodes(
    *,
    title_contains: str | None = None,
    node_id: str | None = None,
    role: str | None = None,
    theme: str | None = None,
    document: _Selector | None = None,
    where: _Where = None,
    limit: int | None = None,
    skip: int = 0,
) -> list[StructureNodeRef]

Search structure nodes across all documents.

where= takes {property_name: value | Op} filters on the node — e.g. where={"role": In(["section", "subsection"])}. See :mod:scinr.newton.navigation.filters.

get_annotation_coverage abstractmethod async

get_annotation_coverage(
    document: _Selector,
    *,
    version: int | None = None,
    depth: int | None = None,
) -> AnnotationCoverage | None

Return annotated / unannotated / matched / proposed counts and ratio.

get_catalog_graph abstractmethod async

get_catalog_graph(
    *,
    include_fields: bool = True,
    include_relationships: bool = True,
) -> CatalogGraph

Return the whole model catalogue — :CatalogModel / :EntityLabel nodes plus the declared relationships between them (AGGREGATES and the domain relationship declarations with their join_via / via_field metadata).

get_child_documents abstractmethod async

get_child_documents(
    path: str,
    *,
    depth: int | None = 1,
    version: int | None = None,
    is_folder: bool | None = None,
    limit: int | None = None,
) -> list[DocumentRef]

Walk IS_COMPOSED_OF downward from pathchild documents only.

Flat, deduplicated. depth=1 returns the immediate children.

get_child_nodes abstractmethod async

get_child_nodes(
    node_id: str,
    *,
    depth: int | None = 1,
    roles: Sequence[str] | None = None,
    limit: int | None = None,
) -> list[StructureNodeRef]

Walk HAS_CHILD downward from node_id. Flat list.

get_document_ancestors abstractmethod async

get_document_ancestors(
    path: str,
    *,
    version: int | None = None,
    depth: int | None = None,
) -> DocumentTree | None

Return the ancestor lineage of path as a single-spine tree.

The result is the root folder-parent, its children a chain leading down to (but not including) path. Flatten it for a plain list; keep it to render the hierarchy. None when path is itself a root.

get_document_entities abstractmethod async

get_document_entities(
    document: _Selector,
    *,
    label: str | None = None,
    version: int | None = None,
    depth: int | None = None,
    limit: int | None = None,
) -> list[LabeledEntityRef]

Return labeled entities referenced anywhere in document.

get_document_extraction_results abstractmethod async

get_document_extraction_results(
    document: _Selector,
    *,
    version: int | None = None,
    model_class: str | None = None,
    depth: int | None = None,
    limit: int | None = None,
) -> list[ExtractionResultWithNode]

Return the extraction results of document, each carrying its node.

get_document_leaves abstractmethod async

get_document_leaves(
    path: str,
    *,
    version: int | None = None,
    depth: int | None = None,
) -> list[DocumentRef]

Return descendants of path with no outgoing IS_COMPOSED_OF.

get_document_model_decisions abstractmethod async

get_document_model_decisions(
    document: _Selector,
    *,
    version: int | None = None,
    matched_only: bool | None = None,
    depth: int | None = None,
) -> list[ModelDecisionWithNode]

Return the model decisions of document, each carrying its node.

get_document_model_instances abstractmethod async

get_document_model_instances(
    document: _Selector,
    *,
    version: int | None = None,
    model_class: str | None = None,
    where: _Where = None,
    depth: int | None = None,
    limit: int | None = None,
    skip: int = 0,
) -> list[ModelInstanceRef]

Return every :ModelInstance extracted anywhere in document (deduped).

where= filters the instances by property ({property_name: value | Op}, values matched verbatim) — e.g. where={"status": "active"}. See :mod:scinr.newton.navigation.filters.

get_document_model_profile abstractmethod async

get_document_model_profile(
    document: _Selector,
    *,
    version: int | None = None,
    depth: int | None = None,
) -> DocumentModelProfile | None

Return how document was semantically catalogued — a roll-up of the matched and complementary model classes across all its decisions, with per-class counts, without the individual decisions.

get_document_of_node abstractmethod async

get_document_of_node(node_id: str) -> DocumentRef | None

Return the document that owns node_id (by traversal, not id-parsing).

get_document_parent abstractmethod async

get_document_parent(
    path: str, *, version: int | None = None
) -> DocumentRef | None

Return the immediate folder-parent of path, or None for a root.

get_document_stats abstractmethod async

get_document_stats(
    path: str, *, version: int | None = None
) -> DocumentStats | None

Return aggregate counts (nodes by role, instances by class, …) for a document.

get_document_tree abstractmethod async

get_document_tree(
    path: str,
    *,
    depth: int | None = None,
    version: int | None = None,
) -> DocumentTree | None

Return the nested IS_COMPOSED_OF subtree rooted at path.

get_documents abstractmethod async

get_documents(
    *,
    path: str | None = None,
    name_contains: str | None = None,
    version: int | None = None,
    latest_only: bool = True,
    is_folder: bool | None = None,
    path_prefix: str | None = None,
    where: _Where = None,
    limit: int | None = None,
    skip: int = 0,
) -> list[DocumentRef]

Find documents by any combination of filters. Always a list.

Only the filters you pass are applied. Anything looser than the full (path, version) key can match more than one node.

Parameters:

Name Type Description Default
where _Where

Property filters on the :Document node, as {property_name: value | Op}. A bare value means equality; the operator objects (Eq, In, Gte, Contains, IsNotNull, …) cover the rest. Values are matched verbatim and always parameterised, and are ANDed with the other arguments and with latest_only.

None

Examples:

A bare value is an equality test::

await nav.get_documents(where={"tenant_id": "acme"})

Operator objects for anything else::

from scinr.newton.navigation import In, IsNotNull, StartsWith

await nav.get_documents(where={
    "job_id": In(["job-1", "job-2"]),
    "created_by_user_id": IsNotNull(),
    "raw_file_id": StartsWith("s3://bucket/"),
})
See Also

:mod:scinr.newton.navigation.filters — the full operator set and the where= contract (property-name rules, verbatim values).

get_documents_for_model_instance abstractmethod async

get_documents_for_model_instance(
    uid: str,
) -> list[DocumentRef]

Return the document(s) that contain instance uid. Always a list.

get_entity_relationships abstractmethod async

get_entity_relationships(
    uid: str,
    *,
    direction: Literal["out", "in", "both"] = "both",
    rel_type: str | None = None,
) -> list[EntityRelation]

Return Level-2 field_relationships edges of labeled entity uid.

Discriminated by both endpoints being :LabeledEntity — some of these types happen to start with HAS_.

get_entity_triples abstractmethod async

get_entity_triples(
    value_or_uid: str,
    *,
    direction: Literal["out", "in", "both"] = "both",
) -> list[Triple]

Return triples touching the :Entity identified by value or uid.

get_extraction_result abstractmethod async

get_extraction_result(
    node_id: str,
) -> ExtractionResultRef | None

Return the extraction result for node_id, or None.

get_extraction_results_for_model_instance abstractmethod async

get_extraction_results_for_model_instance(
    uid: str,
) -> list[ExtractionResultRef]

Return the extraction result(s) that reach instance uid. Always a list.

get_graph_summary abstractmethod async

get_graph_summary() -> GraphSummary

Return whole-graph counts by node type and (structural) relationship type.

get_incoming_model_instances abstractmethod async

get_incoming_model_instances(
    uid: str,
    *,
    rel_type: str | None = None,
    depth: int | None = 1,
    limit: int | None = None,
) -> list[ModelInstanceRef]

Return :ModelInstance nodes with an edge into uid (any rel type).

Each carries via_rel and direction="in".

get_info_unit abstractmethod async

get_info_unit(uid: str) -> InfoUnitRef | None

Return the info unit with this uid, or None.

get_info_units abstractmethod async

get_info_units(
    node_id: str, *, order_by: str = "order"
) -> list[InfoUnitRef]

Return the info units of one structure node.

get_labeled_entities abstractmethod async

get_labeled_entities(
    *,
    label: str | None = None,
    value: str | None = None,
    normalized_value: str | None = None,
    where: _Where = None,
    limit: int | None = None,
    skip: int = 0,
) -> list[LabeledEntityRef]

Find labeled entities by label / value / normalised value / where=.

where= takes {property_name: value | Op} filters on the :LabeledEntity node — e.g. where={"label": In(["Country", "ProcedureType"])}. See :mod:scinr.newton.navigation.filters.

get_labeled_entity abstractmethod async

get_labeled_entity(uid: str) -> LabeledEntityRef | None

Return the labeled entity with this uid, or None.

get_latest_version abstractmethod async

get_latest_version(path: str) -> DocumentRef | None

Return the latest=true document at path, or None.

get_model_decision abstractmethod async

get_model_decision(node_id: str) -> ModelDecisionRef | None

Return the model decision for node_id, or None if unannotated.

get_model_instance abstractmethod async

get_model_instance(uid: str) -> ModelInstanceRef | None

Return the :ModelInstance with this uid, or None.

get_model_instance_by_key abstractmethod async

get_model_instance_by_key(
    model_class: str, key_fields: Mapping[str, str]
) -> ModelInstanceRef | None

Return the instance whose deterministic instance_key uid matches.

key_fields maps each instance_key field name to its value. Values are normalised (NFKD, accent-stripped, lower-cased, whitespace-collapsed) before the uid is rebuilt — same as ingestion.

get_model_instance_entities abstractmethod async

get_model_instance_entities(
    uid: str, *, label: str | None = None
) -> list[LabeledEntityRef]

Return labeled entities that instance uid REFERENCES.

get_model_instance_relationships abstractmethod async

get_model_instance_relationships(
    uid: str,
    *,
    direction: Literal["out", "in", "both"] = "both",
    rel_type: str | None = None,
) -> list[ModelInstanceRelation]

Return every edge between uid and another :ModelInstance.

No relationship-type filtering by default — containment (HAS_*) and typed cross-references alike, each with its rel_type and direction.

get_model_instance_subtree abstractmethod async

get_model_instance_subtree(
    uid: str, *, depth: int | None = None
) -> ModelInstanceTree | None

Return the outgoing-edge subtree rooted at instance uid.

get_model_instances_by_class abstractmethod async

get_model_instances_by_class(
    model_class: str,
    *,
    where: _Where = None,
    document: _Selector | None = None,
    order_by: str | None = None,
    limit: int | None = None,
    skip: int = 0,
) -> list[ModelInstanceRef]

Return :ModelInstance nodes of model_class, filtered by where=.

Parameters:

Name Type Description Default
where _Where

Property filters on the instance, as {property_name: value | Op}. A bare value means equality. Values are matched verbatim — normalise them yourself (instance-key / entity values are stored lower-cased & accent-stripped by ingestion; see :func:scinr.newton.utils.uid.normalize_key).

None
order_by str | None

Instance property to sort by (validated as an identifier); defaults to uid.

None

Examples:

::

from scinr.newton.navigation import In, Gte

await nav.get_model_instances_by_class(
    "VariationCodeModel",
    where={"procedure_type": In(["ia", "ib"]), "confidence": Gte(0.8)},
    order_by="procedure_type",
    limit=50,
)

Use :meth:get_model_properties to discover which property names a class actually carries.

See Also

:mod:scinr.newton.navigation.filters — the full operator set and the where= contract.

get_model_instances_referencing_entity abstractmethod async

get_model_instances_referencing_entity(
    uid: str,
    *,
    model_class: str | None = None,
    limit: int | None = None,
) -> list[ModelInstanceRef]

Return instances that REFERENCES labeled entity uid (reverse lookup).

get_model_properties abstractmethod async

get_model_properties(
    model_class: str, *, document: _Selector | None = None
) -> dict[str, list[str]]

Return {"declared": [...], "observed": [...]} property names for model_class — the catalog-declared :ModelField names and the names actually seen on a sample of its instances.

get_node_ancestors abstractmethod async

get_node_ancestors(
    node_id: str, *, depth: int | None = None
) -> list[StructureNodeRef]

Return the ancestors of node_id, ordered root → immediate parent.

get_node_entities abstractmethod async

get_node_entities(
    node_id: str,
    *,
    label: str | None = None,
    depth: int | None = None,
) -> list[LabeledEntityRef]

Return labeled entities referenced by any model instance under node_id.

REFERENCES always originates from a :ModelInstance; the walk is node → HAS_EXTRACTION → (HAS_* )* → ModelInstance → REFERENCES.

get_node_for_info_unit abstractmethod async

get_node_for_info_unit(uid: str) -> StructureNodeRef | None

Return the structure node that owns info unit uid.

get_node_model_instances abstractmethod async

get_node_model_instances(
    node_id: str,
    *,
    model_class: str | None = None,
    where: _Where = None,
    depth: int | None = None,
    direct_only: bool = False,
) -> list[ModelInstanceRef]

Return the :ModelInstance nodes extracted at node_id.

Reached via HAS_EXTRACTION then HAS_* containment edges — this is the "belongs to this node" set, not arbitrary cross-references.

where= filters the instances by property ({property_name: value | Op}, values matched verbatim); see :mod:scinr.newton.navigation.filters.

get_node_path abstractmethod async

get_node_path(node_id: str) -> NodePath | None

Return the document plus the node chain from its root down to node_id.

get_nodes_by_annotated_model abstractmethod async

get_nodes_by_annotated_model(
    model_class: str, *, document: _Selector | None = None
) -> list[StructureNodeRef]

Return structure nodes whose decision matched model_class.

get_nodes_by_theme abstractmethod async

get_nodes_by_theme(
    theme: str,
    *,
    document: _Selector | None = None,
    limit: int | None = None,
) -> list[StructureNodeRef]

Return structure nodes carrying theme.

get_nodes_referencing_entity abstractmethod async

get_nodes_referencing_entity(
    uid: str,
    *,
    depth: int | None = None,
    limit: int | None = None,
) -> list[StructureNodeRef]

Return structure nodes whose model instances reference entity uid.

Walk: LabeledEntity ← REFERENCES ← ModelInstance ← (HAS_*)* ← ExtractionResult ← HAS_EXTRACTION ← StructureNode.

get_one_document abstractmethod async

get_one_document(
    path: str, version: int
) -> DocumentRef | None

Return the document with exactly this (path, version) composite key.

Both arguments are mandatory — this is the unique key. No "latest" resolution happens here.

Returns:

Type Description
DocumentRef | None

The document, or None if that exact pair does not exist.

get_outgoing_model_instances abstractmethod async

get_outgoing_model_instances(
    uid: str,
    *,
    rel_type: str | None = None,
    depth: int | None = 1,
    limit: int | None = None,
) -> list[ModelInstanceRef]

Return :ModelInstance nodes reached by an edge out of uid (any rel type).

Each carries via_rel and direction="out".

get_parent_node abstractmethod async

get_parent_node(node_id: str) -> StructureNodeRef | None

Return the HAS_CHILD parent of node_id, or None for a root node.

get_proposed_models abstractmethod async

get_proposed_models(
    *, document: _Selector | None = None
) -> list[ProposedModelRef]

Return proposed (new) models with their fields and source node.

get_related_entities(
    uid: str,
    rel_type: str,
    *,
    direction: Literal["out", "in"] = "out",
) -> list[LabeledEntityRef]

Return labeled entities linked to uid by rel_type.

get_related_model_instances(
    uid: str,
    rel_type: str,
    *,
    direction: Literal["out", "in"] = "out",
) -> list[ModelInstanceRef]

Return instances linked to uid by rel_type in direction.

get_root_structure_nodes abstractmethod async

get_root_structure_nodes(
    document: _Selector, *, version: int | None = None
) -> list[StructureNodeRef]

Return only the HAS_STRUCTURE (top-level) nodes of document.

get_sibling_nodes abstractmethod async

get_sibling_nodes(
    node_id: str, *, include_self: bool = False
) -> list[StructureNodeRef]

Return the nodes sharing a parent with node_id.

get_structure_node abstractmethod async

get_structure_node(node_id: str) -> StructureNodeRef | None

Return the structure node with this composite id, or None.

get_structure_nodes abstractmethod async

get_structure_nodes(
    document: _Selector,
    *,
    version: int | None = None,
    roles: Sequence[str] | None = None,
    title_contains: str | None = None,
    theme: str | None = None,
    where: _Where = None,
    depth: int | None = None,
    limit: int | None = None,
    skip: int = 0,
) -> list[StructureNodeRef]

Return structure nodes of document, flat, ordered by appearance.

depth bounds how deep into the HAS_CHILD tree to descend (None = whole tree). title_contains is a convenience substring filter on title; where= covers the rest — a {property_name: value | Op} mapping on the node, e.g. where={"appearance_order": Gte(3)} (see :mod:scinr.newton.navigation.filters).

get_structure_nodes_for_model_instance abstractmethod async

get_structure_nodes_for_model_instance(
    uid: str,
) -> list[StructureNodeRef]

Return the structure node(s) that own instance uid via containment.

Always a list: a deduplicated instance_key instance can belong to several nodes; a shell instance belongs to none ([]).

get_structure_subtree abstractmethod async

get_structure_subtree(
    node_id: str,
    *,
    depth: int | None = None,
    include_info_units: bool = False,
) -> StructureTree | None

Return the nested HAS_CHILD subtree rooted at node_id.

get_triples abstractmethod async

get_triples(node_id: str) -> list[Triple]

Return subject–predicate–object triples extracted from node_id.

The predicate edge is optional: a subject entity with no predicate edge to an object of the same extraction result yields a partial Triple (predicate/object None).

get_unannotated_nodes abstractmethod async

get_unannotated_nodes(
    document: _Selector,
    *,
    version: int | None = None,
    depth: int | None = None,
) -> list[StructureNodeRef]

Return structure nodes of document with no HAS_MODEL_DECISION.

get_version_chain abstractmethod async

get_version_chain(path: str) -> list[DocumentRef]

Return the versions at path ordered by the HAS_NEWER_VERSION chain.

list_catalog_models abstractmethod async

list_catalog_models(
    *, include_fields: bool = False
) -> list[CatalogModelRef]

Return the registered :CatalogModel nodes.

list_document_versions abstractmethod async

list_document_versions(path: str) -> list[DocumentRef]

Return every version at path, ascending by version.

list_entity_labels abstractmethod async

list_entity_labels() -> list[EntityLabelStat]

Return each distinct :LabeledEntity label with its node count.

list_model_classes_in_use abstractmethod async

list_model_classes_in_use(
    *, document: _Selector | None = None
) -> list[ModelClassStat]

Return each distinct ModelInstance.model_class with its count.

list_model_instance_relationship_types abstractmethod async

list_model_instance_relationship_types(
    *, document: _Selector | None = None
) -> list[RelTypeStat]

Return distinct (source model, rel_type, target model, count) triples for non-containment edges between model instances.

list_node_labels abstractmethod async

list_node_labels() -> list[str]

Return the engine-native node-type names in the graph.

list_node_roles abstractmethod async

list_node_roles(
    *, document: _Selector | None = None
) -> list[RoleStat]

Return each distinct StructureNode.role with its count.

list_relationship_types abstractmethod async

list_relationship_types(
    *, structural_only: bool = True
) -> list[str]

Return relationship-type names.

structural_only=True (default) returns the curated set the pipeline writes structurally; False returns every type in the graph (can be thousands — mostly unique normalised Triple predicates).

list_root_documents abstractmethod async

list_root_documents(
    *,
    latest_only: bool = True,
    only_folders: bool = False,
    only_leaves: bool = False,
    limit: int | None = None,
    skip: int = 0,
) -> list[DocumentRef]

List "parent" documents — those with no incoming IS_COMPOSED_OF.

Parameters:

Name Type Description Default
latest_only bool

Keep only latest=true documents (default).

True
only_folders bool

Restrict to folder-parents (is_folder = true).

False
only_leaves bool

Restrict to leaf documents (is_folder = false). Mutually exclusive with only_folders.

False

list_themes abstractmethod async

list_themes() -> list[ThemeRef]

Return the themes present in the graph.

neighbors abstractmethod async

neighbors(
    selector: NodeSelector,
    *,
    edge_types: Sequence[str] | None = None,
    direction: Literal["out", "in", "both"] = "both",
    target_types: Sequence[str] | None = None,
    depth: int | None = 1,
    limit: int | None = None,
) -> list[GraphNode]

Return nodes adjacent to selector along the given edges.

ping abstractmethod async

ping() -> bool

Return True if the backend answers a trivial read.

Raises:

Type Description
GraphConnectionError

If the engine cannot be reached.

search_info_units abstractmethod async

search_info_units(
    text: str,
    *,
    field: Literal["title", "description", "both"] = "both",
    document: _Selector | None = None,
    limit: int = 25,
) -> list[ScoredInfoUnit]

Relevance-search info units by title / description.

shortest_path abstractmethod async

shortest_path(
    from_selector: NodeSelector,
    to_selector: NodeSelector,
    *,
    max_hops: int = 6,
    edge_types: Sequence[str] | None = None,
) -> PathResult | None

Return a shortest path between two nodes, or None.

subgraph abstractmethod async

subgraph(
    selector: NodeSelector,
    *,
    depth: int = 2,
    edge_types: Sequence[str] | None = None,
    max_nodes: int = 500,
) -> Subgraph

Return a bounded neighbourhood of selector as {nodes, edges}.

Return Types

scinr.newton.navigation.models

navigation/models.py — Engine-neutral return types for the navigation API.

Every navigator method returns one of these light Pydantic models (or a list of them). They carry no engine-specific types. Each model exposes an opaque raw dict holding the backend-native record it was built from — useful for debugging, not something to depend on across engines.

All models are frozen: navigation is read-only and its results are snapshots.

AnnotationCoverage

Bases: _Base

How much of a document was annotated.

CatalogFieldRef

Bases: _Base

One :ModelField of a :CatalogModel.

CatalogGraph

Bases: _Base

The whole model catalogue: nodes plus the relationships between them.

CatalogModelRef

Bases: _Base

A registered :CatalogModel, optionally with its fields.

CatalogRelation

Bases: _Base

A declared relationship between two catalog entries.

Covers AGGREGATES (model → model containment) and the domain relationship declarations between :CatalogModel / :EntityLabel nodes (SPECIFIED_IN, REQUIREMENT_APPLIES_TO, …) carrying join_via / via_field / from_field / to_field metadata.

DocumentModelProfile

Bases: _Base

How a whole document was semantically catalogued by annotation.

A compact roll-up of the matched and complementary model classes across every :ModelDecision of the document, with per-class node counts — without listing the individual decisions.

DocumentRef

Bases: _Base

A :Document node — a leaf document or a folder-parent.

DocumentStats

Bases: _Base

Aggregate counts for one document version.

DocumentTree

Bases: DocumentRef

A DocumentRef plus nested IS_COMPOSED_OF children.

Also used as a single-spine lineage (root → … → target) by get_document_ancestors: there every node has exactly zero or one child.

EntityLabelStat

Bases: _Base

Count of :LabeledEntity nodes for one label.

EntityRelation

Bases: _Base

A Level-2 field_relationships edge between labeled entities.

ExtractionResultRef

Bases: _Base

A :ExtractionResult — Stage 4 output for a node.

is_triple is derived (model_class == "Triple"), not a stored prop.

ExtractionResultWithNode

Bases: ExtractionResultRef

An ExtractionResultRef annotated with its owning structure node.

GraphNode

Bases: _Base

A type-tagged node returned by the generic power tools.

GraphSummary

Bases: _Base

Whole-graph counts by node type and (structural) relationship type.

InfoUnitRef

Bases: _Base

A :InfoUnit — the smallest citable summary unit.

InfoUnitWithNode

Bases: InfoUnitRef

An InfoUnitRef annotated with its owning structure node.

LabeledEntityRef

Bases: _Base

A :LabeledEntity — a deduplicated, labelled entity value.

ModelClassStat

Bases: _Base

Count of :ModelInstance / decision nodes for one model_class.

ModelDecisionRef

Bases: _Base

A :ModelDecision — Stage 3 annotation outcome for a node.

confidence is a free word the annotation LLM emits ("high" / "medium" / "low" in practice), not a number. coverage_gaps is a list of strings (often empty).

ModelDecisionWithNode

Bases: ModelDecisionRef

A ModelDecisionRef annotated with its owning structure node.

ModelInstanceRef

Bases: _Base

A :ModelInstance — one extracted record; field values in properties.

ModelInstanceRelation

Bases: _Base

A relationship between two :ModelInstance nodes, with direction.

ModelInstanceTree

Bases: ModelInstanceRef

A ModelInstanceRef plus its nested outgoing-edge children.

NodeDescription

Bases: _Base

An aggregate, human-oriented view of one structure node.

NodePath

Bases: _Base

The chain of structure nodes from a document root down to one node.

NodeSelector

Bases: BaseModel

Identifies a node by type + a unique key/value pair.

Example: NodeSelector(type="ModelInstance", key="uid", value="abc123").

PageText

Bases: _Base

One converted source page, verbatim markdown.

PathResult

Bases: _Base

A path between two nodes (shortest_path).

ProposedFieldRef

Bases: _Base

A single field of a :ProposedModel (or a :SupplementaryField).

ProposedModelRef

Bases: _Base

A :ProposedModel suggested during annotation when nothing matched.

name property

name: str | None

Alias for :attr:schema_name.

RelTypeStat

Bases: _Base

Count of a distinct (source model, rel_type, target model) triple.

RoleStat

Bases: _Base

Count of :StructureNode nodes for one role.

ScoredInfoUnit

Bases: InfoUnitWithNode

An InfoUnitWithNode plus a relevance score (search results).

StructureNodeRef

Bases: _Base

A :StructureNode (section, subsection, table, row, …).

document_path / document_version are populated only when the query that produced this ref already carried the owning :Document — they are never derived by parsing the composite id (which is not safely parseable).

StructureTree

Bases: StructureNodeRef

A StructureNodeRef plus its nested HAS_CHILD children.

Subgraph

Bases: _Base

A bounded neighbourhood of nodes and edges (subgraph).

ThemeRef

Bases: _Base

A :Theme node, or a distinct theme value in use.

Triple

Bases: _Base

A subject–predicate–object statement (Triple fallback extraction).

predicate / predicate_raw / object are None when the subject entity has no predicate edge to an object entity of the same extraction result (a partial / dangling statement).

Filter Operators

scinr.newton.navigation.filters

navigation/filters.py — Engine-neutral property filter operators for where=.

Every list-returning navigation method that filters on node properties accepts a where argument shaped as dict[str, Any | Op]:

where={"status": "active", "confidence": Gte(0.8), "code": In(["A", "B"])}

A bare value is sugar for :class:Eq. Each :class:Op is a frozen Pydantic model carrying only its operands — it holds no engine syntax. A concrete backend (navigation/neo4j/_translate.py for Neo4j) turns each operator into its native predicate with fully parameterised values.

Property keys are validated against ^[A-Za-z_][A-Za-z0-9_]*$ so they can be safely interpolated as an identifier; values are never interpolated.

Contains

Bases: Op

Substring match: value appears somewhere in the (string) field.

EndsWith

Bases: Op

The (string) field ends with value.

Eq

Bases: Op

field == value.

Gt

Bases: Op

field > value.

Gte

Bases: Op

field >= value.

In

Bases: Op

field IN values.

IsNotNull

Bases: Op

field IS NOT NULL — the property is present and non-null.

IsNull

Bases: Op

field IS NULL — the property is absent or explicitly null.

Lt

Bases: Op

field < value.

Lte

Bases: Op

field <= value.

Ne

Bases: Op

field != value.

NotIn

Bases: Op

NOT (field IN values).

Op

Bases: BaseModel

Base class for all where= filter operators. Frozen and immutable.

describe

describe() -> str

Return a short human-readable form, e.g. ">= 0.8". For logs/errors.

Regex

Bases: Op

The (string) field fully matches the regular expression pattern.

StartsWith

Bases: Op

The (string) field starts with value.

normalize_where

normalize_where(
    where: Mapping[str, Any] | None,
) -> dict[str, Op]

Normalise a raw where= mapping into {validated_key: Op}.

A value that is not already an :class:Op is wrapped in :class:Eq. Keys are validated with :func:validate_key.

Parameters:

Name Type Description Default
where Mapping[str, Any] | None

The user-supplied mapping, or None.

required

Returns:

Type Description
dict[str, Op]

A new dict mapping each validated key to an :class:Op. Empty when

dict[str, Op]

where is None or empty.

Raises:

Type Description
NavigationError

On an invalid key or a non-mapping where.

validate_key

validate_key(key: str) -> str

Return key unchanged if it is a safe property identifier, else raise.

Parameters:

Name Type Description Default
key str

A candidate node-property name.

required

Returns:

Type Description
str

The same string.

Raises:

Type Description
NavigationError

If key does not match ^[A-Za-z_][A-Za-z0-9_]*$.

Neo4j Backend

scinr.newton.navigation.neo4j.navigator

navigation/neo4j/navigator.py — Neo4jGraphNavigator.

The default (and, today, only) :class:~scinr.newton.navigation.GraphNavigator backend. It is assembled from one mixin per method group (_documents, _structure, …) over the shared _Neo4jRuntime (driver lifecycle + read helpers). All Cypher lives in the mixins; this module only wires them together.

Neo4jGraphNavigator

Bases: _DocumentsMixin, _StructureMixin, _InfoUnitsMixin, _AnnotationMixin, _ModelInstancesMixin, _EntitiesMixin, _IntrospectionMixin, _PowerMixin, GraphNavigator

Cypher implementation of :class:GraphNavigator.

Construct via :func:scinr.newton.navigation.get_graph_navigator / :func:scinr.newton.navigation.graph_navigator rather than directly. When driver is not supplied it reuses the shared async driver from ingest.config.get_async_driver() and never closes it; pass an explicit driver to own the connection lifecycle.

Parameters:

Name Type Description Default
driver Any

An open neo4j.AsyncDriver. Optional.

None
database str | None

Neo4j database name. Defaults to config.neo4j_database.

None

Source-Text Bridge

scinr.newton.navigation.pages

navigation/pages.py — Source-text bridge (Group I).

Resolves the verbatim converted source pages behind a structure node / info unit / document. Uses the already-abstract storage layer (storage.factory.get_storage), so it stays engine-agnostic on the graph side: it only calls the public :class:GraphNavigator methods plus the page repository.

Every function needs a configured, non-none storage backend — a graph ingested with storage_backend="none" has no page content to return.

get_document_source_text async

get_document_source_text(
    nav: GraphNavigator,
    document: str,
    *,
    version: int | None = None,
) -> list[PageText]

Return every converted page of document, ordered by page index.

Raises:

Type Description
StorageError

If no persistent storage backend is configured.

get_info_unit_source_text async

get_info_unit_source_text(
    nav: GraphNavigator, uid: str
) -> list[PageText]

Return the source pages behind the structure node that owns info unit uid.

get_node_source_page_ids async

get_node_source_page_ids(
    nav: GraphNavigator, node_id: str
) -> list[str]

Return the raw source_page_ids recorded on node_id (no storage needed).

get_node_source_text async

get_node_source_text(
    nav: GraphNavigator, node_id: str
) -> list[PageText]

Return the verbatim converted markdown pages behind node_id.

Raises:

Type Description
StorageError

If no persistent storage backend is configured.