<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/introducing-wrapture-ohj3cvcws" -->

---
title: Introducing wrapture | daily.dev
description: wrapture is a new Python package for monkey patching, unit testing, and tracing, built on top of wrapt. Rather than substituting fake objects like...
canonical: https://daily.dev/posts/introducing-wrapture-ohj3cvcws
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Introducing wrapture | daily.dev
og:description: wrapture is a new Python package for monkey patching, unit testing, and tracing, built on top of wrapt. Rather than substituting fake objects like...
og:url: https://daily.dev/posts/introducing-wrapture-ohj3cvcws
og:image: https://api.daily.dev/og/posts/ohJ3cvCWS.png
og:image:alt: Introducing wrapture
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Introducing wrapture

**[Planet Python](https://daily.dev/sources/planetpython)** · 15 min read · 1 upvotes · 1 comments

## Summary

wrapture is a new Python package for monkey patching, unit testing, and tracing, built on top of wrapt. Rather than substituting fake objects like unittest.mock, wrapture wraps real callables so the actual code runs while calls are observed, intervened on, or exported as OpenTelemetry spans. A single binding mechanism serves three purposes: ad-hoc monkey patching with a proper lifecycle, unit testing with call-graph assertions on real execution, and production-safe tracing via a wrapture.toml config with pluggable sinks (printer, JSON lines, OTLP export). The companion wrapture-instrumentation package ships pre-built bindings for Flask and Jinja2. Notably, every line of code and documentation was written by an AI assistant under the author's direction, following a carefully engineered process of design docs, layered implementation, and doctested documentation. wrapture is currently in alpha (eleventh pre-release), requires Python 3.12+ and wrapt 2.4.0+, and is installable via pip from PyPI.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://grahamdumpleton.me/posts/2026/08/introducing-wrapture>

## Questions this post answers

### What Python version and wrapt version does wrapture require?

Wrapture requires Python 3.12 or later and wrapt 2.4.0 or later. It is currently in alpha, distributed as pre-releases on PyPI, so a plain pip install wrapture picks up the latest pre-release without needing to pin a version. The API for its three core uses (patching, testing, tracing) is considered complete and stable going into 1.0.0.

_Developers evaluating new Python testing tools can track releases like this one on daily.dev._

### How does wrapture differ from unittest.mock for testing Python code?

Wrapture wraps the real callable instead of replacing it with a fabricated object, so the actual code still runs during a test. This lets a test assert on the real call graph, including nesting, normalized arguments, and actual return values, whereas unittest.mock records only a flat list of calls with no return values and no sense of what called what. Wrapture's stub() and mock() helpers are also strict, requiring a spec so nothing is invented on first touch.

_Developers weighing mocking strategies for Python test suites can compare approaches like this via daily.dev._

### Can wrapture trace a running Python application and export to OpenTelemetry without modifying the application code?

Yes, a wrapture.toml config file names the targets and a sink, and running the program with python -m wrapture or via the autowrapt bootstrap applies the instrumentation before the application code runs, with no code changes needed. With the wrapture[otel] extra installed, one [otel] table in the config sends the same events as OpenTelemetry spans, metrics, and correlated logs, propagating W3C trace ids across services.

_Teams adding observability to existing Python services without code changes can follow tracing tool updates on daily.dev._

## Community discussion

Top comments from developers on daily.dev.

**@leonidbugaev** · 0 upvotes

> unittest.mock's MagicMock answers every method and never runs the real body, so the object's calls to itself never happen. A green test there is agreement with the substitute. The obligation that only exists in the real callable (error propagation, nested self-calls, the actual return) cannot fail that test. Wrapping the real function and asserting the tape is a different kind of check: a wrong implementation can make it fail. Substituting it cannot.

## Similar posts on daily.dev

- [Trying out wrapture](https://daily.dev/posts/trying-out-wrapture-qi1ktjmcu) · Planet Python · 0 upvotes · 0 comments
- [Zero-code tracing with wrapture](https://daily.dev/posts/zero-code-tracing-with-wrapture-yy6qgb3me) · Planet Python · 1 upvotes · 0 comments
- [OpenTelemetry export in wrapture](https://daily.dev/posts/opentelemetry-export-in-wrapture-lojftqtkb) · Planet Python · 0 upvotes · 0 comments
- [Beyond callables in wrapture](https://daily.dev/posts/beyond-callables-in-wrapture-a41yd6lmi) · Planet Python · 0 upvotes · 0 comments
- [Tracing Flask with wrapture](https://daily.dev/posts/tracing-flask-with-wrapture-gfrmlfkfe) · Planet Python · 0 upvotes · 0 comments

---

Tags: [#python](https://daily.dev/tags/python), [#testing](https://daily.dev/tags/testing), [#ai-coding](https://daily.dev/tags/ai-coding), [#opentelemetry](https://daily.dev/tags/opentelemetry)

[View this post on daily.dev](https://daily.dev/posts/introducing-wrapture-ohj3cvcws)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Introducing wrapture","url":"https://daily.dev/posts/introducing-wrapture-ohj3cvcws","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/introducing-wrapture-ohj3cvcws"},"datePublished":"2026-08-31T01:49:23.687Z","dateModified":"2026-09-14T07:08:00.642Z","description":"wrapture is a new Python package for monkey patching, unit testing, and tracing, built on top of wrapt. Rather than substituting fake objects like...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/0bb8df1a9110bae29bdc82c29d6eb564?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/0bb8df1a9110bae29bdc82c29d6eb564?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Planet Python","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Planet Python","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/eac3cc584cb043b5a242d13752bd3d0c","url":"https://daily.dev/sources/planetpython"},"commentCount":1,"discussionUrl":"https://daily.dev/posts/introducing-wrapture-ohj3cvcws","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":1}],"keywords":"python,testing,ai-coding,opentelemetry","timeRequired":"PT15M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Planet Python","item":"https://daily.dev/sources/planetpython"},{"@type":"ListItem","position":3,"name":"Introducing wrapture"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/introducing-wrapture-ohj3cvcws","comment":[{"@type":"Comment","text":"unittest.mock’s MagicMock answers every method and never runs the real body, so the object’s calls to itself never happen. A green test there is agreement with the substitute. The obligation that only exists in the real callable (error propagation, nested self-calls, the actual return) cannot fail that test. Wrapping the real function and asserting the tape is a different kind of check: a wrong implementation can make it fail. Substituting it cannot.","datePublished":"2026-08-31T11:01:42.933Z","url":"https://daily.dev/posts/ohJ3cvCWS#c-2y3i9B6TE","author":{"@type":"Person","name":"Leonid Bugaev","url":"https://daily.dev/leonidbugaev","image":"https://lh3.googleusercontent.com/a/ACg8ocLhMgurwTmJElWaH9A8Ju8cHvZxgMCDt009jEYkmFCyUGAoaGSw=s96-c"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/introducing-wrapture-ohj3cvcws#faq","mainEntity":[{"@type":"Question","name":"What Python version and wrapt version does wrapture require?","acceptedAnswer":{"@type":"Answer","text":"Wrapture requires Python 3.12 or later and wrapt 2.4.0 or later. It is currently in alpha, distributed as pre-releases on PyPI, so a plain pip install wrapture picks up the latest pre-release without needing to pin a version. The API for its three core uses (patching, testing, tracing) is considered complete and stable going into 1.0.0. Developers evaluating new Python testing tools can track releases like this one on daily.dev."}},{"@type":"Question","name":"How does wrapture differ from unittest.mock for testing Python code?","acceptedAnswer":{"@type":"Answer","text":"Wrapture wraps the real callable instead of replacing it with a fabricated object, so the actual code still runs during a test. This lets a test assert on the real call graph, including nesting, normalized arguments, and actual return values, whereas unittest.mock records only a flat list of calls with no return values and no sense of what called what. Wrapture's stub() and mock() helpers are also strict, requiring a spec so nothing is invented on first touch. Developers weighing mocking strategies for Python test suites can compare approaches like this via daily.dev."}},{"@type":"Question","name":"Can wrapture trace a running Python application and export to OpenTelemetry without modifying the application code?","acceptedAnswer":{"@type":"Answer","text":"Yes, a wrapture.toml config file names the targets and a sink, and running the program with python -m wrapture or via the autowrapt bootstrap applies the instrumentation before the application code runs, with no code changes needed. With the wrapture[otel] extra installed, one [otel] table in the config sends the same events as OpenTelemetry spans, metrics, and correlated logs, propagating W3C trace ids across services. Teams adding observability to existing Python services without code changes can follow tracing tool updates on daily.dev."}}]}
```

