Skip to main content

Render directed graphs as ASCII/Unicode art for console output

Project description

graphtty

PyPI downloads PyPI - Version Python versions

Render directed graphs as ASCII/Unicode art for console output.

Installation

pip install graphtty

Screenshots

React Agent (monokai theme)

React Agent

Deep Agent (ocean theme)

Deep Agent

Workflow Agent (forest theme)

Workflow Agent

Supervisor Agent (dracula theme)

Supervisor Agent

CLI

Render any graph JSON file straight from the terminal:

graphtty graph.json
graphtty graph.json --theme monokai
graphtty graph.json --ascii
graphtty graph.json --no-types

Options

usage: graphtty [-h] [-t THEME] [--ascii] [--no-types] [--list-themes] [file]

positional arguments:
  file                  Path to a graph JSON file

options:
  -h, --help            show this help message and exit
  -t THEME, --theme THEME
                        Color theme (use --list-themes to see options)
  --ascii               Use plain ASCII instead of Unicode box-drawing characters
  --no-types            Hide node type labels
  --list-themes         List available themes and exit

Themes

Five built-in color themes that style nodes by type:

graphtty graph.json --theme monokai
graphtty graph.json --theme ocean
graphtty graph.json --theme forest
graphtty graph.json --theme dracula
graphtty graph.json                   # default (no color)

List all available themes:

graphtty --list-themes

Python API

Simple linear chain

from graphtty import AsciiGraph, AsciiNode, AsciiEdge, render

graph = AsciiGraph(
    nodes=[
        AsciiNode(id="a", name="Start", type="entry"),
        AsciiNode(id="b", name="Process", type="tool"),
        AsciiNode(id="c", name="End", type="exit"),
    ],
    edges=[
        AsciiEdge(source="a", target="b"),
        AsciiEdge(source="b", target="c"),
    ],
)

print(render(graph))
  ┌ entry ──┐
  │  Start  │
  └────┬────┘
       │
       ▼
  ┌ tool ───┐
  │ Process │
  └─────┬───┘
        │
        ▼
   ┌ exit ──┐
   │  End   │
   └────────┘

Branching with edge labels

graph = AsciiGraph(
    nodes=[
        AsciiNode(id="start", name="User Input", type="entry"),
        AsciiNode(id="router", name="Router", type="condition"),
        AsciiNode(id="search", name="Web Search", type="tool"),
        AsciiNode(id="calc", name="Calculator", type="tool"),
        AsciiNode(id="respond", name="Respond", type="model"),
    ],
    edges=[
        AsciiEdge(source="start", target="router"),
        AsciiEdge(source="router", target="search", label="search"),
        AsciiEdge(source="router", target="calc", label="calc"),
        AsciiEdge(source="search", target="respond"),
        AsciiEdge(source="calc", target="respond"),
    ],
)

print(render(graph))
           ┌ entry ─────┐
           │ User Input │
           └─────┬──────┘
                 │
                 ▼
          ┌ condition ──┐
          │   Router    │
          └──────┬──────┘
         ┌search─└──calc───┐
         ▼                 ▼
  ┌ tool ──────┐    ┌ tool ──────┐
  │ Web Search │    │ Calculator │
  └──────┬─────┘    └──────┬─────┘
         └───────┌─────────┘
                 ▼
            ┌ model ──┐
            │ Respond │
            └─────────┘

Nested subgraphs

sub = AsciiGraph(
    nodes=[
        AsciiNode(id="s1", name="Fetch Data", type="tool"),
        AsciiNode(id="s2", name="Transform", type="action"),
    ],
    edges=[AsciiEdge(source="s1", target="s2")],
)

graph = AsciiGraph(
    nodes=[
        AsciiNode(id="a", name="Start", type="entry"),
        AsciiNode(id="b", name="ETL Pipeline", type="subgraph", subgraph=sub),
        AsciiNode(id="c", name="Done", type="exit"),
    ],
    edges=[
        AsciiEdge(source="a", target="b"),
        AsciiEdge(source="b", target="c"),
    ],
)

print(render(graph))
     ┌ entry ──┐
     │  Start  │
     └─────┬───┘
           │
           ▼
  ┌ subgraph ──────┐
  │  ETL Pipeline  │
  │ ┌ tool ──────┐ │
  │ │ Fetch Data │ │
  │ └──────┬─────┘ │
  │        │       │
  │        ▼       │
  │  ┌ action ───┐ │
  │  │ Transform │ │
  │  └───────────┘ │
  └────────┬───────┘
           │
           ▼
      ┌ exit ──┐
      │  Done  │
      └────────┘

Node descriptions

graph = AsciiGraph(
    nodes=[
        AsciiNode(id="a", name="LLM", type="model", description="gpt-4o"),
    ],
)

print(render(graph))

Themes (Python API)

from graphtty import render, RenderOptions, get_theme

options = RenderOptions(theme=get_theme("monokai"))
print(render(graph, options))

Render options

from graphtty import RenderOptions

options = RenderOptions(
    use_unicode=True,   # Use Unicode box-drawing characters (default: True)
    show_types=True,    # Show node types in box borders (default: True)
    padding=2,          # Padding around the diagram (default: 2)
)

print(render(graph, options))

JSON format

graphtty reads a simple JSON format:

{
  "nodes": [
    { "id": "a", "name": "Start", "type": "entry" },
    { "id": "b", "name": "Process", "type": "tool", "description": "optional detail" },
    { "id": "c", "name": "End", "type": "exit" }
  ],
  "edges": [
    { "source": "a", "target": "b", "label": "optional" },
    { "source": "b", "target": "c" }
  ]
}

Testing

uv run pytest tests/ -v

Acknowledgements

Built with :heart: on top of grandalf, a Python library for graph layout using the Sugiyama algorithm.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

graphtty-0.0.2.tar.gz (187.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

graphtty-0.0.2-py3-none-any.whl (16.5 kB view details)

Uploaded Python 3

File details

Details for the file graphtty-0.0.2.tar.gz.

File metadata

  • Download URL: graphtty-0.0.2.tar.gz
  • Upload date:
  • Size: 187.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for graphtty-0.0.2.tar.gz
Algorithm Hash digest
SHA256 f031fac9041fcbf2c465b1d7946c7558ea3f9c3400c8cf05da09c80f01334e8a
MD5 95c49f25a2b305ed12b91e9678fee1e2
BLAKE2b-256 427d4f8588ba9f64f79701266ef4f207e117dc4e848b7afe31940dcba44e5539

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphtty-0.0.2.tar.gz:

Publisher: cd.yml on cristipufu/graphtty

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file graphtty-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: graphtty-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 16.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for graphtty-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6eee7469b4b2d9338dd6c4fd0d7c438e86a9ffce8f23e7e902fb178e99b4c090
MD5 74a627f1627c6fa3e612f458d6c8c8e9
BLAKE2b-256 67bbb304d31d66f1be7a87e8f3ea4e0b73d9f6b1e842f464a464dee7222fcfd0

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphtty-0.0.2-py3-none-any.whl:

Publisher: cd.yml on cristipufu/graphtty

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page