dotpath

The master addressing engine for the dotsuite ecosystem. A fully extensible, registration-based path engine where each capability is encapsulated in a self-contained segment class.

Overview

dotpath is the Turing-complete addressing engine that underpins the entire Depth pillar. While simpler tools like dotget and dotstar handle common cases, dotpath provides the full power of advanced path expressions including filters, slices, regex matching, and recursive descent.

Installation

pip install dotsuite

Quick Start

from depth.dotpath import find_all, find_first

data = {
    "users": [
        {"name": "Alice", "age": 30, "role": "admin"},
        {"name": "Bob", "age": 25, "role": "user"},
        {"name": "Charlie", "age": 35, "role": "admin"}
    ]
}

# Find all user names
names = find_all("users.*.name", data)
# ["Alice", "Bob", "Charlie"]

# Find first admin
admin = find_first("users[?(@['role'] == 'admin')]", data)
# {"name": "Alice", "age": 30, "role": "admin"}

# Slice operations
first_two = find_all("users[:2].name", data)
# ["Alice", "Bob"]

Path Segment Types

Key

Access dictionary keys using dot notation or bracket notation.

# Dot notation
find_first("user.name", {"user": {"name": "Alice"}})  # "Alice"

# Bracket notation for special characters
find_first("['user-info']['full-name']", {"user-info": {"full-name": "Alice"}})

Index

Access list elements by position (supports negative indices).

find_first("items[0]", {"items": ["a", "b", "c"]})   # "a"
find_first("items[-1]", {"items": ["a", "b", "c"]})  # "c"

Slice

Extract ranges from lists using Python slice syntax.

find_all("items[1:3]", {"items": [0, 1, 2, 3, 4]})    # [1, 2]
find_all("items[::2]", {"items": [0, 1, 2, 3, 4]})    # [0, 2, 4]
find_all("items[-3:]", {"items": [0, 1, 2, 3, 4]})    # [2, 3, 4]

Wildcard (*)

Match all keys in a dict or all elements in a list.

find_all("users.*.name", data)  # All user names
find_all("matrix.*.*", {"matrix": [[1,2], [3,4]]})  # [1, 2, 3, 4]

Descendant (**)

Recursively descend through all nested structures.

data = {"a": {"b": {"c": 1}}, "d": [{"e": 2}]}
find_all("**.c", data)  # Would need filtering, but ** yields all descendants

Filter ([?(...)])

Filter list elements using predicate expressions.

# Filter by field value
find_all("users[?(@['age'] > 25)].name", data)  # ["Alice", "Charlie"]

# Filter by equality
find_all("users[?(@['role'] == 'admin')].name", data)  # ["Alice", "Charlie"]

RegexKey (~r/.../)

Match dictionary keys using regular expressions.

data = {"user_1": "Alice", "user_2": "Bob", "admin": "Charlie"}
find_all("~r/user_\\d+/", data)  # ["Alice", "Bob"]

# Case-insensitive
find_all("~r/USER_\\d+/i", data)  # ["Alice", "Bob"]

Advanced Usage

Custom Path Engine

Create an engine with limited capabilities:

from depth.dotpath import PathEngine, Key, Index

# Minimal engine with only key and index access
engine = PathEngine()
engine.register(Key)
engine.register(Index)

# Can parse simple paths
ast = engine.parse("users[0].name")

# Cannot parse wildcards (not registered)
# engine.parse("users.*")  # Raises ValueError

AST Serialization

Path expressions can be serialized to JSON for storage or transmission:

from depth.dotpath import create_default_engine

engine = create_default_engine()

# Parse to AST
ast = engine.parse("users[0].name")

# Serialize
json_str = engine.ast_to_json(ast)
# '[{"$type": "key", "name": "users"}, {"$type": "index", "value": 0}, ...]'

# Deserialize
restored_ast = engine.json_to_ast(json_str)

Creating Custom Segments

Extend the path language by implementing the PathSegment interface:

from depth.dotpath import PathSegment
from dataclasses import dataclass

@dataclass(frozen=True)
class MySegment(PathSegment):
    _type_name = "my_segment"
    # ... implement parse(), evaluate(), to_dict(), from_dict()

API Reference

Functions

Function Description
find_all(path, doc) Find all values matching the path
find_first(path, doc) Find first value matching the path (or None)
create_default_engine() Create engine with all standard segments

Classes

Class Description
PathEngine Registration-based path parsing and evaluation engine
PathSegment Abstract base class for path segment implementations
Key Dictionary key access
Index List index access
Slice List slice operations
Wildcard Match all children
Descendant Recursive descent
Filter Predicate-based filtering
RegexKey Regex-based key matching

See Also

  • dotget - Simple exact path access
  • dotstar - Wildcard pattern matching
  • dotselect - User-friendly interface to dotpath