Skip to main content

ux3270

IBM 3270-like terminal UI library for Python.

Documentation | PyPI

Overview

Create terminal applications with an IBM 3270-style interaction model: display a form, let the user fill it in, continue when they submit.

Screenshots

The inventory management demo app showcases the library's capabilities:

Main Menu Inventory List Data Entry Form
Main Menu Inventory List Form
Menu with single-key selection Work-with list with action codes Form with field validation

Installation

pip install ux3270

Or with uv:

uv add ux3270

For development of ux3270 itself:

git clone https://github.com/ljosa/ux3270.git
cd ux3270
uv venv && uv pip install -e .

Quick Start

from ux3270.dialog import Menu, Form, Table, TabularEntry, WorkWithList, SelectionList, show_message

# Create a form with help text
form = Form("DATA ENTRY", help_text="Enter your information")
form.add_field("Name", length=30, required=True,
               help_text="Your full name")
form.add_field("Email", length=40)
result = form.show()  # F1 for help, F3 to cancel
if result:
    print(f"Hello, {result['Name']}!")

# Form with F4=Prompt lookup
def select_dept():
    sel = SelectionList("SELECT DEPARTMENT", ["Code", "Name"])
    sel.add_row(Code="ENG", Name="Engineering")
    sel.add_row(Code="SAL", Name="Sales")
    selected = sel.show()
    return selected["Code"] if selected else None

form = Form("ASSIGNMENT")
form.add_field("Department", prompt=select_dept)  # F4 shows list
result = form.show()

# Work-with list (action codes per row)
wwl = WorkWithList("WORK WITH ITEMS", ["ID", "Name", "Status"])
wwl.add_action("2", "Change")
wwl.add_action("4", "Delete")
wwl.add_action("5", "Display")
wwl.set_add_callback(add_new_item)  # F6=Add
wwl.add_row(ID="001", Name="Item 1", Status="Active")
wwl.add_row(ID="002", Name="Item 2", Status="Inactive")
result = wwl.show()  # Returns [{"action": "2", "row": {...}}, ...]
for item in result or []:
    if item["action"] == "2":
        edit_item(item["row"]["ID"])

# Create a menu
menu = Menu("MAIN MENU")
menu.add_item("1", "Option 1", lambda: print("Selected 1"))
menu.add_item("2", "Option 2", lambda: print("Selected 2"))
menu.run()  # Runs until user exits with F3 or X

# Display a table (with pagination)
table = Table("RESULTS", ["ID", "Name", "Status"])
table.add_row("001", "Item 1", "Active")
table.add_row("002", "Item 2", "Inactive")
table.show()  # F7/F8 to page up/down

# Tabular entry (table with editable columns)
te = TabularEntry("PORTFOLIO UPDATE", panel_id="PORT01")
te.add_column("Ticker", width=8)
te.add_column("Name", width=20)
te.add_column("New Amount", width=12, editable=True, required=True)
te.add_column("Previous", width=12)
te.add_row(Ticker="AAPL", Name="Apple Inc", Previous="1,234.56")
te.add_row(Ticker="GOOGL", Name="Alphabet", Previous="5,678.90")
result = te.show()  # Tab between cells, Enter to submit

# Show a message
show_message("Operation completed", msg_type="success")

Demo App

The inventory management system demonstrates the library:

# Load sample data and run
inventory-app --demo

# Or just run (empty database)
inventory-app

# Other options
inventory-app --help

Keyboard Controls

Context Key Action
All F1 Help
All F3 Cancel/Exit
Forms Tab Next field
Forms Shift+Tab Previous field
Forms Enter Submit
Forms F4 Prompt (show selection list)
Fields Left/Right Move cursor
Fields Home/End Start/end of field
Fields Delete Delete at cursor
Fields Backspace Delete before cursor
Fields Insert Toggle insert/overwrite mode
Fields Ctrl+E Erase to end of field
Menus 1-9, A-Z Select item
Tables/Lists F7 Page backward
Tables/Lists F8 Page forward
Tables Enter Return
Selection Lists S Select item
Work-with Lists 1-9, A-Z Enter action code
Work-with Lists Enter Process actions
Work-with Lists F6 Add new record
Tabular Entry Tab Next editable cell
Tabular Entry Shift+Tab Previous editable cell
Tabular Entry Enter Submit all values

Terminal Width

Tables and lists automatically adapt to terminal width:

  • Uses actual terminal width (not hardcoded 80 columns)
  • Short columns are preserved at natural width
  • Long columns are truncated to fit available space
  • Truncated content shows > indicator (e.g., "Very long tex>")

IBM 3270 Colors

The library uses IBM 3270 color conventions:

  • Green: Input fields
  • Turquoise: Labels (protected fields)
  • White: Titles, headers (intensified)
  • Red: Error messages
  • Yellow: Warnings

Requirements

  • Python 3.10+
  • Unix-like system (Linux, macOS)
  • Terminal with ANSI support

Development

Building and Viewing Documentation Locally

uv run mkdocs serve

Then open http://127.0.0.1:8000 in your browser. The site auto-reloads on changes.

Regenerating Screenshots

Screenshots require Docker with VHS:

./screenshots/generate.sh

Cutting a Release

The version number must be updated in two places that must match:

  1. pyproject.toml: The version field (e.g., version = "0.2.0")
  2. Git tag: Must be v + version (e.g., v0.2.0)

Release process:

# 1. Update version in pyproject.toml
#    Edit: version = "0.2.0"

# 2. Commit the version bump
git add pyproject.toml
git commit -m "Bump version to 0.2.0"

# 3. Create and push tag (triggers release workflow)
git tag v0.2.0
git push origin main --tags

The GitHub Actions workflow will automatically:

  • Build and publish the package to PyPI
  • Deploy versioned documentation to GitHub Pages

Documentation Versions

Documentation is versioned using mike. Each release gets its own version, with latest always pointing to the most recent release. Users can switch versions using the dropdown in the docs.

License

MIT

Metadata

Release files for ux3270 1.1.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 ux3270 1.1.0
File Size Uploaded
ux3270-1.1.0.tar.gz 884.0 kB Details

Built distribution (wheel)

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

Total release size: 927.8 kB

Release files / ux3270-1.1.0.tar.gz

Download URL ux3270-1.1.0.tar.gz
Size 884.0 kB
Tags Source
SHA-256 checksum
How to use checksums
0daf7f305975ba2e2d3e4e522f40bebe60fd6ff58a02781cb973567d215a1d06
BLAKE2b-256 checksum
How to use checksums
16fdb0607d41d173378fd2edb1451d020f28d6e0aa3e8f08db5d2160eb232ef7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 13, 2026.

Transparency log

Release files / ux3270-1.1.0-py3-none-any.whl

Download URL ux3270-1.1.0-py3-none-any.whl
Size 43.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
82ddbfe79d19971ecc6a3245f1d4fe9d24df521c97945e1caf815abf4579ad42
BLAKE2b-256 checksum
How to use checksums
70bc78d179acb198ad3ea0799aa3819ca2ba3056f2586bfee396cff39012d77a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.1

2 release files

1.0.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