Skip to main content

termopy

Terminal UIs as pure functions from state to an immutable view tree.

from termopy import View, run

def app(ui):
    return View.text("Hello world!").center(within=ui.size)

run(app)

An app is a function (UI) -> View. It re-runs whenever a frame is marked dirty (state changed, an event arrived, the terminal resized, a timer fired), and the renderer diffs by row before writing escape codes. State lives in hooks on the ui handle.

uv sync                             # or: pip install -e .
python examples/hello_world.py
python examples/theme_gallery.py    # 19 colour flavours, ← → to browse
python examples/charts.py           # line, scatter and bar charts
python examples/focus.py            # three key-hungry widgets, one keyboard
python examples/filter.py           # type to filter a list
python examples/logs.py             # colourised output, tail -f style
python examples/embed.py htop       # another TUI, embedded (needs tmux)
python examples/vi one.py two.py    # a vi clone, built on the core alone
python examples/turbo_python        # Turbo Pascal 7.0's IDE, for Python
python examples/frogmouth README.md # a Markdown browser, ported from Textual

One dependency (Rich, for glyph-width measurement and for drawing Rich renderables into a view), Python 3.12+, POSIX only.

Version 0.2. What is stable says which parts of the API are safe to build on now and which are still moving.

What's here

  • src/termopy/: the core — views, styles, events, terminal, render loop, themes, layout arithmetic, overlapping windows, a command table, key naming, syntax spans, Markdown, ANSI parsing, clipboard
  • src/termopy/widgets/: dialogs, button, checkbox, radio set, selection list, textbox, listbox, table, tabs, progress bar, spinner, rule, border, frame, scroller, tree, directory tree, menu bar, status line, charts, editor, ncdu, tmux pane
  • examples/: all 17 bonsai_term examples, ported and running, plus demos, a vi clone, a Markdown browser and a Turbo Pascal IDE. Start here, inventory, API and design notes.
  • COMPONENTS.md: the bonsai_term_components port, what moved, what changed shape, what was left out.

Documentation

make docs-serve      # live reload
make docs            # build to docs/site/
make docs-check      # strict: a broken cross-reference fails the build

The docs are their own project under docs/, with their own Makefile (cd docs && make works too).

Built with Zensical. docs/ has a guide, a comparison with Textual and other frameworks grounded in two real ports, and notes on the internals.

Tests

A pyramid, run with make test or uv run pytest:

uv run pytest -m unit          # 2,401 — pure functions, no I/O, under a second
uv run pytest -m integration   #   598 — widgets and apps through a UI
uv run pytest -m e2e           #    10 — real programs on a pty
uv run pytest -m "not slow"    # skips the pty and tmux tests
tests/
├── a_unit/          views, styles, events, markdown, typography, and the pure
│                    halves of the two applications: vi's grammar, the IDE's
│                    ast walks, its debugger state and its settings files
├── b_integration/   the runtime, widgets, dialogs, every example, all three apps
├── c_e2e/           pty-driven: alternate screen, keys, vi saving, a modal, and
│                    the IDE editing, compiling and running a program
└── conftest.py      ui / render / screen / scratch_data_dir fixtures

Metadata

Release files for termopy 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for termopy 0.2.0
File Size Uploaded
termopy-0.2.0.tar.gz 96.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for termopy 0.2.0
File Interpreter ABI Platform
termopy-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 211.2 kB

Release files / termopy-0.2.0.tar.gz

Download URL termopy-0.2.0.tar.gz
Size 96.8 kB
Tags Source
SHA-256 checksum
How to use checksums
79a4099a2c8841dd50f06c682a863ef7a4b5182c98a4cf1fd46de3c3591fa1e9
BLAKE2b-256 checksum
How to use checksums
6a308856d782e133d660488c4b67f260d52911dd328575f268073ec3d410dd6c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / termopy-0.2.0-py3-none-any.whl

Download URL termopy-0.2.0-py3-none-any.whl
Size 114.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a4be33fa7cfc1eff4b800bb4b8b33cd8e1d10e77ec3b8376de5cd6fe61492f99
BLAKE2b-256 checksum
How to use checksums
47014178a1e2c1d01a5a2ab8fa374a3fec699b197498b8d6c936f897ce04eb75
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page