Skip to main content

faultlib

faultlib is the Python interface to the Rust fault network fault-injection engine. It runs TCP and UDP proxies inside an asyncio application, applies ordered fault chains, and exposes typed progress, status, TCP-stream, and UDP-exchange records.

Use it when network degradation is one part of a larger Python experiment—for example, adding database latency while restarting a pod and observing service recovery. For shell-driven experiments, use the fault CLI.

Python is a thin binding: validation, phase lifecycle, scheduling decisions, events, and errors remain canonical Rust behavior. The package adds typed Python mappings and dataclasses, not a second fault model.

Requirements and installation

faultlib requires Python 3.14 or newer.

python -m pip install faultlib

Start a proxy

import asyncio

from faultlib import Engine, Run


RUN: Run = {
    "schema_version": 1,
    "name": "slow database",
    "proxies": [
        {
            "name": "database",
            "protocol": "tcp",
            "listen": "127.0.0.1:15432",
            "upstream": "database.internal:5432",
        }
    ],
    "phases": [
        {
            "name": "degraded for thirty seconds",
            "duration": "30s",
            "proxies": [
                {
                    "proxy": "database",
                    "faults": [
                        {
                            "type": "latency",
                            "flow": "both",
                            "distribution": {
                                "type": "normal",
                                "mean_ms": 200.0,
                                "stddev_ms": 20.0,
                            },
                        }
                    ],
                }
            ],
        }
    ],
}


async def main() -> None:
    async with Engine(RUN) as engine:
        print(f"proxy listening on {engine.endpoints.tcp[0]}")
        result = await engine.run()

    print(f"run outcome: {result.outcome.kind}")


asyncio.run(main())

Point the application at 127.0.0.1:15432 for the duration of the experiment. The proxy forwards the connection to database.internal:5432; no database protocol support is required.

Run and its nested TypedDict types give type checkers the same shape as the published schema. Runtime results and events are frozen dataclasses rather than unstructured dictionaries.

Observe traffic

Engine.next_event() returns a completed transport record when one is available and otherwise publishes periodic status:

from faultlib import StatusEvent, TcpStreamEvent, UdpExchangeEvent


async def observe(engine: Engine) -> None:
    while engine.alive():
        match event := await engine.next_event():
            case StatusEvent(status):
                print(
                    f"active={status.tcp.active} "
                    f"impacted={status.tcp.impacted}"
                )
            case TcpStreamEvent(stream):
                print(stream.stream_id, stream.outcome)
            case UdpExchangeEvent(exchange):
                print(exchange.exchange_id, exchange.outcome)
            case None:
                return

Record delivery is bounded and best effort. A slow Python consumer never stalls the Rust proxy. Aggregate status remains complete and reports omitted records through dropped_records.

Adapt a running experiment

engine.schedule() exposes Rust-owned phase controls to Python. You can add, modify, delete, start, or stop future phases while ordinary Python tasks coordinate the surrounding system. A phase becomes immutable once it starts; invalid mutations raise PhaseStateError.

The complete example in the repository demonstrates engine events, adaptive scheduling, and bounded record retention: examples/python_proxy.py.

Supported behavior

  • TCP: latency, jitter, bandwidth, blackhole, connection reset
  • UDP: latency, jitter, directional blackhole
  • DNS over UDP: delay, timeout, truncation, refusal, SERVFAIL, NXDOMAIN, empty answers, and random A records

See the guide for realistic failure scenarios and the generated field reference for the exact wire contract.

Local development

From a checkout of the repository:

uv sync --project fault-python --python 3.14 --reinstall-package faultlib
uv run --project fault-python --python 3.14 python examples/python_proxy.py
uv run --project fault-python --python 3.14 ruff check \
  fault-python/python examples

Repeat uv sync --reinstall-package faultlib after changing Rust binding code.

Licensed under the Apache License 2.0.

Metadata

Release files for faultlib 1.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 faultlib 1.1.0
File Size Uploaded
faultlib-1.1.0.tar.gz 68.3 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for faultlib 1.1.0
File Interpreter ABI Platform
faultlib-1.1.0-cp314-abi3-win_amd64.whl CPython 3.14 abi3 Windows x86-64 Details
faultlib-1.1.0-cp314-abi3-manylinux_2_34_x86_64.whl CPython 3.14 abi3 Linux glibc 2.34+ x86-64 Details
faultlib-1.1.0-cp314-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl CPython 3.14 abi3 macOS 10.12+ universal2 (ARM64, x86-64), macOS 10.12+ x86-64, macOS 11.0+ ARM64 Details

Total release size: 2.9 MB

Release files / faultlib-1.1.0.tar.gz

Download URL faultlib-1.1.0.tar.gz
Size 68.3 kB
Tags Source
SHA-256 checksum
How to use checksums
1313cc320be27b79f3f4833c89b9e9b1fbd826469876e75b4a4eecfcbb9263d2
BLAKE2b-256 checksum
How to use checksums
ad4b97b04ba913ac1368745ed8b5b96238bd5a4e88e4d3a749f576bf175a3cb3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 6, 2026.

Transparency log

Release files / faultlib-1.1.0-cp314-abi3-win_amd64.whl

Download URL faultlib-1.1.0-cp314-abi3-win_amd64.whl
Size 613.3 kB
Tags CPython 3.14 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
cb671ef62e8819ec5080d72f08c753da0ab35e3c344a2f7c21f04ccdf9fd198a
BLAKE2b-256 checksum
How to use checksums
0ca74d617904c36d2171e3d2863d9fd8e385917e975ecd2ec31edae14b80f872
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 6, 2026.

Transparency log

Release files / faultlib-1.1.0-cp314-abi3-manylinux_2_34_x86_64.whl

Download URL faultlib-1.1.0-cp314-abi3-manylinux_2_34_x86_64.whl
Size 805.6 kB
Tags CPython 3.14 Linux glibc 2.34+ x86-64 abi3
SHA-256 checksum
How to use checksums
2ba81e04dc574b663a4273ee40ecac2fc3447b612d469e83fcc1aeec9dc7b703
BLAKE2b-256 checksum
How to use checksums
67358e1b7874dbf955d477c90a5ebf75047773f3ba37bfdd912848c342b5e3b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 6, 2026.

Transparency log

Release files / faultlib-1.1.0-cp314-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl

Download URL faultlib-1.1.0-cp314-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Size 1.4 MB
Tags CPython 3.14 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
3e60437dfb96114ca774ce3206002fbc0506c0d00adc4df17afbe10dbdc4f730
BLAKE2b-256 checksum
How to use checksums
fb99507dbed28f69d3b78fa2126240c06246f6f9c6d7e2fff168e74487f8c775
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 6, 2026.

Transparency log

Release history Release notifications | RSS feed

1.2.1

4 release files

1.2.0

4 release files

This release

1.1.0 This release

4 release files

1.0.0

4 release files

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