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

World Map (solarized theme)

World Map

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

Ten 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 --theme solarized
graphtty graph.json --theme nord
graphtty graph.json --theme catppuccin
graphtty graph.json --theme gruvbox
graphtty graph.json --theme tokyo-night
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.4.tar.gz (233.5 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.4-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: graphtty-0.0.4.tar.gz
  • Upload date:
  • Size: 233.5 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.4.tar.gz
Algorithm Hash digest
SHA256 63433607c1aed8b55421b3bfac9ac0d66f6cc83dfe7d3aa32195ab5d9d72c4dc
MD5 5715668f4d764acd4f14b7a90ecf6e30
BLAKE2b-256 ebfc1a55a68ad01183aa86dc16f610d2d9b87c95116e844326881a60a834dfcf

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphtty-0.0.4.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.4-py3-none-any.whl.

File metadata

  • Download URL: graphtty-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 17.2 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.4-py3-none-any.whl
Algorithm Hash digest
SHA256 e02c881495ae00a849876c1cb0e19b6eb388b8a112f35b93fcb21c4949d8a609
MD5 a7b60a9af5ab8731b3b9892b8180336b
BLAKE2b-256 3cfebc27acec543a5ba29104572c5784b8c34ce9aa06249778d1037c5d8f55b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphtty-0.0.4-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