wrapture Unifies Python Mocking and Tracing in One Primitive

September 1, 2026news
PythonObservabilityOpen Weights

Graham Dumpleton — the engineer behind wrapt, mod_wsgi, and New Relic's Python agent — released wrapture on 31 August 2026, extending the monkeypatching concepts from wrapt into a library that handles both testing stubs and live tracing in the same instrumentation pass. For teams building multi-step AI pipelines where observability and deterministic test control over third-party calls are equally non-negotiable, that combination matters. As pipeline architecture rather than model upgrades drives most 2026 AI gains, tooling that makes complex call graphs inspectable without modifying the code under observation becomes load-bearing infrastructure.

What wrapture does

The library lets a developer wrap any function or method to either record every invocation transparently or override what it returns — without touching the target's source. Dumpleton frames the core problem directly: attaching observation to code you don't control, capturing what flows through it, and doing so without disturbing the running program. wrapture is simultaneously a unittest.mock alternative and a production tracing layer. Most instrumentation tools choose one role; wrapture treats them as two surfaces of the same primitive.

The OpenTelemetry integration extends this into production observability. Beyond the Python API, wrapture ships a configuration-based mechanism that can add tracing to an existing project with no code changes at all:

capture = "summary"

[[observe]]
target = "domain:Calculator"
name = ["outer", "inner"]

[[sink]]
type = "jsonlines"
path = "trace.jsonl"

That jsonlines sink writes a structured trace file — a record of exactly what entered and exited observed call sites, directly useful for debugging non-deterministic agent behaviour without inserting print statements or restructuring production code.

Testing patterns: stubs and result transforms

A follow-up post, Unit testing with wrapture, shows two patterns that illustrate the library's dual character. The first is a straightforward stub: wrapture.binding(Gateway, "charge").on_call.returns({"id": "stub", "amount": 0}) replaces the real Gateway.charge for the duration of a with block, so any call to OrderService().place(500) that internally invokes Gateway().charge() receives the stub dict instead.

The second pattern is more useful for AI pipeline work: transforms_result intercepts the real return value and rewrites it before the caller sees it. In the example, charge.on_call.transforms_result(lambda r: {**r, "id": "ch_TEST"}) lets the actual charge execute while pinning the id field to a test sentinel. For agent workflows that call external tools or LLM endpoints, being able to let a call execute while deterministically altering one field in its response is substantially more surgical than replacing the entire call with a mock.

Capability unittest.mock wrapture
Stub entire return value Yes Yes — via on_call.returns()
Intercept and transform real return value Requires manual side_effect wiring Yes — via on_call.transforms_result()
Production tracing without code changes No Yes — TOML config + jsonlines sink
OpenTelemetry integration No Yes
Non-invasive (no target source modification) Partial — requires import patching setup Yes — core design constraint

Agent-driven development, done carefully

Dumpleton's disclosure about the project's development process is worth examining on its own terms. Every line of code and documentation in wrapture was written by an AI assistant under his direction. He draws a deliberate line between that and what he calls vibe coding — a one-shot prompt producing code that the operator can't evaluate because they lack domain knowledge. His position is that his decades in Python's instrumentation corner meant he knew precisely what the output needed to be; the AI was a production mechanism, not a design oracle. The distinction maps onto the same dynamic that shapes agentic work in data science contexts: expert-directed agents produce qualitatively different results than unsupervised generation because the human constraint surface remains tight throughout.

The project is, by Dumpleton's own description, just a few weeks old as of the announcement date. That youth means the API surface will move and edge cases remain undocumented. The architecture — monkeypatching primitives unified across testing and tracing, with a configuration path requiring zero source changes — is coherent enough that wrapture is a serious addition to the Python observability toolkit. For teams whose agent pipelines call into libraries they don't own and need both repeatable test coverage and production visibility at those call boundaries, the dual-mode design addresses a gap no existing single tool covers cleanly.

Related Reading