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 |