6 posts tagged “graham-dumpleton”
2026
Graham Dumpleton's new monkey patching package wrapture is shaping up to be an indispensable tool for Python developers. I'm not sure why I've seen so little buzz about it!
Graham has been posting new tutorials for it almost daily since the initial release on August 31st. Here's everything he's published so far:
- Introducing wrapture - a new monkey patching library that serves both testing and observability (think New Relic style tracing) at the same time.
- Unit testing with wrapture - how to use it for the same kinds of thing as
unittest.mock. - Recording calls with wrapture - recording method calls as timelines and processing and displaying them as trees.
- Phased behaviour in wrapture - arranging patched methods to change behavior across multiple calls.
- Beyond callables in wrapture - monkey patching attributes, dictionaries, generators.
- Live tracing with wrapture - tracing a live application to see exactly how it works.
- Zero-code tracing with wrapture - configuring tracing in a separate TOML file without modifying Python code at all.
- Tracing Flask with wrapture - using the separate wrapture-instrumenation package to instrument a Flask application. That package also provides instrumentation for
aiohttp.client,aiohttp.web,django,fastapi,flask,grpc,http.client,httpx,jinja2,requests,sqlalchemy,sqlite3,starlette,urllib.request,urllib3,uvicorn,werkzeug.serving,wsgiref.simple_server,xmlrpc.client,xmlrpc.server. - Finding slow code with wrapture - wrapture's tools for recording timing information, both individually and aggregated across multiple calls.
- OpenTelemetry export in wrapture - exporting traces to OpenTelemetry.
Graham also has a set of interactive workshops for wrapture, implemented as JupyterLab notebooks.
Wrapture is still alpha software but it's already very usable - especially given you can configure and try it out with a TOML file without modifying any Python code at all.
This feels like one of those Swiss Army Knife packages that, once mastered, will provide value against all sorts of problems for years to come.
Introducing wrapture. New from Graham Dumpleton (of wrapt, mod_wsgi, and New Relic's Python agent fame), who describes Wrapture as taking the monkeypatching ideas from wrapt and extending them to apply to testing and tracing at the same time.
Wrapture (full documentation here) makes it easy to wrap any function or method such that all access can be traced, or can be overridden to return a different value.
It acts as both an alternative to unittest.mock and a way to implement tracing against an existing project:
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.
Wrapture includes OpenTelemetry support and even has an entirely configuration-based mechanism for adding tracing to an existing Python project, which looks like this:
capture = "summary"
[[observe]]
target = "domain:Calculator"
name = ["outer", "inner"]
[[sink]]
type = "jsonlines"
path = "trace.jsonl"This is still a very young project - just a few weeks old - but it's off to a very promising start.
Interestingly, this is also Graham's first attempt at large entirely agent-driven project:
Every line of code and documentation in wrapture was written by an AI assistant working under my direction. I want to be upfront about that, and equally upfront about what it was not. This was not vibe coding, where a one-shot prompt produces a pile of generated code and the person driving hopes for the best because they lack the knowledge to judge what came back. Vibe coding has earned its bad reputation. I engineered wrapture carefully from the start. I have spent a long time in this particular corner of Python and knew exactly what the result needed to be, and the AI was the means of producing it rather than the source of the design.
In a follow-up post, Unit testing with wrapture, Graham shows the testing patterns supported by the new library:
def test_stub_with_wrapture(): with wrapture.binding( Gateway, "charge" ).on_call.returns({ "id": "stub", "amount": 0} ): assert OrderService().place( 500 )["id"] == "stub"
And this neat example of a test that calls and then modifies the return value from the original method:
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 of these examples the OrderService().place(...) method calls Gateway().charge(...).)
2009
Future roadmap for mod_wsgi. mod_wsgi 3.0 isn’t too far off, and will include Python 3.0 support, WSGI application preloading and internal web server redirection (similar to nginx X-Accel-Redirect). Version 4.0 plans a major architectural change that will allow multiple versions of Python to be run from the same Apache.
Load spikes and excessive memory usage in mod_python. “The final answer? Stop using mod_python, use mod_wsgi and run it with daemon mode instead. You will save yourself a lot of headaches by doing so.”
2008
Setup mod_wsgi for Django and Shared Hosting. Tutorial by David Cramer; attached are useful comments from mod_wsgi author Graham Dumpleton.
2007
Web hosting landscape and mod_wsgi. Graham Dumpleton explains how mod_wsgi’s daemon mode should provide secure Python deployment for commodity hosting providers.