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.
Four surfaces, two of them interactive. Line mode is a host-side line editor with persistent per-device history, $EDITOR handoff (:edit), saved snippets (:save / :load / :snippets), and Tab completion against Python keywords plus the board's own namespace. Passthrough mode forwards every keystroke to the board with mpremote-compatible keybindings (Ctrl-C / Ctrl-D / Ctrl-X / Ctrl-E), which is what you want for raw-REPL framing and paste-mode flows. The other two surfaces are for scripts: tail() follows a board for a fixed window and stops on a traceback, and ReplSession runs code on the board and hands back stdout. Every surface decodes UTF-8 safely across chunk boundaries and highlights tracebacks as they scroll past. A pluggable session-failure classifier lets you build your own orchestrator on top.
Part of the ChuMicro family, small focused Python libraries for microcontrollers and laptops. Browse all workbench tools. This is a workbench tool: it runs on your laptop, not on the board.
Install
pip install chumicro-repl
pyserial and prompt_toolkit come along as dependencies. There is no board-side install; chumicro-repl talks to the CircuitPython or MicroPython runtime already on the board over USB serial. Native Windows isn't currently supported (the passthrough 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
On a terminal that drops you into line mode. Type for index in r<Tab> and Tab completes range. Up-arrow recalls history from earlier sessions on the same board. :edit opens $EDITOR with the recent buffer pre-seeded, so a multi-line block isn'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.
Run something on the board from a script 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 and 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(device) |
Wraps ReplSession with classify + retry + coaching for session-start failures (mirrors the chumicro_deploy.RecoveringDeployer shape) |
interactive_line(device) |
Opens line mode: host-side line editor, persistent per-device history, :edit / :save / :load / :snippets builtins, Tab against keywords plus on-device dir() |
interactive(device) |
Opens passthrough mode: 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, and useful if you're embedding completion in your own session shape. |
build_default_completer(*, port=None, cache=None) |
prompt_toolkit-shaped completer wrapping KeywordCompleter plus (when port is given) DeviceCompleter. A caller-owned cache lets :rescan-style invalidation hook in. |
BUILTIN_COMMANDS / LineModeContext / CompletionCache |
The line-mode command table, the state a command handler receives, and the namespace cache. Register your own :command by passing an extended table. |
detect_patterns(text) / colorize(text) |
Streaming pattern detector plus ANSI renderer for CircuitPython Traceback / safe mode / Hard fault and MicroPython 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 plus 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 on a terminal) |
chumicro-repl --address ... --mode passthrough |
Byte-passthrough mode, for raw-REPL framing and paste mode |
chumicro-repl --address ... --tail SECONDS |
One-shot follow mode instead of interactive |
--mode takes auto, line, or passthrough. The default, auto, picks line mode on a terminal and passthrough when stdin is piped, since line mode needs interactive input.
Line-mode :commands
Type : at the start of a line to invoke a builtin command. :help lists every command live in your session; the seven builtins are:
| Command | What it does |
|---|---|
:help |
List every registered command. |
:edit |
Open $EDITOR with the recent input buffer pre-seeded. On save and 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 it after import-ing a new module, since 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 and Ctrl-R reverse search work normally.
Tab completion
Two sources merge:
- Keywords and builtins:
print,range,for,import,True, and the rest. 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. Cached for the session;:rescaninvalidates it 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
No upstream ChuMicro dependencies; the third-party pyserial and prompt_toolkit do the transport and the line editing. Sister of chumicro-deploy, and 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, opening a serial REPL given a port path, so the two compose cleanly: Deployer(device).deploy_diff(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 passthrough TUI through unplug / replug / Ctrl-C scenarios. A manual demo of the auto-reconnect and retry behavior. |
Contributing
Issues, bug reports, and pull requests are welcome, and so is "I ran it on this board and here's what happened", some of the most useful feedback a hardware project can get. Development happens in the ChuMicro repository, whose contributing guide covers setup and the test workflow.
Docs
📖 Stable docs · Experimental docs
Find this library
- PyPI: chumicro-repl
- Source: workbench/repl
License
Metadata
Release files for chumicro-repl 0.4.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| chumicro_repl-0.4.3.tar.gz | 53.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| chumicro_repl-0.4.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 116.2 kB
Release files / chumicro_repl-0.4.3.tar.gz
| Download URL | chumicro_repl-0.4.3.tar.gz |
|---|---|
| Size | 53.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2c07d379307d388587d5a48a5eec5d0d4d122e3255167943ce030847d0e90f84
|
|
BLAKE2b-256 checksum How to use checksums |
63ec794be58ed1ff0c2b8201d8ec7880785318de390de4611758749b2b3ce2d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 Aug 7, 2026.
Transparency logRelease files / chumicro_repl-0.4.3-py3-none-any.whl
| Download URL | chumicro_repl-0.4.3-py3-none-any.whl |
|---|---|
| Size | 62.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c884d26bb1cc12b76deb1f7e8ad06591362cb8b557304aac39dcafb3f62746ac
|
|
BLAKE2b-256 checksum How to use checksums |
c86e3a890c141488dc10e1562b65617e5ceb78c2c67d0b4eb9df021a2e864d55
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 Aug 7, 2026.
Transparency log