craft-cli
raw JSON → 3.4.0 verified Fri May 01 auth: no python
A Python framework from Canonical for building CLI tools with structured output, logging, and progress indicators. Current version 3.4.0, requires Python >=3.10. Released on a monthly cadence.
pip install craft-cli Common errors
error ModuleNotFoundError: No module named 'craft_cli' ↓
cause Package not installed or wrong import path (e.g., 'craft-cli' with hyphen).
fix
Install with 'pip install craft-cli' and import as 'craft_cli' (underscore).
error RuntimeError: Emitter already initialized ↓
cause emit.init() called twice without emit.cleanup() in between.
fix
Wrap code in try/finally: emit.init(...); try: ... finally: emit.cleanup().
error AttributeError: module 'craft_cli' has no attribute 'emit' ↓
cause Old import pattern or using incorrect casing.
fix
Use 'from craft_cli import emit'.
Warnings
breaking In version 2.x, craft_cli was internally called CraftCLI but later renamed to craft_cli. Ensure imports use lowercase. ↓
fix Use lowercase 'craft_cli' throughout.
deprecated EmitterMode.BRIEF is considered legacy; prefer EmitterMode.VERBOSE or EmitterMode.QUIET for production. ↓
fix Use EmitterMode.VERBOSE for detailed output, EmitterMode.QUIET for minimal output.
gotcha Calling emit.init() more than once without emit.cleanup() will raise a RuntimeError. ↓
fix Always pair emit.init() with emit.cleanup() in a try/finally block or context manager.
gotcha The appname argument in emit.init() must not contain spaces; otherwise, output formatting may break. ↓
fix Use a single word or hyphenated name for appname.
Imports
- craft_cli
import craft_cli - EmitterMode wrong
from craft_cli.emitter import EmitterModecorrectfrom craft_cli import EmitterMode - emit wrong
from craft_cli.emitter import emitcorrectfrom craft_cli import emit
Quickstart
from craft_cli import emit, EmitterMode
# Initialize the CLI emitter
emit.init(EmitterMode.BRIEF, appname="myapp")
# Simple message
emit.message("Hello, world!")
# Progress bar
with emit.open_stream("Processing") as stream:
for i in range(10):
stream.progress(f"Step {i+1}")
# Error handling
emit.error("Something went wrong")