This release is a pre-release and may not be stable for production use.
wrapture-instrumentation-postgresql
Instrumentation for the PostgreSQL client libraries, applied through wrapture.
wrapture attaches bindings to arbitrary Python call sites without
modifying the code being observed, and its config layer can switch on
packaged instrumentation for a third-party package by name. This is
the PostgreSQL package in that collection: one wrapture.Instrumentation
class per client library, so tracing every query, connection and
transaction your application sends to PostgreSQL is one config entry
and no code.
Status: alpha, ahead of 1.0.0. Developed against wrapture's alpha series, with pre-releases published to PyPI, and until 1.0.0 is final a plain
pip install wrapture-instrumentation-postgresqlpicks up the latest pre-release automatically, so there is no need to pin a specific version.
Why a separate package
The core wrapture-instrumentation package deliberately covers only the standard library and third-party packages that can be exercised in-process, with no separate backend product or service needed to test against. A PostgreSQL driver is exactly the kind of target the separate-package rule was drawn for: its tests need a real server, so this package's suite runs one in a docker container, and it carries the drivers as test dependencies (some of them compiled wheels) and its own release cadence, so the core package's test matrix stays light. One package covers every client library for the one backend: psycopg, psycopg2 and asyncpg.
Installation
$ pip install wrapture-instrumentation-postgresql
Installing it brings wrapture and nothing else. No driver is a dependency: each instrumentation is inert until its driver is present, and wrapture checks the installed version against the range the instrumentation supports at apply time.
Using it
An [[instrument]] entry in wrapture.toml names the target:
[[instrument]]
name = "psycopg"
[[sink]]
type = "printer"
and the runner applies it before the application starts, so the patch is in place before the driver is imported:
$ python -m wrapture -m myapp
The same config works through
autowrapt injection
(AUTOWRAPT_BOOTSTRAP=wrapture python myapp.py); through
manual setup,
a few lines in the application's own startup where wrapping the launch
from outside is awkward; and, in a test, through
wrapture.instrumentation("psycopg") scoping the instrumentation to
a block. The
ad-hoc tracing guide
covers the config file itself.
To see what is installed, what it supports in the current environment, and what settings it takes:
$ python -m wrapture.tools instrumentation --verbose
Provided instrumentation
| Target | Supported versions | Records | Settings |
|---|---|---|---|
psycopg |
psycopg 3.1+ (3.x) | Every query as one database leaf, however it was issued (a cursor's execute or executemany, the connection's shortcut, a streamed query, a COPY, a server-side cursor's DECLARE), plus the connection being opened and each transaction boundary (commit, rollback, the connection's context manager, and a transaction() block's begin and end, savepoints included); sync and async classes alike, and connections from a pool. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text is recorded only with the statement setting on, bound parameters never. |
statement |
psycopg2 |
psycopg2 2.9+ (2.x), psycopg2-binary alike | Every query as one database leaf, however it was issued (execute, executemany, callproc, the extras' batch helpers, a named cursor's DECLARE), each COPY (copy_from, copy_to, copy_expert), the connection being opened and each transaction boundary (commit, rollback, the connection's context manager); through recording subclasses injected by psycopg2's own factory mechanism, so your cursor_factory and connection_factory classes keep working and are recorded too. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text (the template with its placeholders) is recorded only with the statement setting on, bound parameters never. |
statement |
asyncpg |
asyncpg 0.29+ (0.x) | Every query as one database leaf recorded around its await, however it was issued (a connection's execute, executemany, fetch, fetchrow, fetchval or fetchmany, a prepared statement's own fetches, a server-side cursor's DECLARE and each FETCH), each COPY, the connection being opened, and each transaction boundary, which asyncpg issues through execute. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text (with its $n placeholders) is recorded only with the statement setting on, query arguments never. A connection taken from a pool records its queries like any other. |
statement |
The entry point name is the config's name""; the linked per-target
README is the full user documentation: what records, what the events
carry, the setting, and what is deliberately not traced.
What is not traced
By design, and where it goes:
-
Fetching rows: a query event closes when its execute returns, so time spent iterating rows afterwards is the application's, and a server-side cursor's FETCHes are not recorded (its DECLARE is).
-
Pool checkouts (
psycopg_pool): a connection taken from a pool records its queries like any other, but taking and returning it are not database operations and are not recorded. -
LISTEN/NOTIFY, large objects and two-phase commit are out of scope.
Adding a target
Each client library is its own subpackage and entry point here. The
subpackage's __init__.py holds one wrapture.Instrumentation
subclass and imports only wrapture (and the package's own common.py,
which imports only wrapture too); everything that touches the driver
lives in sibling modules imported inside the hook. The class is
registered in pyproject.toml under
[project.entry-points."wrapture.instrumentation"], and gets its own
test suite under tests/<target>/ and a README.md linked from the
table above. The
instrumentation packages
page of the wrapture documentation is the full contract; TESTING.md
here covers the tests and the server they run against.
License
BSD 2-Clause. See LICENSE.
Release files for wrapture-instrumentation-postgresql 1.0.0.dev2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| wrapture_instrumentation_postgresql-1.0.0.dev2.tar.gz | 64.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wrapture_instrumentation_postgresql-1.0.0.dev2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 100.7 kB
Release files / wrapture_instrumentation_postgresql-1.0.0.dev2.tar.gz
| Download URL | wrapture_instrumentation_postgresql-1.0.0.dev2.tar.gz |
|---|---|
| Size | 64.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c443ae48dd3223446e078c483482c5001bdc8a085038793a25c7fdebef1dc684
|
|
BLAKE2b-256 checksum How to use checksums |
1896bad1f2ff75d84aadc58803d2d24ba179a91a734432e1ba501cbe68b6d50c
|
| 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 Sep 4, 2026.
Transparency logRelease files / wrapture_instrumentation_postgresql-1.0.0.dev2-py3-none-any.whl
| Download URL | wrapture_instrumentation_postgresql-1.0.0.dev2-py3-none-any.whl |
|---|---|
| Size | 36.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
35be16b9cf9600f321d59ccaf4daeb378f7cb97b8720c3625f62de1bc1fecf4b
|
|
BLAKE2b-256 checksum How to use checksums |
620e820d8a6d5a20ec396615dd2a48cb5eb0105271f17a886510d51c68d7bdfa
|
| 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 Sep 4, 2026.
Transparency log