kumiho.edge

Edge module for Kumiho asset management.

This module provides the Edge class and related constants for tracking relationships between revisions. Edges enable dependency tracking, lineage visualization, and impact analysis.

Edge Types:
  • DEPENDS_ON: Source depends on target (e.g., model uses texture).

  • DERIVED_FROM: Source was created from target (e.g., LOD from highpoly).

  • REFERENCED: Source references target (soft dependency).

  • CONTAINS: Source contains target (composition).

  • CREATED_FROM: Source was generated from target.

  • BELONGS_TO: Source belongs to target (grouping).

Example:

import kumiho

# Get revisions
model = kumiho.get_revision("kref://project/models/hero.model?r=1")
texture = kumiho.get_revision("kref://project/tex/skin.texture?r=2")

# Create a dependency edge
edge = model.create_edge(texture, kumiho.DEPENDS_ON)

# Query edges
deps = model.get_edges(kumiho.DEPENDS_ON, kumiho.OUTGOING)
for dep in deps:
    print(f"{dep.source_kref} depends on {dep.target_kref}")
exception kumiho.edge.EdgeTypeValidationError[source]

Bases: ValueError

Raised when an edge type is invalid or potentially malicious.

kumiho.edge.validate_edge_type(edge_type)[source]

Validate an edge type for security and correctness.

Edge types must: - Start with an uppercase letter - Contain only uppercase letters, digits, and underscores - Be 1-50 characters long

Parameters:

edge_type (str) – The edge type to validate.

Raises:

EdgeTypeValidationError – If the edge type is invalid.

Return type:

None

Example:

from kumiho.edge import validate_edge_type, EdgeTypeValidationError

try:
    validate_edge_type("DEPENDS_ON")  # OK
    validate_edge_type("depends_on")  # Raises error
except EdgeTypeValidationError as e:
    print(f"Invalid edge type: {e}")
kumiho.edge.is_valid_edge_type(edge_type)[source]

Check if an edge type is valid without raising exceptions.

Parameters:

edge_type (str) – The edge type to validate.

Return type:

bool

Returns:

True if the edge type is valid, False otherwise.

class kumiho.edge.EdgeType[source]

Bases: object

Standard edge types for Kumiho relationships.

These constants define the semantic meaning of relationships between revisions. Use them when creating or querying edges.

All edge types use UPPERCASE format as required by the Neo4j graph database.

BELONGS_TO

Indicates ownership or grouping relationship.

Type:

str

CREATED_FROM

Indicates the source was generated from target.

Type:

str

REFERENCED

Indicates a soft reference relationship.

Type:

str

DEPENDS_ON

Indicates the source requires the target.

Type:

str

DERIVED_FROM

Indicates the source was derived/modified from target.

Type:

str

CONTAINS

Indicates the source contains or includes the target.

Type:

str

Example:

import kumiho

# Model depends on texture
model_v1.create_edge(texture_v2, kumiho.DEPENDS_ON)

# LOD derived from high-poly
lod_v1.create_edge(highpoly_v1, kumiho.DERIVED_FROM)
BELONGS_TO = 'BELONGS_TO'

Ownership or grouping relationship.

CREATED_FROM = 'CREATED_FROM'

Source was generated/created from target.

REFERENCED = 'REFERENCED'

Soft reference relationship.

DEPENDS_ON = 'DEPENDS_ON'

Source requires target to function.

DERIVED_FROM = 'DERIVED_FROM'

Source was derived or modified from target.

CONTAINS = 'CONTAINS'

Source contains or includes target.

class kumiho.edge.EdgeDirection[source]

Bases: object

Direction constants for edge traversal queries.

When querying edges, you can specify which direction to traverse: outgoing edges (from source), incoming edges (to target), or both.

OUTGOING

Edges where the queried revision is the source.

Type:

int

INCOMING

Edges where the queried revision is the target.

Type:

int

BOTH

Edges in either direction.

Type:

int

Example:

import kumiho

# Get dependencies (what this revision depends on)
deps = revision.get_edges(kumiho.DEPENDS_ON, kumiho.OUTGOING)

# Get dependents (what depends on this revision)
dependents = revision.get_edges(kumiho.DEPENDS_ON, kumiho.INCOMING)

# Get all relationships
all_edges = revision.get_edges(direction=kumiho.BOTH)
OUTGOING = 0

Edges where the queried revision is the source.

INCOMING = 1

Edges where the queried revision is the target.

BOTH = 2

Edges in either direction.

class kumiho.edge.Edge[source]

Bases: KumihoObject

A relationship between two revisions in the Kumiho system.

Edges represent semantic relationships between revisions, enabling dependency tracking, lineage visualization, and impact analysis. They are directional (source -> target) and typed.

Common use cases:
  • Track which textures a model uses (DEPENDS_ON)

  • Record that a LOD was created from a high-poly model (DERIVED_FROM)

  • Link a render to the scene file that created it (CREATED_FROM)

source_kref

Reference to the source revision.

Type:

Kref

target_kref

Reference to the target revision.

Type:

Kref

edge_type

The type of relationship (see EdgeType).

Type:

str

metadata

Custom metadata key-value pairs.

Type:

Dict[str, str]

created_at

ISO timestamp when the edge was created.

Type:

Optional[str]

author

The user ID who created the edge.

Type:

str

username

Display name of the creator.

Type:

str

Example:

import kumiho

# Get revisions
model = kumiho.get_revision("kref://project/models/hero.model?r=1")
texture = kumiho.get_revision("kref://project/tex/skin.texture?r=2")

# Create edge with metadata
edge = model.create_edge(texture, kumiho.DEPENDS_ON, {
    "channel": "diffuse",
    "uv_set": "0"
})

# Inspect edge
print(f"Type: {edge.edge_type}")
print(f"From: {edge.source_kref}")
print(f"To: {edge.target_kref}")

# Delete edge
edge.delete()
__init__(pb_edge, client)[source]

Initialize an Edge from a protobuf message.

Parameters:
  • pb_edge (Edge) – The protobuf Edge message.

  • client (_Client) – The client instance for making API calls.

Return type:

None

__repr__()[source]

Return a string representation of the Edge.

Return type:

str

delete(force=False)[source]

Delete this edge.

Parameters:

force (bool) – Reserved for future use.

Return type:

None

Example

>>> edge = model.create_edge(texture, kumiho.DEPENDS_ON)
>>> edge.delete()  # Remove the relationship
class kumiho.edge.PathStep[source]

Bases: object

A single step in a traversal path.

Represents one hop in a graph traversal, including the revision reached and the edge type used to reach it.

revision_kref

The revision at this step.

Type:

Kref

edge_type

The relationship type used to reach this revision.

Type:

str

depth

Distance from the origin (0 = origin).

Type:

int

Example:

for step in path.steps:
    print(f"Step {step.depth}: {step.revision_kref} via {step.edge_type}")
revision_kref: Kref
edge_type: str
depth: int
__init__(revision_kref, edge_type, depth)
Parameters:
  • revision_kref (Kref)

  • edge_type (str)

  • depth (int)

Return type:

None

class kumiho.edge.RevisionPath[source]

Bases: object

A complete path between revisions.

Represents a sequence of steps from one revision to another, used in traversal and shortest-path queries.

steps

The sequence of steps in the path.

Type:

List[PathStep]

total_depth

Total length of the path.

Type:

int

Example:

path = source_revision.find_path_to(target_revision)
if path:
    print(f"Path length: {path.total_depth}")
    for step in path.steps:
        print(f"  -> {step.revision_kref}")
steps: List[PathStep]
total_depth: int = 0
__init__(steps=<factory>, total_depth=0)
Parameters:
  • steps (List[PathStep])

  • total_depth (int)

Return type:

None

class kumiho.edge.ImpactedRevision[source]

Bases: object

A revision impacted by changes to another revision.

Represents a revision that directly or indirectly depends on a target revision, used in impact analysis.

revision_kref

The impacted revision.

Type:

Kref

item_kref

The item containing the impacted revision.

Type:

Kref

impact_depth

How many hops away from the target.

Type:

int

impact_path_types

Edge types in the impact chain.

Type:

List[str]

Example:

impact = texture_v1.analyze_impact()
for iv in impact:
    print(f"{iv.revision_kref} at depth {iv.impact_depth}")
revision_kref: Kref
item_kref: Optional[Kref] = None
impact_depth: int = 0
impact_path_types: List[str]
__init__(revision_kref, item_kref=None, impact_depth=0, impact_path_types=<factory>)
Parameters:
  • revision_kref (Kref)

  • item_kref (Kref | None)

  • impact_depth (int)

  • impact_path_types (List[str])

Return type:

None

class kumiho.edge.TraversalResult[source]

Bases: object

Result of a graph traversal query.

Contains all revisions discovered during a multi-hop traversal, along with optional path information.

revision_krefs

Flat list of discovered revision references.

Type:

List[Kref]

paths

Path information if requested.

Type:

List[RevisionPath]

edges

All traversed edges.

Type:

List[Edge]

total_count

Total number of discovered revisions.

Type:

int

truncated

True if results were limited by max_depth or limit.

Type:

bool

Example:

# Get all transitive dependencies
result = revision.get_all_dependencies(max_depth=5)

print(f"Found {result.total_count} dependencies")
if result.truncated:
    print("Results were truncated")

for kref in result.revision_krefs:
    print(f"  - {kref}")
__init__(revision_krefs, paths, edges, total_count, truncated, client)[source]
Parameters:
Return type:

None

get_revisions()[source]

Fetch full Revision objects for all discovered revisions.

Returns:

List of Revision objects.

Return type:

List[Revision]

Example:

result = revision.get_all_dependencies()
for v in result.get_revisions():
    print(f"{v.kref} - {v.metadata}")
class kumiho.edge.ShortestPathResult[source]

Bases: object

Result of a shortest path query.

Contains path(s) between two revisions if found.

paths

One or more shortest paths found.

Type:

List[RevisionPath]

path_exists

True if any path was found.

Type:

bool

path_length

Length of the shortest path(s).

Type:

int

Example:

result = source_revision.find_path_to(target_revision)
if result.path_exists:
    print(f"Found path of length {result.path_length}")
    for path in result.paths:
        for step in path.steps:
            print(f"  {step.depth}: {step.revision_kref}")
__init__(paths, path_exists, path_length)[source]
Parameters:
  • paths (List[RevisionPath])

  • path_exists (bool)

  • path_length (int)

Return type:

None

property first_path: RevisionPath | None

Get the first (or only) shortest path.

Returns:

RevisionPath if a path exists, None otherwise.