Graham Dumpleton — known for wrapt, mod_wsgi and work on New Relic's Python agent — has published a new tool called wrapture. The library extends the monkeypatching concepts from wrapt, allowing any function or method to be wrapped so that accesses can be traced or the return value can be overridden.
What does wrapture do?
- It can serve as an alternative to unittest.mock by letting tests intervene in a function's or method's behavior.
- It can also be used to attach observation and tracing to existing projects: you can observe code you do not control, record what flows through it, and do so without disturbing the running program.
Dumpleton writes: “Attaching observation to code you do not control, recording what flows through it, and doing so without disturbing the program being watched, is a problem I have never really stopped thinking about.”
OpenTelemetry and configuration-driven tracing
wrapture includes OpenTelemetry support and provides a fully configuration-based mechanism to add tracing to an existing Python project. An example configuration from the documentation looks like this:
capture = "summary"
[[observe]]
target = "domain:Calculator"
name = ["outer","inner"]
[[sink]]
type = "jsonlines"
path = "trace.jsonl"
Project status and the role of an AI assistant
The project is very young — only a few weeks old — but has a promising start. Notably, Dumpleton says every line of code and documentation in wrapture was written by an AI assistant under his direction. He emphasizes this was not casual "vibe coding" where a one-shot prompt produces code without sufficient review; instead, he says he engineered wrapture deliberately, using the AI as a means of producing the implementation while keeping the design and oversight himself.
Testing patterns with wrapture
In a follow-up post titled "Unit testing with wrapture", Dumpleton shows how the library can be used in tests. Example usages from the post:
A simple stub return in a test:
def test_stub_with_wrapture():
with wrapture.binding(Gateway, "charge").on_call.returns({"id": "stub", "amount": 0}):
assert OrderService().place(500)["id"] == "stub"
A test that calls the original method and then transforms its result:
def test_pinned_result_with_wrapture():
charge = wrapture.binding(Gateway, "charge")
charge.on_call.transforms_result(lambda r: {**r, "id": "ch_TEST"})
with charge:
assert OrderService().place(500) == {"id": "ch_TEST", "amount": 500}
(In both examples OrderService().place(...) calls Gateway().charge(...).)
Why this matters
By combining monkeypatching-style runtime interception with tracing capabilities and configuration-driven observability, wrapture aims to simplify both testing and runtime monitoring of Python applications. Its early release and the fact that code and docs were produced with AI assistance under human direction make it an interesting project to watch for teams working on testing and observability in Python.
Related context
Graham Dumpleton's previous work on wrapt and mod_wsgi and his contributions to observability tooling inform the goals behind wrapture; the documentation contains additional usage examples and details for those who want to try the library.



