Skip to content

Instantly share code, notes, and snippets.

@afspies
Created January 22, 2025 12:03
Show Gist options
  • Save afspies/e679e3a02aa05e87cafff9e00ea90779 to your computer and use it in GitHub Desktop.
Save afspies/e679e3a02aa05e87cafff9e00ea90779 to your computer and use it in GitHub Desktop.
Python function to visually inspect json structure
from typing import Any
from rich.console import Console
from rich.theme import Theme
from rich.text import Text
custom_theme = Theme({
"key": "yellow",
"type": "cyan",
"value": "green",
"tree": "bright_black",
})
console = Console(theme=custom_theme, soft_wrap=True)
def _get_tree_prefix(indent: int, is_last: bool = False) -> str:
"""Generate tree-style prefix with proper indentation."""
if indent == 0:
return ""
return "│ " * (indent - 1) + ("└── " if is_last else "├── ")
def _format_content(content: Any, show_content: bool, max_length: int) -> str:
"""Format content with truncation."""
if not show_content:
return ""
content_str = str(content)
if len(content_str) > max_length:
content_str = content_str[:max_length] + "..."
return f" = {content_str}" if content_str else ""
def _build_visualization(
obj: Any,
*,
show_content: bool,
max_length: int,
indent: int = 0,
is_last: bool = True,
key: str = "",
output: Text = None
) -> Text:
"""Build visualization as a single Rich Text object."""
if output is None:
output = Text()
def add_node(label: str, type_name: str, content: str = ""):
"""Add a node to the text output."""
if output.plain: # If not first line, add newline
output.append("\n")
output.append(_get_tree_prefix(indent, is_last), style="tree")
output.append(label, style="key")
output.append(": ", style="tree")
output.append(type_name, style="type")
if content:
output.append(content, style="value")
if isinstance(obj, dict):
if key: # Print dict header if this is a nested dict
add_node(key, "dict")
items = list(obj.items())
for i, (k, v) in enumerate(items):
_build_visualization(
v, show_content=show_content, max_length=max_length,
indent=indent + 1, is_last=i == len(items) - 1,
key=k, output=output
)
elif isinstance(obj, list):
label = key if key else ""
if not obj:
add_node(label, "list", " (empty)")
return output
if all(not isinstance(x, (dict, list)) for x in obj):
types = {type(x).__name__ for x in obj}
type_str = f"list of {' or '.join(types)} [{len(obj)} items]"
add_node(label, type_str)
if show_content:
for i, item in enumerate(obj):
_build_visualization(
item, show_content=show_content, max_length=max_length,
indent=indent + 1, is_last=i == len(obj) - 1,
key=f"[{i}]", output=output
)
return output
add_node(label, "list")
for i, item in enumerate(obj):
_build_visualization(
item, show_content=show_content, max_length=max_length,
indent=indent + 1, is_last=i == len(obj) - 1,
key=f"[{i}]", output=output
)
else:
content = _format_content(obj, show_content, max_length)
add_node(key, type(obj).__name__, content)
return output
def visualize_json(
obj: Any,
*,
show_content: bool = False,
max_length: int = 100,
) -> None:
"""
Visualize JSON structure with tree-style indicators and colored output.
Args:
obj: The JSON object to visualize
show_content: Whether to display the actual values (default: False)
max_length: Maximum length for displayed values before truncation (default: 100)
Example:
>>> data = {
... "name": "John Doe",
... "contacts": {
... "email": "[email protected]",
... "phones": ["+1234567890"]
... }
... }
>>> visualize_json(data) # Shows structure only
>>> visualize_json(data, show_content=True) # Shows values
"""
output = _build_visualization(obj, show_content=show_content, max_length=max_length)
console.print(output)
# Example usage:
if __name__ == "__main__":
sample_json = {
"name": "John Doe",
"contacts": {
"email": "[email protected]",
"phones": ["+1234567890", "+0987654321"],
"emergency": []
},
"addresses": [
{
"type": "home",
"street": "123 Main St",
"city": "Anytown"
},
{
"type": "work",
"street": "456 Office Blvd",
"city": "Workville"
}
],
"scores": [95, 87, 91],
"notes": [],
"active": True
}
print("\nStructure only:")
visualize_json(sample_json)
print("\nWith content:")
visualize_json(sample_json, show_content=True, max_length=50)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment