Host-side serial REPL for CircuitPython and MicroPython boards with traceback highlighting.
Project description
chumicro-repl
Host-side serial REPL for CircuitPython and MicroPython boards — line-mode editor, passthrough TUI, programmatic ReplSession, and a tail() follower for deploy orchestration.
Two interactive surfaces: a line-mode editor with persistent per-device history, $EDITOR handoff (:edit), saved snippets (:save / :load / :snippets), and Tab completion against keywords + the on-device namespace; or a byte-passthrough TUI with mpremote-compatible keybindings (Ctrl-C / Ctrl-D / Ctrl-X / Ctrl-E) for raw-REPL framing and paste-mode flows. UTF-8-safe streaming + in-stream traceback highlighting + auto-reconnect on cable drop apply to both. Pluggable session-failure classifier so callers can build their own orchestrators on top.
Part of the ChuMicro family — small, focused Python libraries for microcontrollers and laptops. Browse all workbench tools. This is a workbench tool — runs on your laptop, not on the board.
Install
pip install chumicro-repl
pyserial and prompt_toolkit come along as dependencies. No board-side install — chumicro-repl talks to the existing CP / MP runtime over USB serial. Native Windows isn't currently supported (the interactive TUI needs POSIX termios); WSL2 works.
Experimental (pre-release) versions and channel switching
Pre-release builds publish automatically when the package version is bumped.
pip install chumicro-repl-experimental
Quick example
Open an interactive REPL on a board:
chumicro-repl --address /dev/cu.usbmodem1101
That drops you into line mode: type for index in r<Tab> and Tab completes range; up-arrow recalls history; :edit opens $EDITOR with the recent buffer pre-seeded so multi-line blocks aren't a retype; :save my-bringup then :load my-bringup round-trips a snippet you'll paste again tomorrow. Type :help to list every :command.
Need byte-passthrough (paste mode, raw-REPL framing, mpremote-shape Ctrl-C/Ctrl-D)? Add --mode passthrough.
Programmatic — exec something on the board and capture stdout:
from chumicro_deploy import Device
from chumicro_repl import ReplSession
device = Device(transport="micropython", address="/dev/cu.usbmodem1101")
with ReplSession(device) as session:
output = session.exec("import sys; print(sys.implementation)")
print(output) # → "(name='micropython', version=(1,28,0), …)\n"
Follow a board after a deploy, fail the script on a traceback:
from chumicro_repl import tail, ExitCode
result = tail(device, seconds=10)
if result is ExitCode.TRACEBACK_DETECTED:
raise SystemExit("board crashed during follow-up tail")
What's included
Programmatic API
| Symbol | Description |
|---|---|
ReplSession(device) |
Context manager wrapping the raw REPL. exec(code), call(function_name, *args, **kwargs), read_until(pattern, timeout) |
InteractiveReplSession(session) |
Wraps ReplSession with classify + retry + coaching for session-start failures (mirrors chumicro_deploy.RecoveringDeployer shape) |
interactive_line(device) |
Line-mode TUI — host-side line editor with persistent per-device history, :edit / :save / :load / :snippets builtins, Tab against keywords + on-device dir() |
interactive(device) |
Passthrough TUI — mpremote-compatible keybindings (Ctrl-C / Ctrl-D / Ctrl-X / Ctrl-E), auto-reconnect through the configured serial-port factory, Ctrl-X quits without rebooting the device |
tail(device, seconds, *, fail_on_traceback=True) → ExitCode |
Stream serial output for a window, highlight tracebacks as they arrive, return one of the ExitCode enum values |
fetch_device_names(port) → list[str] | None |
Drive the friendly→raw→dir()→friendly round-trip in one call; the engine behind line-mode Tab completion. Useful if you're embedding completion in your own session shape. |
build_default_completer(*, port=None, cache=None) |
prompt_toolkit-shaped completer wrapping KeywordCompleter + (optionally, when port is given) DeviceCompleter. Caller-owned cache lets :rescan-style invalidation hook in. |
detect_patterns(text) / colorize(text) |
Streaming pattern detector + ANSI renderer for CP Traceback / safe mode / Hard fault, MP Traceback / MPY: soft reboot banners |
classify_session_failure(error) → ReplFailureKind |
Standalone classifier for building your own orchestrator on top of ReplSession |
recovery_plan_for(kind) → RecoveryPlan |
Canned headline + ordered fix-steps per failure kind |
CLI
chumicro-repl (or python -m chumicro_repl). Opens a serial REPL on a given port.
| Form | What it does |
|---|---|
chumicro-repl --address /dev/cu.usbmodem... |
Interactive REPL on the bare port (line mode by default) |
chumicro-repl --address ... --mode passthrough |
Byte-passthrough mode (mpremote-shape — for raw REPL framing / paste mode) |
chumicro-repl --address ... --tail SECONDS |
One-shot follow mode instead of interactive |
Line-mode :commands
Type : at the start of a line to invoke a builtin command. :help lists every command live in your session; the built-in six are:
| Command | What it does |
|---|---|
:edit |
Open $EDITOR with the recent input buffer pre-seeded; on save+exit, every non-empty line ships line-by-line. Falls back to vi when $EDITOR is unset. |
:save NAME |
Persist the last 10 input lines to ~/.chumicro-repl/snippets/NAME.py. |
:load NAME |
Replay a saved snippet line-by-line to the device. |
:snippets |
List saved snippet names. |
:rescan |
Drop the cached dir() so the next Tab re-queries the device. Use after import-ing a new module — the completer otherwise serves the snapshot it took on first Tab. |
:quit |
Exit without rebooting the device. Ctrl-D / Ctrl-C at the empty prompt do the same. |
History is persisted per-device under ~/.chumicro-repl/history/<sanitized-address>/history.txt so a session on back-porch doesn't pollute one on greenhouse. Up-arrow / Ctrl-R reverse search work normally.
Tab completion
Two sources merge:
- Keywords + builtins —
print,range,for,import,True, … Always works, no device round-trip. Covers most "what's that builtin called again" Tab presses. - On-device
dir()— populated on first Tab via a friendly-→raw-→dir()-→friendly round-trip (8–45 ms on tested CircuitPython and MicroPython boards; well below the perceptual "instant" threshold). Cached for the session;:rescaninvalidates after a newimport.
The round-trip's friendly-banner reprint is consumed by the fetcher's read-until->>> so it never leaks into the rendered output. See fetch_device_names() in chumicro_repl.completion if you're embedding the round-trip in your own session shape.
Where this fits
Leaf — no upstream ChuMicro deps (uses third-party pyserial and prompt_toolkit). Sister of chumicro-deploy; used by chumicro-workspace for deploy-and-tail flows.
Companion: chumicro-deploy
chumicro-deploy is the sister workbench tool for pushing code onto a board, probing identity, and flashing firmware. chumicro-repl is narrower — it opens a serial REPL given a port path — so the two compose cleanly: Deployer.deploy(source) writes the payload, then tail(device, seconds=10) (or any of the API entry points) follows the board for first-cycle output.
Examples
| Example | What it shows |
|---|---|
tail_after_deploy.py |
Programmatic deploy → tail with traceback fail-fast |
demo_repl_robustness.py |
Walks the interactive TUI through unplug / replug / Ctrl-C scenarios — manual demo of the auto-reconnect + retry behavior |
Contributing
Working on chumicro-repl itself? Clone the mono-repo if you haven't already — the rest of the workflow assumes you're inside that workspace.
pip install -e .[test]
pytest tests/ # host-side tests
pytest functional_tests/ # on-device tests (needs a board registered in devices.yml)
Register a board before running functional tests: chumicro-workspace add-device <id> --address <port>.
Docs
📖 Stable docs · Experimental docs
Find this library
- PyPI: chumicro-repl
- Source: workbench/repl
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chumicro_repl-0.4.2.tar.gz.
File metadata
- Download URL: chumicro_repl-0.4.2.tar.gz
- Upload date:
- Size: 53.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41bd60f98f24c2e726c2833efadbc10182801426f9c428a1bb6d53324569bae6
|
|
| MD5 |
ae324fee723a7361d054b3c5b703d8a6
|
|
| BLAKE2b-256 |
9ea000302c63d1314b23e2c865b362b8ee430a970e47aff9de4f71185f309e13
|
Provenance
The following attestation bundles were made for chumicro_repl-0.4.2.tar.gz:
Publisher:
promote.yml on ChuMicro/ChuMicro
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chumicro_repl-0.4.2.tar.gz -
Subject digest:
41bd60f98f24c2e726c2833efadbc10182801426f9c428a1bb6d53324569bae6 - Sigstore transparency entry: 2200853134
- Sigstore integration time:
-
Permalink:
ChuMicro/ChuMicro@f0371ee3184710a808c548acf3b1a9391dcf072e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ChuMicro
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
promote.yml@f0371ee3184710a808c548acf3b1a9391dcf072e -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chumicro_repl-0.4.2-py3-none-any.whl.
File metadata
- Download URL: chumicro_repl-0.4.2-py3-none-any.whl
- Upload date:
- Size: 62.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c1ae5758b5986848482a471b98eb52fb09bf8fb2d4bd2132a0aa6708332a7de
|
|
| MD5 |
d512d7c9d997b177439945aaaf65cd03
|
|
| BLAKE2b-256 |
d78c8e11240a4316424066aec2c09bc9019f8e438363e9686d5ee41492e51bda
|
Provenance
The following attestation bundles were made for chumicro_repl-0.4.2-py3-none-any.whl:
Publisher:
promote.yml on ChuMicro/ChuMicro
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chumicro_repl-0.4.2-py3-none-any.whl -
Subject digest:
8c1ae5758b5986848482a471b98eb52fb09bf8fb2d4bd2132a0aa6708332a7de - Sigstore transparency entry: 2200853171
- Sigstore integration time:
-
Permalink:
ChuMicro/ChuMicro@f0371ee3184710a808c548acf3b1a9391dcf072e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ChuMicro
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
promote.yml@f0371ee3184710a808c548acf3b1a9391dcf072e -
Trigger Event:
workflow_dispatch
-
Statement type: