opsis
Nice and simple command-line output for Python. Fka comms
Note: This package is experimental — the API may change between releases.
What is this?
opsis gives you a clean, consistent way to print structured output from CLI applications. It handles the fiddly bits — column alignment, truncation, spinners, timing — so you can focus on what your tool actually does.
It's particularly useful for scripts and tools that perform a sequence of discrete tasks (parsing files, calling APIs, running checks, etc.) where you want to show progress without cluttering the terminal.
Install
pip install opsis
Quick start
from opsis import Comms
comms = Comms(prefix="myapp")
comms.announce("Starting up")
comms.talk("Processing input files...")
comms.warn("Something looks off!")
This produces neatly aligned, prefixed output like:
[myapp] Starting up
[myapp] -> Processing input files...
[myapp] ** Something looks off!
Features
Messages
comms.talk("Regular message") # prefixed, indented with ->
comms.announce("Important heading") # bold, followed by a blank line
comms.warn("Something went wrong") # bold red, indented with **
Multi-line messages
Print structured, multi-line output with an optional boldened title:
comms.state("Line one\nLine two\nLine three", title="Results")
comms.state(["Also works", "with lists"])
Reporter
For multi-step operations, use a Reporter. It manages tasks, steps, timing, and animated spinners for you:
reporter = comms.reporter()
reporter.start("building project") # begins a timed task
reporter.step("compiling sources") # shows a spinner while waiting
# ... do work ...
reporter.step("linking binaries") # finishes previous step, starts next
# ... do work ...
reporter.done() # prints completion with elapsed time
Each step is automatically timed. While a step is running, a spinner animates in-place. When the next step starts (or done() is called), the previous step's duration is printed:
[myapp] start building project ...
[myapp] .. compiling sources ✓ (1.203s)
[myapp] .. linking binaries ✓ (0.042s)
[myapp] done building project! ✓ (1.245s)
For fast, repetitive operations, use a ticker instead of a spinner:
reporter.step("processing files", spin=False)
for i, path in enumerate(files):
process(path)
reporter.tick(f"file {i}") # updates in-place, throttled
You can still use comms.talk() and comms.warn() during a reporter session — they print cleanly without disrupting the spinner.
Custom prefix
Every Comms instance takes a prefix that appears in brackets on each line. Use this to identify your tool:
comms = Comms(prefix="deploy")
# [deploy] -> uploading artifacts...
Silent mode
Pass silent=True to suppress all output from a Comms instance — handy for a --quiet flag. Every method becomes a no-op, and any reporter() it creates inherits the silence, so spinners and tickers stay quiet too:
comms = Comms(prefix="myapp", silent=True)
comms.talk("you will never see this")
reporter = comms.reporter() # also silent
Pass silent explicitly to reporter() to override per reporter.
TTY detection
Spinners and tickers are automatically disabled when stdout is not a TTY (e.g. when piping to a file or running in CI). Your output stays clean and parseable without any extra configuration.
Dependencies
Just click (for styled terminal output).
License
MIT
Metadata
Release files for opsis 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| opsis-0.2.0.tar.gz | 7.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| opsis-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 15.2 kB
Release files / opsis-0.2.0.tar.gz
| Download URL | opsis-0.2.0.tar.gz |
|---|---|
| Size | 7.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ae47bdca1085c9900aab90b4b29436cf7f98d516f58515251296f2265bb9e00d
|
|
BLAKE2b-256 checksum How to use checksums |
6eb5156afcd52265ec2360bc5100a79caa9efefe772fe3f3e84c2cf386beff0c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jun 30, 2026.
Transparency logRelease files / opsis-0.2.0-py3-none-any.whl
| Download URL | opsis-0.2.0-py3-none-any.whl |
|---|---|
| Size | 7.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
13d598673b9ebac1ebb67682951f8e7fb6b594e0fa36727ebdf1b1505010de3b
|
|
BLAKE2b-256 checksum How to use checksums |
749d23114c2ad8e7315730ca51649db2b242588873dfaaa535a5d01ecccb7df0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jun 30, 2026.
Transparency log