Skip to main content

Outwrite

Keep your logs readable and your progress visible.

outwrite combines Python's standard logging with a live status line that updates in place while logs stay readable, including messages from multiple processes or threads. The status is plain text you control, so it fits naturally into existing CLI workflows.

[10/30/26 12:00:00] INFO     Starting                        app.py:10
[10/30/26 12:00:02] INFO     Configuration check passed      app.py:14
Running connection check

Status is text you provide, not an automatically calculated progress bar.

Built on Rich. Python 3.11+.

Install

pip install outwrite

Quick start

import logging
import time

import outwrite

logger = logging.getLogger("my_app")

with outwrite.configure_console(logger=logger):
    logger.info("Starting")

    for check in ("Configuration", "Connection", "Permissions"):
        outwrite.status.update(f"Running {check.lower()} check")
        time.sleep(0.5)  # Simulate each check.
        logger.info("%s check passed", check)

    logger.info("Done")

When the with block ends, outwrite finishes printing pending messages and removes the status line. Existing file handlers still receive logs, but not status.

Multiple processes

Pass the connection returned by the main process to each child process and call outwrite.configure_console(console_connection) there before logging or updating status.

The multiprocessing demo shows the complete setup, including cleanup when interrupted with Ctrl+C.

After installing outwrite, run it from a repository checkout:

python examples/multiprocessing_demo.py
  • Use the same logger name and multiprocessing context in the main process and workers.
  • Join workers before leaving the with block so their final messages arrive.
  • Workers share one status line; the last update received is shown.

Threads need no extra setup.

Options

Pass these options to outwrite.configure_console(...):

Option Default What it does
console_connection None Pass the main process's connection when setting up a worker. Leave unset in the main process.
logger None The Python logger to use. If omitted, uses the logger named "outwrite". The root logger is not supported.
console_level logging.INFO Minimum log level shown by the default console handler. Accepts integer logging levels, including custom levels. Existing handlers keep their own levels.
show_status True Whether to show the status line. Does not affect logs.
mp_context None Multiprocessing context used to create the shared queue. Defaults to spawn. Use the same context to create your workers.
console_handler None Your own RichHandler for console logs. Its console, formatting, and level replace the defaults.
render_status None Function that takes (text, console) and returns something Rich can display. The default is cyan text that fits on one line.

In workers, pass only console_connection. The other options configure the main process; they are ignored when a connection is supplied.

Call What it does
outwrite.status.clear() Remove the current text. The next update can show it again.
outwrite.status.disable() Hide status and ignore later updates until the with block ends. Call this in the main process only.

By default, output goes to stderr. When that stream is redirected to a file or pipe, logs are still written, but the live status line is hidden.

Change how it looks

This example hides the time and source filename in logs and makes status green:

import logging
import time

import outwrite
from rich.console import Console
from rich.logging import RichHandler
from rich.text import Text

logger = logging.getLogger("my_app")
handler = RichHandler(show_time=False, show_path=False, level=logging.INFO)


def render_status(text: str, console: Console) -> Text:
    status_text = Text(text, style="green", no_wrap=True)
    status_text.truncate(max(1, console.width - 2), overflow="ellipsis")
    return status_text


with outwrite.configure_console(
    logger=logger, console_handler=handler, render_status=render_status
):
    logger.info("Starting")
    outwrite.status.update("Simulation: step 1 of 100")
    time.sleep(1)
    # Do your work here.

A supplied handler controls the console and log level; console_level does not override it. Status uses the same console. outwrite reuses your handler without adding it twice or closing it afterward.

License

MIT.

Metadata

Release files for outwrite 0.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 outwrite 0.1.0
File Size Uploaded Provenance Actions
outwrite-0.1.0.tar.gz 11.2 kB With provenance Details for outwrite-0.1.0.tar.gz

Built distribution (wheel)

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

Total release size: 19.6 kB

Release files / outwrite-0.1.0.tar.gz

Download URL outwrite-0.1.0.tar.gz
Size 11.2 kB
Tags Source
SHA-256 checksum
How to use checksums
f1d9ff2a48f484d8665d3261424f4801b25e48f24bbf2259f01f1e7b3081931f
BLAKE2b-256 checksum
How to use checksums
54fad25a96beda5727d719509599b97c17212c9b0d54f19821e17086435b88ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Oct 30, 2026.

Transparency log

Release files / outwrite-0.1.0-py3-none-any.whl

Download URL outwrite-0.1.0-py3-none-any.whl
Size 8.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
735954250568cdf59c0d492d68fe6abc59b7a96cbd9cd1d6682489a395ef3e91
BLAKE2b-256 checksum
How to use checksums
046e1b6ba636d7bd0bd494668b820b93eb2289b57eaee8d545f9fcd249b29f40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Oct 30, 2026.

Transparency log

Security for outwrite 0.1.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for outwrite-0.1.0.tar.gz

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 Oct 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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