API Reference

This is the complete API reference for AlgoTree v1.0+.

Core Classes

Node

class AlgoTree.Node(name: str | None = None, parent: Node | None = None, **payload)[source]

Bases: object

A tree node with proper attributes instead of dict inheritance.

This class represents a single node in a tree structure with: - A unique name/identifier - Optional parent reference - List of children - Arbitrary payload data

add_child(name: str | None = None, **payload) Node[source]

Add a child node.

Parameters:
  • name – Name for the child node.

  • **payload – Data for the child node.

Returns:

The newly created child node.

clone() Node[source]

Create a deep copy of this node and its subtree.

find(predicate: Callable[[Node], bool]) Node | None[source]

Find first node matching predicate.

Parameters:

predicate – Function that returns True for matching nodes.

Returns:

First matching node or None.

find_all(predicate: Callable[[Node], bool]) List[Node][source]

Find all nodes matching predicate.

Parameters:

predicate – Function that returns True for matching nodes.

Returns:

List of matching nodes.

classmethod from_dict(data: Dict[str, Any], parent: Node | None = None) Node[source]

Create tree from nested dictionary representation.

Parameters:
  • data – Dictionary with node data and optional ‘children’ key.

  • parent – Parent node for the created tree.

Returns:

Root node of created tree.

get_path() List[Node][source]

Get path from root to this node.

property is_leaf: bool

Check if this is a leaf node.

property is_root: bool

Check if this is a root node.

property level: int

Get the level (depth) of this node in the tree.

property parent: Node | None

Get the parent node.

remove_child(child: Node) None[source]

Remove a child node.

property root: Node

Get the root node of the tree.

property siblings: List[Node]

Get list of sibling nodes.

to_dict() Dict[str, Any][source]

Convert tree to nested dictionary representation.

Returns:

Dictionary with node data and nested children.

traverse_levelorder() Iterator[Node][source]

Traverse tree in level order (breadth-first).

traverse_postorder() Iterator[Node][source]

Traverse tree in postorder (children before parent).

traverse_preorder() Iterator[Node][source]

Traverse tree in preorder (parent before children).

from AlgoTree import Node

# Create nodes
root = Node("root", type="container")
child = root.add_child("child", value=42)

# Access properties
print(root.name)        # "root"
print(root.payload)     # {"type": "container"}
print(root.children)    # [child]
print(root.is_root)     # True
print(child.parent)     # root
print(child.level)      # 1

TreeBuilder

class AlgoTree.TreeBuilder[source]

Bases: object

Fluent API for building trees with method chaining.

Example

tree = (TreeBuilder()

.root(“company”, type=”corporation”) .child(“engineering”, head=”Alice”)

.child(“frontend”, team_size=5) .sibling(“backend”, team_size=8) .up()

.sibling(“sales”, head=”Bob”) .build())

build() Node[source]

Build and return the tree.

Returns:

The root node of the constructed tree.

child(name: str, **payload) TreeBuilder[source]

Add a child to the current node and move to it.

Parameters:
  • name – Name for the child node.

  • **payload – Data for the child node.

Returns:

Self for method chaining.

root(name: str, **payload) TreeBuilder[source]

Create the root node.

Parameters:
  • name – Name for the root node.

  • **payload – Data for the root node.

Returns:

Self for method chaining.

sibling(name: str, **payload) TreeBuilder[source]

Add a sibling to the current node.

Parameters:
  • name – Name for the sibling node.

  • **payload – Data for the sibling node.

Returns:

Self for method chaining.

to_root() TreeBuilder[source]

Move to the root node.

Returns:

Self for method chaining.

up(levels: int = 1) TreeBuilder[source]

Move up in the tree by specified levels.

Parameters:

levels – Number of levels to move up. Default is 1.

Returns:

Self for method chaining.

from AlgoTree import TreeBuilder

tree = (TreeBuilder()
    .root("app")
    .child("config", debug=True)
    .sibling("database", host="localhost")
    .up()
    .child("modules")
        .child("auth")
        .sibling("api")
    .build())

FluentNode

class AlgoTree.FluentNode(node: Node | List[Node])[source]

Bases: object

Wrapper for Node that provides fluent API for tree operations.

Example

result = (FluentNode(tree)

.filter(lambda n: n.level <= 2) .map(lambda n: n.payload.get(‘size’, 0)) .where(lambda n: n > 5) .to_list())

children() FluentNode[source]

Get all children of current nodes.

Returns:

New FluentNode with all children.

count() int[source]

Get count of current nodes.

Returns:

Number of nodes.

descendants() FluentNode[source]

Get all descendants of current nodes.

Returns:

New FluentNode with all descendants.

each(action: Callable[[Node], None]) FluentNode[source]

Execute an action on each node.

Parameters:

action – Function to execute on each node.

Returns:

Self for method chaining.

filter(predicate: Callable[[Node], bool]) FluentNode[source]

Filter nodes by predicate.

Parameters:

predicate – Function that returns True for nodes to keep.

Returns:

New FluentNode with filtered nodes.

first() Node | None[source]

Get first node or None.

Returns:

First node or None if empty.

leaves() FluentNode[source]

Get all leaf nodes from current nodes.

Returns:

New FluentNode with leaf nodes only.

map(transform: Callable[[Node], Any]) FluentNode[source]

Transform each node’s payload.

Parameters:

transform – Function to transform each node.

Returns:

Self for method chaining.

match(pattern: str | Pattern | dict) FluentNode[source]

Find nodes matching a pattern.

Parameters:

pattern – Pattern to match (string, Pattern object, or dict)

Returns:

New FluentNode with matching nodes.

prune(predicate: Callable[[Node], bool]) FluentNode[source]

Remove nodes matching predicate.

Parameters:

predicate – Function that returns True for nodes to remove.

Returns:

Self for method chaining.

replace_matches(pattern: str | Pattern | dict, replacement: Node | Callable[[Node], Node]) FluentNode[source]

Replace nodes matching a pattern.

Parameters:
  • pattern – Pattern to match

  • replacement – Node or function to generate replacement

Returns:

Self for method chaining.

sort(key: Callable[[Node], Any] | None = None, reverse: bool = False) FluentNode[source]

Sort children of each node.

Parameters:
  • key – Function to extract sort key from each node.

  • reverse – Whether to sort in reverse order.

Returns:

Self for method chaining.

to_dict() dict | List[dict][source]

Convert to dictionary representation.

Returns:

Dictionary or list of dictionaries.

to_list() List[Node][source]

Get list of current nodes.

Returns:

List of nodes.

where(predicate: Callable[[Node], bool]) FluentNode[source]

Filter current nodes by predicate (alias for filter on current set).

Parameters:

predicate – Function that returns True for nodes to keep.

Returns:

New FluentNode with filtered nodes.

from AlgoTree import FluentNode

fluent = FluentNode(tree)

# Chain operations
(fluent
    .filter(lambda n: n.payload.get("enabled"))
    .map(lambda n: {"processed": True})
    .each(lambda n: print(n.name)))

Pattern Matching

Pattern

class AlgoTree.Pattern(name: str | None = None, attributes: ~typing.Dict[str, ~typing.Any] = <factory>, children: ~typing.List[~AlgoTree.pattern_matcher.Pattern] = <factory>, is_wildcard: bool = False, is_deep_wildcard: bool = False, min_children: int | None = None, max_children: int | None = None, predicate: ~typing.Callable[[~AlgoTree.node.Node], bool] | None = None)[source]

Bases: object

Represents a tree pattern to match against.

Patterns can include: - Exact node matches - Wildcards (*) that match any single node - Deep wildcards (**) that match any subtree - Attribute constraints

attributes: Dict[str, Any]
children: List[Pattern]
static from_dict(pattern_dict: Dict[str, Any]) Pattern[source]

Create a pattern from dictionary representation.

Example

{

“name”: “parent”, “attributes”: {“type”: “container”}, “children”: [

{“name”: “child1”}, {“name”: “*”} # Wildcard child

]

}

static from_string(pattern_str: str) Pattern[source]

Parse a pattern from string notation.

Examples

“root” # Match node named ‘root’ “*” # Match any single node “**” # Match any subtree “node[type=foo]” # Match node with attribute “parent(child1, child2)” # Match parent with specific children “root.branch.leaf” # Dot notation path “app.*.test” # Dot notation with wildcard “root.**.target” # Dot notation with deep wildcard

is_deep_wildcard: bool = False
is_wildcard: bool = False
max_children: int | None = None
min_children: int | None = None
name: str | None = None
predicate: Callable[[Node], bool] | None = None

PatternMatcher

class AlgoTree.PatternMatcher(match_type: MatchType = MatchType.PARTIAL)[source]

Bases: object

Matches patterns against tree structures.

find_all(tree: Node, pattern: Pattern) List[Node][source]

Find all nodes in tree that match the pattern.

Parameters:
  • tree – Root node of tree to search

  • pattern – Pattern to match

Returns:

List of nodes that match the pattern

find_first(tree: Node, pattern: Pattern) Node | None[source]

Find first node that matches the pattern.

Parameters:
  • tree – Root node of tree to search

  • pattern – Pattern to match

Returns:

First matching node or None

match(node: Node, pattern: Pattern) bool[source]

Check if a node matches a pattern.

Parameters:
  • node – Node to match against

  • pattern – Pattern to match

Returns:

True if node matches pattern

replace(tree: Node, pattern: Pattern, replacement: Node | Callable[[Node], Node]) int[source]

Replace all nodes matching pattern with replacement.

Parameters:
  • tree – Root node of tree

  • pattern – Pattern to match

  • replacement – Node or function to generate replacement

Returns:

Number of replacements made

Pattern Functions

AlgoTree.pattern_match(tree: Node, pattern: str | Dict | Pattern, match_type: MatchType = MatchType.PARTIAL) List[Node][source]

Convenience function to find all matches of a pattern in a tree.

Parameters:
  • tree – Tree to search

  • pattern – Pattern as string, dict, or Pattern object

  • match_type – Type of matching

Returns:

List of matching nodes

AlgoTree.dotmatch(tree: Node, dot_path: str, return_paths: bool = False) List[Node] | List[str][source]

Match nodes using dot notation paths, inspired by dotsuite.

This provides a clean, intuitive way to navigate and match tree paths using dot notation similar to JSONPath or object property access.

Parameters:
  • tree – Tree to search

  • dot_path – Dot notation path (e.g., “root.branch.*.leaf”, “app.**.test”)

  • return_paths – If True, return dot paths to matches instead of nodes

Returns:

List of matching nodes or their dot paths

Examples

# Find all test files dotmatch(tree, “src.**.test_*”)

# Find specific path dotmatch(tree, “app.models.user”)

# Find with wildcards dotmatch(tree, “data.*.value”)

# Get paths instead of nodes paths = dotmatch(tree, “**.config”, return_paths=True) # Returns: [“app.config”, “modules.auth.config”, …]

AlgoTree.dotpluck(tree: Node, *dot_paths: str) List[Any][source]

Extract values from tree using dot notation paths.

Inspired by dotsuite’s dotpluck, this extracts payload values from nodes at specified paths.

Parameters:
  • tree – Tree to extract from

  • *dot_paths – Variable number of dot notation paths

Returns:

List of values (payload or None for missing paths)

Examples

# Extract multiple values values = dotpluck(tree, “user.name”, “user.age”, “user.email”)

# Extract with wildcards (returns all matching values) values = dotpluck(tree, “users.*.name”)

AlgoTree.dotexists(tree: Node, dot_path: str) bool[source]

Check if a path exists in the tree.

Inspired by dotsuite’s dotexists from the Truth pillar.

Parameters:
  • tree – Tree to check

  • dot_path – Dot notation path

Returns:

True if path exists, False otherwise

AlgoTree.dotcount(tree: Node, dot_path: str) int[source]

Count nodes matching a path pattern.

Parameters:
  • tree – Tree to count in

  • dot_path – Dot notation path pattern

Returns:

Number of matching nodes

AlgoTree.dotfilter(tree: Node, filter_expr: str) List[Node][source]

Filter tree nodes using advanced expressions.

Supports: - Comparison operators: >, <, >=, <=, ==, != - Logical operators: and, or, not - Path expressions: @.property - Functions: contains(), startswith(), endswith()

Parameters:
  • tree – Tree to filter

  • filter_expr – Filter expression

Returns:

List of matching nodes

Examples

# Size greater than 100 dotfilter(tree, “@.size > 100”)

# Name contains “test” and has children dotfilter(tree, “contains(@.name, ‘test’) and @.children.length > 0”)

Closed Transformations (Tree → Tree)

AlgoTree.dotmod(tree: Node, transformations: Dict[str, Any] | List[Tuple[str, Any]], in_place: bool = False) Node[source]

Apply closed tree-to-tree transformations using dot notation paths.

This function modifies nodes in the tree based on dot notation paths, preserving the tree structure (closed transformation).

Parameters:
  • tree – Tree to transform

  • transformations – Either: - Dict mapping dot paths to transformations - List of (dot_path, transformation) tuples

  • in_place – If True, modify tree in place; otherwise create a copy

Returns:

Transformed tree (same object if in_place=True, copy otherwise)

Transformations can be:
  • Dict: Update node payload with dict contents

  • Callable: Apply function to node (receives node, returns dict to update payload)

  • String: Rename the node

  • None: Clear the payload (but keep the node)

Examples

# Update specific nodes tree = dotmod(tree, {

“app.config”: {“version”: “2.0”, “debug”: False}, “app.database”: {“host”: “localhost”, “port”: 5432}

})

# Rename nodes tree = dotmod(tree, {

“app.oldname”: “newname”

})

# Apply functions tree = dotmod(tree, {

“app.**.file”: lambda n: {“size”: n.payload.get(“size”, 0) * 2}

})

# Multiple transformations to same path pattern tree = dotmod(tree, [

(“app.**.test_*”, lambda n: {“tested”: True}), (“app.**.test_*”, lambda n: {“priority”: “high”})

])

AlgoTree.dotmap(tree: Node, mapper: Callable[[Node], Dict[str, Any]] | Dict[str, Callable], dot_path: str = '**', in_place: bool = False) Node[source]

Map a transformation function over nodes matching a pattern.

This is a convenience function that applies the same transformation to all nodes matching a pattern.

Parameters:
  • tree – Tree to transform

  • mapper – Either: - Function that takes a node and returns dict to update payload - Dict mapping payload keys to transformation functions

  • dot_path – Pattern to match nodes (default “**” for all nodes)

  • in_place – If True, modify tree in place

Returns:

Transformed tree

Examples

# Double all sizes tree = dotmap(tree, lambda n: {“size”: n.payload.get(“size”, 0) * 2})

# Transform specific fields tree = dotmap(tree, {

“size”: lambda v: v * 2, “name”: lambda v: v.upper(), “timestamp”: lambda v: str(v)

})

# Apply only to specific nodes tree = dotmap(tree,

lambda n: {“processed”: True}, dot_path=”app.data.**”)

AlgoTree.dotprune(tree: Node, condition: str | Callable[[Node], bool], keep_structure: bool = False, in_place: bool = False) Node[source]

Prune nodes from tree based on condition.

Parameters:
  • tree – Tree to prune

  • condition – Either: - Dot path pattern of nodes to remove - Predicate function (returns True for nodes to remove)

  • keep_structure – If True, replace pruned nodes with empty placeholders

  • in_place – If True, modify tree in place

Returns:

Pruned tree

Examples

# Remove all test files tree = dotprune(tree, “**.test_*”)

# Remove empty directories tree = dotprune(tree, lambda n: n.payload.get(“type”) == “dir” and len(n.children) == 0)

# Keep structure but clear nodes tree = dotprune(tree, “**.deprecated”, keep_structure=True)

AlgoTree.dotmerge(tree1: Node, tree2: Node, merge_strategy: str = 'overlay', conflict_resolver: Callable[[Node, Node], Node] | None = None, in_place: bool = False) Node[source]

Merge two trees using various strategies.

Parameters:
  • tree1 – First tree (base)

  • tree2 – Second tree (overlay)

  • merge_strategy – Strategy for merging: - “overlay”: tree2 values override tree1 - “underlay”: tree1 values take precedence - “combine”: merge payloads, keeping both values - “custom”: use conflict_resolver function

  • conflict_resolver – Function to resolve conflicts (for custom strategy)

  • in_place – If True, modify tree1 in place

Returns:

Merged tree

Examples

# Simple overlay merge merged = dotmerge(tree1, tree2, “overlay”)

# Custom conflict resolution def resolver(node1, node2):

# Combine arrays, prefer tree2 for other values merged_payload = {} for key in set(node1.payload.keys()) | set(node2.payload.keys()):

if key in node1.payload and key in node2.payload:

val1, val2 = node1.payload[key], node2.payload[key] if isinstance(val1, list) and isinstance(val2, list):

merged_payload[key] = val1 + val2

else:

merged_payload[key] = val2

elif key in node1.payload:

merged_payload[key] = node1.payload[key]

else:

merged_payload[key] = node2.payload[key]

return Node(node2.name, **merged_payload)

merged = dotmerge(tree1, tree2, “custom”, conflict_resolver=resolver)

AlgoTree.dotgraft(tree: Node, graft_point: str, subtree: Node, position: int | str = 'append', in_place: bool = False) Node[source]

Graft a subtree onto a tree at specified point(s).

Parameters:
  • tree – Tree to graft onto

  • graft_point – Dot path to graft point(s)

  • subtree – Subtree to graft

  • position – Where to add the subtree: - “append”: Add at end of children (default) - “prepend”: Add at beginning of children - int: Insert at specific index - “replace”: Replace existing children

  • in_place – If True, modify tree in place

Returns:

Tree with grafted subtree

Examples

# Add new module to app new_module = Node(“auth”, type=”module”) tree = dotgraft(tree, “app.modules”, new_module)

# Insert at specific position tree = dotgraft(tree, “app.modules”, new_module, position=0)

# Replace children tree = dotgraft(tree, “app.old_modules”, new_modules, position=”replace”)

AlgoTree.dotsplit(tree: Node, split_point: str, include_point: bool = True) Tuple[Node, List[Node]][source]

Split tree at specified point(s), extracting subtrees.

Parameters:
  • tree – Tree to split

  • split_point – Dot path to split point(s)

  • include_point – If True, include split point in extracted subtrees

Returns:

Tuple of (modified tree, list of extracted subtrees)

Examples

# Extract all test modules tree, test_modules = dotsplit(tree, “**.tests”)

# Extract but keep the container node tree, extracted = dotsplit(tree, “app.deprecated”, include_point=False)

AlgoTree.dotflatten(tree: Node, flatten_pattern: str = '**', max_depth: int | None = None) List[Node][source]

Flatten tree structure into a list of nodes.

Parameters:
  • tree – Tree to flatten

  • flatten_pattern – Pattern for nodes to include

  • max_depth – Maximum depth to flatten to

Returns:

List of nodes (flattened)

Examples

# Get all nodes as flat list all_nodes = dotflatten(tree)

# Get only file nodes files = dotflatten(tree, “**[type=file]”)

# Flatten only top 3 levels top_nodes = dotflatten(tree, max_depth=3)

AlgoTree.dotreduce(tree: Node, reducer: Callable[[Any, Node], Any], initial: Any = None, traverse_pattern: str = '**') Any[source]

Reduce tree to a single value using a reducer function.

Parameters:
  • tree – Tree to reduce

  • reducer – Function (accumulator, node) -> new_accumulator

  • initial – Initial value for accumulator

  • traverse_pattern – Pattern for nodes to include in reduction

Returns:

Reduced value

Examples

# Sum all sizes total_size = dotreduce(tree,

lambda acc, n: acc + n.payload.get(“size”, 0), initial=0)

# Collect all names names = dotreduce(tree,

lambda acc, n: acc + [n.name], initial=[])

# Find maximum depth max_depth = dotreduce(tree,

lambda acc, n: max(acc, n.level), initial=0)

AlgoTree.dotannotate(tree: Node, annotator: Callable[[Node], Dict[str, Any]] | Dict[str, Any], annotation_key: str = '_annotation', dot_path: str = '**', in_place: bool = False) Node[source]

Add annotations to nodes in the tree.

Parameters:
  • tree – Tree to annotate

  • annotator – Either: - Function that returns annotation dict for each node - Static annotation dict to add to all matching nodes

  • annotation_key – Key to store annotations under in payload

  • dot_path – Pattern for nodes to annotate

  • in_place – If True, modify tree in place

Returns:

Annotated tree

Examples

# Add computed annotations tree = dotannotate(tree,

lambda n: {

“depth”: n.level, “has_children”: len(n.children) > 0, “path”: “.”.join(p.name for p in n.get_path())

})

# Add static annotations to specific nodes tree = dotannotate(tree,

{“reviewed”: True, “version”: “1.0”}, dot_path=”**.critical_*”)

AlgoTree.dotvalidate(tree: Node, validator: Callable[[Node], bool] | Dict[str, Any], dot_path: str = '**', raise_on_invalid: bool = True) bool | List[Node][source]

Validate nodes in the tree against criteria.

Parameters:
  • tree – Tree to validate

  • validator – Either: - Predicate function returning True for valid nodes - Dict of required attributes and values

  • dot_path – Pattern for nodes to validate

  • raise_on_invalid – If True, raise exception on first invalid node

Returns:

List of invalid nodes (empty if all valid) If raise_on_invalid=True: True if all valid (raises otherwise)

Return type:

If raise_on_invalid=False

Examples

# Validate with function dotvalidate(tree,

lambda n: n.payload.get(“size”, 0) < 1000000, dot_path=”**[type=file]”)

# Validate required attributes dotvalidate(tree,

{“type”: “file”, “tested”: True}, dot_path=”app.src.**”)

# Get list of invalid nodes invalid = dotvalidate(tree,

lambda n: len(n.name) <= 255, raise_on_invalid=False)

AlgoTree.dotnormalize(tree: Node, normalizer: Callable[[str], str] | None = None, normalize_payload: bool = False, in_place: bool = False) Node[source]

Normalize node names and optionally payload keys.

Parameters:
  • tree – Tree to normalize

  • normalizer – Function to normalize names (default: lowercase + underscore)

  • normalize_payload – If True, also normalize payload keys

  • in_place – If True, modify tree in place

Returns:

Normalized tree

Examples

# Default normalization (lowercase, spaces to underscores) tree = dotnormalize(tree)

# Custom normalization tree = dotnormalize(tree,

normalizer=lambda s: s.lower().replace(“-”, “_”))

# Also normalize payload keys tree = dotnormalize(tree, normalize_payload=True)

Open Transformations (Tree → Any)

AlgoTree.dotpipe(tree: Node, *transformers: Callable | Tuple[str, Callable]) Any[source]

Pipe tree through a series of transformations.

This is the main function for open transformations - converting trees to any structure through a pipeline of operations.

Parameters:
  • tree – Tree to transform

  • *transformers – Variable number of transformers, each can be: - Callable: Applied to entire result of previous stage - Tuple[str, Callable]: (dot_path, transformer) applies to matched nodes

Returns:

Result of the final transformation (can be any type)

Examples

# Extract all names as a list names = dotpipe(tree,

lambda t: [n.name for n in t.traverse_preorder()])

# Pipeline of transformations result = dotpipe(tree,

(”**.config”, lambda n: n.payload), # Extract config payloads lambda configs: {c.get(“name”): c for c in configs}, # Dict by name lambda d: list(d.values())) # Back to list

# Convert tree to nested dict data = dotpipe(tree, to_dict)

# Extract and process specific data totals = dotpipe(tree,

(”**[type=file]”, lambda n: n.payload.get(“size”, 0)), sum) # Sum all sizes

AlgoTree.to_dict(node: Node, include_children: bool = True, include_parent: bool = False, key_mapper: Callable[[str], str] | None = None) Dict[str, Any][source]

Convert tree node to dictionary representation.

Parameters:
  • node – Node to convert

  • include_children – If True, recursively include children

  • include_parent – If True, include parent reference (careful: can be circular)

  • key_mapper – Optional function to transform keys

Returns:

Dictionary representation of the node

Examples

# Simple conversion data = to_dict(tree)

# Without children (just this node) node_data = to_dict(tree, include_children=False)

# With key transformation data = to_dict(tree, key_mapper=str.upper)

AlgoTree.to_list(node: Node, traverse_order: str = 'preorder', include_data: bool = True) List[str | Dict[str, Any]][source]

Convert tree to flat list representation.

Parameters:
  • node – Root node

  • traverse_order – Traversal order (“preorder”, “postorder”, “levelorder”)

  • include_data – If True, include full node data; if False, just names

Returns:

List of nodes (as dicts or names)

Examples

# List of all node names names = to_list(tree, include_data=False)

# List of node data in level order nodes = to_list(tree, traverse_order=”levelorder”)

AlgoTree.to_paths(node: Node, path_separator: str = '.', include_payload: bool = False) List[str] | Dict[str, Any][source]

Convert tree to path representations.

Parameters:
  • node – Root node

  • path_separator – Separator for path components

  • include_payload – If True, return dict mapping paths to payloads

Returns:

List of paths or dict mapping paths to payloads

Examples

# List of all paths paths = to_paths(tree) # [“app”, “app.config”, “app.database”, …]

# Paths with payloads path_data = to_paths(tree, include_payload=True) # {“app”: {…}, “app.config”: {…}, …}

# Using different separator paths = to_paths(tree, path_separator=”/”) # [“app”, “app/config”, “app/database”, …]

AlgoTree.to_adjacency_list(node: Node) Dict[str, List[str]][source]

Convert tree to adjacency list representation.

Parameters:

node – Root node

Returns:

Dictionary mapping node names to lists of child names

Examples

adj = to_adjacency_list(tree) # {“app”: [“config”, “database”], “config”: [], …}

AlgoTree.to_edge_list(node: Node, include_root: bool = False) List[Tuple[str, str]][source]

Convert tree to edge list representation.

Parameters:
  • node – Root node

  • include_root – If True, include edge from None to root

Returns:

List of (parent, child) tuples

Examples

edges = to_edge_list(tree) # [(“app”, “config”), (“app”, “database”), …]

AlgoTree.to_nested_lists(node: Node) List[source]

Convert tree to nested list structure (like S-expressions).

Parameters:

node – Root node

Returns:

Nested list representation

Examples

nested = to_nested_lists(tree) # [“app”, [“config”], [“database”], [“modules”, [“auth”], [“api”]]]

AlgoTree.to_table(node: Node, columns: List[str] | None = None, include_path: bool = True) List[Dict[str, Any]][source]

Convert tree to tabular/relational format.

Parameters:
  • node – Root node

  • columns – Specific payload columns to include (None = all)

  • include_path – If True, include full path to node

Returns:

List of row dictionaries suitable for DataFrame or CSV

Examples

# Convert to table format rows = to_table(tree, columns=[“type”, “size”, “enabled”])

# Can be used with pandas: # df = pd.DataFrame(rows)

AlgoTree.dotextract(tree: Node, extractor: Callable[[Node], Any], dot_path: str = '**', flatten: bool = True) List[Any] | Dict[str, Any][source]

Extract data from tree nodes using custom extractor.

Parameters:
  • tree – Tree to extract from

  • extractor – Function to extract data from each node

  • dot_path – Pattern to match nodes

  • flatten – If True, return flat list; if False, preserve structure

Returns:

Extracted data as list or structured dict

Examples

# Extract all sizes sizes = dotextract(tree, lambda n: n.payload.get(“size”))

# Extract node info for files files = dotextract(tree,

lambda n: {“name”: n.name, “size”: n.payload[“size”]}, dot_path=”**[type=file]”)

AlgoTree.dotcollect(tree: Node, collector: Callable[[Node, Any], Any], initial: Any = None, dot_path: str = '**') Any[source]

Collect data from tree using a collector function.

Similar to reduce but more focused on building collections.

Parameters:
  • tree – Tree to collect from

  • collector – Function (node, accumulator) -> new_accumulator

  • initial – Initial accumulator value

  • dot_path – Pattern to match nodes

Returns:

Final collected value

Examples

# Collect into a dict by type by_type = dotcollect(tree,

lambda n, acc: {

**acc, n.payload.get(“type”, “unknown”):

acc.get(n.payload.get(“type”, “unknown”), []) + [n.name]

}, initial={})

# Collect statistics stats = dotcollect(tree,

lambda n, acc: {

“count”: acc[“count”] + 1, “total_size”: acc[“total_size”] + n.payload.get(“size”, 0), “max_depth”: max(acc[“max_depth”], n.level)

}, initial={“count”: 0, “total_size”: 0, “max_depth”: 0})

AlgoTree.dotgroup(tree: Node, grouper: str | Callable[[Node], Any], dot_path: str = '**') Dict[Any, List[Node]][source]

Group tree nodes by a key.

Parameters:
  • tree – Tree to group nodes from

  • grouper – Either: - String: payload key to group by - Callable: function to compute group key

  • dot_path – Pattern to match nodes

Returns:

Dictionary mapping group keys to lists of nodes

Examples

# Group by type by_type = dotgroup(tree, “type”)

# Group by custom function by_level = dotgroup(tree, lambda n: n.level)

# Group files by extension by_ext = dotgroup(tree,

lambda n: n.name.split(“.”)[-1] if “.” in n.name else “no_ext”, dot_path=”**[type=file]”)

AlgoTree.dotpartition(tree: Node, predicate: Callable[[Node], bool], dot_path: str = '**') Tuple[List[Node], List[Node]][source]

Partition nodes into two groups based on predicate.

Parameters:
  • tree – Tree to partition

  • predicate – Function returning True for first group, False for second

  • dot_path – Pattern to match nodes

Returns:

Tuple of (matching_nodes, non_matching_nodes)

Examples

# Partition by size large, small = dotpartition(tree, lambda n: n.payload.get(“size”, 0) > 1000)

# Partition enabled/disabled enabled, disabled = dotpartition(tree,

lambda n: n.payload.get(“enabled”, False), dot_path=”app.modules.*”)

AlgoTree.dotproject(tree: Node, projection: List[str] | Dict[str, str], dot_path: str = '**') List[Dict[str, Any]][source]

Project specific fields from nodes (like SQL SELECT).

Parameters:
  • tree – Tree to project from

  • projection – Either: - List of field names to include - Dict mapping field names to aliases

  • dot_path – Pattern to match nodes

Returns:

List of projected dictionaries

Examples

# Select specific fields data = dotproject(tree, [“name”, “size”, “type”])

# With aliases data = dotproject(tree, {

“name”: “file_name”, “size”: “file_size”, “type”: “file_type”

})

AlgoTree.to_graphviz_data(tree: Node) Dict[str, Any][source]

Convert tree to GraphViz data structure.

Returns dict with ‘nodes’ and ‘edges’ suitable for visualization.

AlgoTree.to_json_schema(tree: Node, type_key: str = 'type', required_key: str = 'required') Dict[str, Any][source]

Convert tree to JSON Schema-like structure.

Useful for representing configuration schemas or data models.

Tree DSL Parsing

AlgoTree.parse_tree(text: str, format: str = 'auto') Node[source]

Convenience function to parse tree from DSL text.

Parameters:
  • text – DSL text to parse.

  • format – Format to use (‘visual’, ‘indent’, ‘sexpr’, ‘auto’).

Returns:

Root node of parsed tree.

Examples

# Visual format tree = parse_tree(‘’’

company ├── engineering │ ├── frontend │ └── backend └── sales

‘’’)

# Indent format tree = parse_tree(‘’’

company
engineering

frontend backend

sales

‘’’)

# S-expression format tree = parse_tree(‘’’

(company
(engineering

(frontend) (backend))

(sales))

‘’’)

class AlgoTree.TreeDSL[source]

Bases: object

Parser for various tree DSL formats.

static parse(text: str, format: str = 'auto') Node[source]

Parse tree from DSL text.

Parameters:
  • text – DSL text to parse.

  • format – Format to use (‘visual’, ‘indent’, ‘sexpr’, ‘auto’). ‘auto’ tries to detect format automatically.

Returns:

Root node of parsed tree.

Export Functions

class AlgoTree.TreeExporter[source]

Bases: object

Base class for tree exporters.

static to_ascii(node: Node, style: str = 'ascii') str[source]

Export tree to ASCII/Unicode art.

Parameters:
  • node – Root node of tree

  • style – “ascii” for ASCII characters, “unicode” for box drawing

Returns:

String representation of tree

static to_dict(node: Node) Dict[str, Any][source]

Export tree to dictionary (already implemented in Node).

static to_graphviz(node: Node, name: str = 'Tree', node_attr: Callable[[Node], Dict[str, str]] | None = None, edge_attr: Callable[[Node, Node], Dict[str, str]] | None = None, graph_attr: Dict[str, str] | None = None) str[source]

Export tree to GraphViz DOT format.

Parameters:
  • node – Root node of tree

  • name – Graph name

  • node_attr – Function to generate node attributes

  • edge_attr – Function to generate edge attributes

  • graph_attr – Graph-level attributes

Returns:

DOT format string

Example

dot = TreeExporter.to_graphviz(tree,

node_attr=lambda n: {“label”: f”{n.name}n{n.payload.get(‘size’, ‘’)}”})

static to_html(node: Node, include_styles: bool = True, collapsible: bool = True) str[source]

Export tree to interactive HTML.

Parameters:
  • node – Root node of tree

  • include_styles – Include CSS styles

  • collapsible – Make tree nodes collapsible

Returns:

HTML string representation

static to_json(node: Node, indent: int = 2) str[source]

Export tree to JSON string.

static to_mermaid(node: Node, direction: str = 'TD', node_shape: str = 'round', node_text: Callable[[Node], str] | None = None) str[source]

Export tree to Mermaid diagram format.

Parameters:
  • node – Root node of tree

  • direction – Graph direction (TD, TB, BT, RL, LR)

  • node_shape – Shape style (“round”, “square”, “circle”, “rhombus”, “stadium”)

  • node_text – Function to generate node text

Returns:

Mermaid format string

Example

mermaid = TreeExporter.to_mermaid(tree,

node_text=lambda n: f”{n.name}<br/>{n.payload.get(‘type’, ‘’)}”)

static to_unicode(node: Node) str[source]

Export tree to Unicode box drawing (alias for to_ascii with unicode style).

static to_xml(node: Node, root_tag: str = 'tree', indent: int = 2) str[source]

Export tree to XML format.

Parameters:
  • node – Root node of tree

  • root_tag – Tag name for root element

  • indent – Number of spaces per level

Returns:

XML string representation

static to_yaml(node: Node, indent: int = 2) str[source]

Export tree to YAML-like indented format.

Parameters:
  • node – Root node of tree

  • indent – Number of spaces per level

Returns:

YAML-like string representation

AlgoTree.export_tree(node: Node, format: str, **kwargs) str[source]

Export tree to specified format.

Parameters:
  • node – Root node of tree

  • format – Export format (json, ascii, unicode, graphviz, mermaid, yaml, xml, html)

  • **kwargs – Format-specific options

Returns:

String representation in specified format

AlgoTree.save_tree(node: Node, filepath: str, format: str | None = None, **kwargs)[source]

Save tree to file in specified format.

Parameters:
  • node – Root node of tree

  • filepath – Output file path

  • format – Export format (auto-detected from extension if not specified)

  • **kwargs – Format-specific options

Visualization

AlgoTree.pretty_tree(node, **kwargs) str[source]

Converts a tree to a pretty string representation.

Parameters:

kwargs – Key-word arguments. See PrettyTree for more details.

Returns:

A pretty string representation of the tree.

class AlgoTree.PrettyTree(style: ~typing.Dict[str, str] | None = None, node_name: ~typing.Callable[[~typing.Any], str] = <function PrettyTree.<lambda>>, indent: int = 7, mark: ~typing.List[str] | None = None, node_details: ~typing.Callable[[~typing.Any], ~typing.Any] | None = None)[source]

Bases: object

A class to print a tree in a more readable way.

default_style = {'child_connector': '├', 'horizontal': '─', 'last_child_connector': '└', 'markers': ['🔵', '🔴', '🟢', '🟣', '🟠', '🟡', '🟤', '⚫', '⚪', '⭕', '🔘'], 'payload_connector': '◄', 'spacer': ' ', 'vertical': '│'}
static mark(name: str, markers: List[str]) str[source]

Get the marker for a node based on the hash of the node name.

Parameters:

name – The name of the node.

Returns:

The marker for the node.