Powerful and Lightweight Python Tree Data Structure with various plugins
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
ASCII and Unicode tree rendering with multiple built-in styles for displaying tree structures in console output, documentation, and reports. Provides comprehensive visualization capabilities with customizable formatting.
Main class for rendering tree structures as formatted text with various styling options, child ordering control, and depth limits.
class RenderTree:
"""
Renders tree structure as formatted text.
Args:
node: Root node to render from
style: Rendering style (ContStyle, AsciiStyle, etc.)
childiter: Function to determine child iteration order
maxlevel: Maximum depth to render
"""
def __init__(self, node, style=ContStyle(), childiter=list, maxlevel=None): ...
def __str__(self) -> str: ...
def __iter__(self) -> Iterator[Row]: ...Usage Example:
from anytree import Node, RenderTree, AsciiStyle
# Create tree structure
root = Node("Company")
engineering = Node("Engineering", parent=root)
marketing = Node("Marketing", parent=root)
Node("Backend", parent=engineering)
Node("Frontend", parent=engineering)
Node("Content", parent=marketing)
# Basic rendering
print(RenderTree(root))
# Company
# ├── Engineering
# │ ├── Backend
# │ └── Frontend
# └── Marketing
# └── Content
# ASCII-only rendering
print(RenderTree(root, style=AsciiStyle()))
# Company
# |-- Engineering
# | |-- Backend
# | +-- Frontend
# +-- Marketing
# +-- Content
# With max level limit
print(RenderTree(root, maxlevel=2))
# Company
# ├── Engineering
# └── MarketingMultiple built-in styles for different output requirements and character set compatibility.
Default Unicode style with continuous line characters for modern terminals and documentation.
class ContStyle(AbstractStyle):
"""
Unicode tree rendering with continuous lines.
"""
def __init__(self): ...
vertical = "│"
cont = "├── "
end = "└── "ASCII-compatible style for environments that don't support Unicode characters.
class AsciiStyle(AbstractStyle):
"""
ASCII-only tree rendering style.
"""
def __init__(self): ...
vertical = "|"
cont = "|-- "
end = "+-- "Unicode style with rounded corner characters for a softer visual appearance.
class ContRoundStyle(AbstractStyle):
"""
Unicode tree rendering with rounded corners.
"""
def __init__(self): ...
vertical = "│"
cont = "├─ "
end = "╰─ "Unicode style with double-line characters for emphasis and visual distinction.
class DoubleStyle(AbstractStyle):
"""
Unicode tree rendering with double lines.
"""
def __init__(self): ...
vertical = "║"
cont = "╠══ "
end = "╚══ "Base class for creating custom rendering styles with user-defined characters.
class AbstractStyle:
"""
Tree Render Style base class.
Args:
vertical: Sign for vertical line
cont: Chars for a continued branch
end: Chars for the last branch
"""
def __init__(self, vertical, cont, end): ...
vertical: str
cont: str
end: strUsage Example:
from anytree import Node, RenderTree, AbstractStyle
# Create custom style
class CustomStyle(AbstractStyle):
def __init__(self):
super().__init__(
vertical="▏",
cont="▣ ",
end="▣ "
)
root = Node("root")
Node("child1", parent=root)
Node("child2", parent=root)
print(RenderTree(root, style=CustomStyle()))Control the order in which child nodes are rendered using the childiter parameter:
from anytree import Node, RenderTree
root = Node("root")
Node("zebra", parent=root)
Node("apple", parent=root)
Node("beta", parent=root)
# Default order (insertion order)
print("Default order:")
print(RenderTree(root))
# Alphabetical order
print("\nAlphabetical order:")
print(RenderTree(root, childiter=lambda children: sorted(children, key=lambda n: n.name)))
# Reverse order
print("\nReverse order:")
print(RenderTree(root, childiter=lambda children: reversed(children)))
# Custom sorting (by length)
print("\nBy name length:")
print(RenderTree(root, childiter=lambda children: sorted(children, key=lambda n: len(n.name))))Render only a specific number of levels to focus on tree structure or handle very deep trees:
from anytree import Node, RenderTree
# Create deep tree
root = Node("Level 0")
current = root
for i in range(1, 6):
current = Node(f"Level {i}", parent=current)
Node(f"Side branch {i}", parent=current)
# Show only first 3 levels
print("First 3 levels:")
print(RenderTree(root, maxlevel=3))
# Show only top 2 levels
print("\nTop 2 levels:")
print(RenderTree(root, maxlevel=2))Access individual rendered rows for custom processing or formatting:
from anytree import Node, RenderTree, Row
root = Node("Company")
engineering = Node("Engineering", parent=root)
Node("Alice", parent=engineering, role="Engineer")
Node("Bob", parent=engineering, role="Manager")
# Process each row individually
for row in RenderTree(root):
# row is a Row namedtuple with fields: pre, fill, node
indent = row.pre
node = row.node
fill = row.fill
# Custom formatting
if hasattr(node, 'role'):
print(f"{indent}{node.name} ({node.role})")
else:
print(f"{indent}{node.name}")Include additional node information in rendered output:
from anytree import Node, RenderTree
class InfoNode(Node):
def __init__(self, name, info=None, **kwargs):
super().__init__(name, **kwargs)
self.info = info
def __str__(self):
if self.info:
return f"{self.name} [{self.info}]"
return self.name
root = InfoNode("Company", "Founded 2020")
eng = InfoNode("Engineering", "50 employees", parent=root)
InfoNode("Backend Team", "Python/Django", parent=eng)
InfoNode("Frontend Team", "React/TypeScript", parent=eng)
print(RenderTree(root))
# Company [Founded 2020]
# └── Engineering [50 employees]
# ├── Backend Team [Python/Django]
# └── Frontend Team [React/TypeScript]Here's how the same tree looks with different styles:
from anytree import Node, RenderTree, AsciiStyle, ContStyle, ContRoundStyle, DoubleStyle
# Create sample tree
root = Node("root")
child1 = Node("child1", parent=root)
child2 = Node("child2", parent=root)
Node("grandchild1", parent=child1)
Node("grandchild2", parent=child1)
Node("grandchild3", parent=child2)
styles = [
("ContStyle (default)", ContStyle()),
("AsciiStyle", AsciiStyle()),
("ContRoundStyle", ContRoundStyle()),
("DoubleStyle", DoubleStyle())
]
for name, style in styles:
print(f"\n{name}:")
print(RenderTree(root, style=style))Output:
ContStyle (default):
root
├── child1
│ ├── grandchild1
│ └── grandchild2
└── child2
└── grandchild3
AsciiStyle:
root
|-- child1
| |-- grandchild1
| +-- grandchild2
+-- child2
+-- grandchild3
ContRoundStyle:
root
├─ child1
│ ├─ grandchild1
│ ╰─ grandchild2
╰─ child2
╰─ grandchild3
DoubleStyle:
root
╠══ child1
║ ╠══ grandchild1
║ ╚══ grandchild2
╚══ child2
╚══ grandchild3from anytree import Node, RenderTree
def generate_api_tree(modules):
"""Generate API documentation tree"""
root = Node("API Documentation")
for module_name, functions in modules.items():
module_node = Node(module_name, parent=root)
for func_name in functions:
Node(func_name, parent=module_node)
return RenderTree(root)
modules = {
"authentication": ["login", "logout", "verify_token"],
"user_management": ["create_user", "update_user", "delete_user"],
"data_processing": ["process_csv", "validate_data"]
}
print(generate_api_tree(modules))import os
from anytree import Node, RenderTree
def create_file_tree(path, max_depth=3):
"""Create tree representation of file system"""
def add_path(parent, path, current_depth):
if current_depth >= max_depth:
return
try:
for item in os.listdir(path):
item_path = os.path.join(path, item)
node = Node(item, parent=parent)
if os.path.isdir(item_path):
add_path(node, item_path, current_depth + 1)
except PermissionError:
pass
root = Node(os.path.basename(path) or path)
add_path(root, path, 0)
return RenderTree(root)
# Visualize current directory structure
print(create_file_tree(".", max_depth=2))from anytree import Node, RenderTree
class Employee(Node):
def __init__(self, name, title, parent=None):
super().__init__(name, parent=parent)
self.title = title
def __str__(self):
return f"{self.name} ({self.title})"
# Build org chart
ceo = Employee("Alice Johnson", "CEO")
cto = Employee("Bob Smith", "CTO", parent=ceo)
cfo = Employee("Carol Davis", "CFO", parent=ceo)
Employee("David Wilson", "Senior Engineer", parent=cto)
Employee("Eve Brown", "DevOps Engineer", parent=cto)
Employee("Frank Miller", "Accountant", parent=cfo)
print("Organizational Chart:")
print(RenderTree(ceo))Install with Tessl CLI
npx tessl i tessl/pypi-anytree