django-vpg
A Rust-powered PostgreSQL driver and Django database backend.
- A single connection pool used for both sync and async (asyncio) usage
- Very slightly better cpu/memory effeciency, especially with large INSERTs, when compared to psycopg
- Callable from Python or Rust with single connection pool
- Drop in compatibility
"ENGINE": "django_vpg.backend" - Supports django-async-backend for real asyncio usage
Build with tokio-postgres, deadpool, PyO3.
Status: Beta quality. Mostly feature complete. Report bugs. Use in production at your own risk.
Documentation: https://django-vpg.glitchtip.com
Part of the django-v* family — django-vcache, django-vtasks, django-vpg — small, fast, Rust-core Django infrastructure maintained by the GlitchTip team.
Why
- CPU and RSS. Protocol parsing, row decoding, and type marshalling run in Rust; only final Python values are materialized — intermediate protocol buffers and COPY encoding never traverse the Python heap. In the GlitchTip team's A/B benchmarks against psycopg (production-shaped ingest workloads, replayed locally), the driver holds resident memory flat under heavy-tailed payloads where libpq's buffers ratchet (2.5 vs 21 MB growth per 10k events), and wins per-op CPU on jsonb reads, pipelined batch inserts, and COPY event batches.
fetch_modelsfusion. Row → model-instance materialization can run as a single driver call instead of a per-row Python loop.- COPY at native speed.
COPY FROM STDINwith batch text-format encoding in Rust (encode_copy_chunk). - psycopg-shaped errors. Full PEP 249 exception hierarchy with
sqlstateandDiagnostics, so existing error-handling code ports cleanly. - Server-side cancellation. Cancelled queries fire a PostgreSQL
CancelRequeston a fresh connection and the pooled connection returns clean — no poisoned pool state, no abandoned server work. - Real pooling. deadpool checkout/return with warmup, wait timeouts,
and jittered max-lifetime recycling; prepared-statement cache with
psycopg3-style admission (
prepare_threshold/prepared_max), off by default like Django's postgresql backend — opt in withOPTIONS={"prepare_threshold": 5}, and leave it off behind a transaction-mode PgBouncer withoutmax_prepared_statements. - libpq-parity TLS.
sslmode(disable/allow/prefer/require/verify-ca/verify-full),sslrootcert, client certificates.
Install
pip install django-vpg # sync ORM + async driver API
pip install "django-vpg[async]" # + async ORM via django-async-backend
Requires Django >= 6.1 and Python >= 3.12.
Wheels cover Linux (manylinux + musllinux, x86_64 + aarch64, CPython 3.12-3.14). Other platforms install from the sdist, which needs a Rust toolchain at build time.
Note: psycopg (the library) must be installed — it is a declared
dependency. Django's stock postgresql backend, which django-vpg
subclasses for schema/introspection/operations, imports it at load time.
The IO path never uses it.
Quickstart
DATABASES = {
"default": {
"ENGINE": "django_vpg.backend",
"NAME": "mydb",
"USER": "postgres",
"PASSWORD": "...",
"HOST": "db.example.com",
"PORT": "5432",
# Optional driver OPTIONS (libpq-parity naming; psycopg3-compatible
# pool dict):
# "OPTIONS": {
# "pool": {"max_size": 20, "min_size": 2}, # default max_size: 10
# "sslmode": "verify-full",
# "sslrootcert": "/path/ca.pem",
# },
}
}
Supported OPTIONS keys: pool (psycopg3-compatible dict — max_size,
min_size, timeout, max_lifetime, max_idle, name — or False for
a dedicated single-slot connection per Django connection, e.g. under test
runners), pool_size (shorthand for pool={"max_size": N}; default 10),
prepare_threshold (psycopg3 semantics — int = prepare after N uses, 0 =
prepare on first use, None = disable prepared statements; defaults to off,
matching Django's postgresql backend, so opt in with an int),
prepared_max, isolation_level, application_name, connect_timeout,
keepalives, keepalives_idle, sslmode, sslrootcert, sslcert,
sslkey, and server_settings. pgbouncer (bool) is accepted as a legacy
alias for prepare_threshold=None; prefer the psycopg spelling, which — unlike
pgbouncer — is a real psycopg key, so the same OPTIONS dict also works on the
stock backend. Unknown keys warn once and are dropped.
The async story (three layers)
- Sync ORM — stock Django, zero extra deps. Works everywhere Django works.
- Async driver API — real asyncio, works anywhere. The raw driver
(
django_vpg._vpg_driver.RustPgDriver) exposesawait-able query, execute, transaction, and COPY operations with no dependency on any async framework beyond asyncio itself; driver awaitables interoperate withgather,wait_for,shield, and cancellation. (django_vpg.dbapiitself is the sync DB-API 2.0 shim the Django engine builds on.) - Async ORM — via django-async-backend. Installing the
django-vpg[async]extra activatesAsyncDatabaseWrapper, which plugs into theasync_connectionsframework. Without it, the backend cleanly degrades to sync-only (no ImportError).
Unifying Django's connections and async_connections (transaction
management and isolation across both worlds) is active upstream work in
django-async-backend that this package tracks closely.
Pooling and session semantics (psycopg is the reference)
Two rules, both deliberately psycopg's, because porting an app should not mean re-learning connection behaviour:
- The backend decides whether a transaction is open — never the driver.
Every PostgreSQL response ends with a
ReadyForQuerycarrying the session's transaction state; libpq caches it asPQtransactionStatusand psycopg exposes it asConnection.info.transaction_status, which django-vpg does too. On release the pool applies psycopg_pool's policy: idle sends nothing, an open or failed block is rolled back, and a connection whose state cannot be established is discarded rather than reused. (Inferring this from SQL text instead is not sound — it misreadsROLLBACK TRANSACTION TO SAVEPOINT,COMMIT AND CHAIN,ABORT, comment-led SQL and PL/pgSQL bodies, and it cannot see statements that never went through the driver's own statement path.) A pool hook re-checks at checkout, so no return path can hand on a connection that is still inside a transaction. - Session state is not reset between checkouts. Same as psycopg_pool,
which ships no reset by default: GUCs set with
SET, TEMP tables, session advisory locks andLISTENregistrations survive into whoever checks the connection out next. Reset them yourself if your application needs a clean session — and noteDISCARD ALLis the wrong tool, because it deallocates prepared statements the driver's per-connection cache still refers to.
One more difference worth knowing if you use the async ORM: in async
autocommit each statement borrows a pooled connection and returns it, so
consecutive autocommit statements may run on different backend sessions —
pg_backend_pid() is not stable, and TEMP tables, SET GUCs and advisory
locks do not persist between them. The sync path pins one session per
connection and matches psycopg. Transactions pin in both. This is a
deliberate trade for throughput (holding no connection between statements
lets a small pool serve many concurrent tasks), and it is safe rather than
merely fast because of the status checks above. It will become a
configurable choice before 1.0.
The tokio runtime
The driver runs on a fork-safe shared tokio runtime owned by the package
(1 worker thread by default; VPG_TOKIO_WORKER_THREADS overrides). Prefork
servers are safe: the runtime is rebuilt per child on first use.
Rust embedders get the same hook django-vcache offers: link vpg-pyo3 as
an rlib, re-export its pyclasses into your own pymodule, and install a
process-wide runtime with vpg_core::set_runtime_provider(my_get_runtime)
so one tokio pool serves every driver in the process. (This is how
GlitchTip's own Rust extension embeds the driver.) The hook returns
false if a runtime had already been built — assert on it at module
init to catch wiring mistakes.
Known limitations
USE_TZ = Trueonly (Django's default).timestamptzvalues are returned timezone-aware in UTC. The stock psycopg backend returns naive local datetimes whenUSE_TZ = False; django-vpg does not implement that conversion yet, so aUSE_TZ = Falseproject will hit naive/aware comparison errors on DateTimeFields.- One statement per
execute(). Multi-statement strings (cursor.execute("SET x = 1; SELECT 1")) raise a syntax error where psycopg3 runs them; the extended query protocol is one statement per Parse. Django's schema editor and test-runner paths batch through a dedicated internal path and are unaffected — this only bites ported raw-SQL code, which should split its statements.
Known naming wart: the vendored tokio-postgres buffer-cap patch reads the
GT_PG_BUF_CAP_BYTES env var (512 KiB default retained-buffer cap); it
will be renamed with a compatibility window before 1.0.
Development
./scripts/check.sh # fmt + clippy -D warnings + cargo test + ruff
# (includes tests/wire.rs — an in-process scripted
# PG wire server; no live postgres needed)
# Python suite (needs maturin + a live postgres for the marked tests):
python -m venv .venv && source .venv/bin/activate
pip install maturin pytest pytest-asyncio django psycopg django-async-backend
maturin develop --release
VPG_TEST_DSN=postgres://postgres@localhost:5432/postgres python -m pytest tests/
The workspace is two crates: crates/vpg-core (pure Rust, no pyo3,
cargo test-able) and crates/vpg-pyo3 (thin bindings, cdylib + rlib).
vendor/tokio-postgres carries a minimal retained-buffer-capacity patch —
see vendor/tokio-postgres/GT_PATCH.md for rationale and the re-audit
procedure on version bumps.
License
MIT
Metadata
Release files for django-vpg 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| django_vpg-0.6.1.tar.gz | 404.9 kB | Without provenance | Details |
Built distributions (wheels)
Total release size: 28.8 MB
Release files / django_vpg-0.6.1.tar.gz
| Download URL | django_vpg-0.6.1.tar.gz |
|---|---|
| Size | 404.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
40322a8f88df0d1af1233d23d85d6780655cb585e27818de2b410ff673ca1e6b
|
|
BLAKE2b-256 checksum How to use checksums |
c024bce20ae7938df12c19e86314f4229281321bdc9e9d14482783e0cd212871
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp314-cp314-musllinux_1_2_x86_64.whl
| Download URL | django_vpg-0.6.1-cp314-cp314-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | CPython 3.14 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
a30c511a277d3a2b97b5ff1364668a2c9fbb27315fabb161554e2a4697003d14
|
|
BLAKE2b-256 checksum How to use checksums |
bb373847c47aecceb85c6cc1f42d5bbc69fc8cdc99cfa3a335c285633bb5dd81
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp314-cp314-musllinux_1_2_aarch64.whl
| Download URL | django_vpg-0.6.1-cp314-cp314-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.14 Linux musl 1.2+ ARM64 |
|
SHA-256 checksum How to use checksums |
2fd2c0f095a73b5b6423580b92aa712e2d55c39686d2fe9b392f22dab59dd2e6
|
|
BLAKE2b-256 checksum How to use checksums |
b38ca6c4b47fccecd0dd1c1406b0e6d92e0a6f33760910a70e4ede29fef798bf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | django_vpg-0.6.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | CPython 3.14 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
c93dca43d5e317cb40fb1f4a3d88bf91dfa3c2987d0a959697d3ac60e2daf538
|
|
BLAKE2b-256 checksum How to use checksums |
4859b3f66f13f5d315ee2f01f53f0b831f3d2ae111ada8e07fac1e8f8c33aa1e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | django_vpg-0.6.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.14 Linux glibc 2.17+ ARM64 |
|
SHA-256 checksum How to use checksums |
072bca322c0579704bdce2978785a22605c7b6812d4c121a0f95db3056200bfd
|
|
BLAKE2b-256 checksum How to use checksums |
09ba73c5817a4e9c7bf53d5b41cea039d5b6ee15e589f9cf23a39cd3449a1a87
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp313-cp313-musllinux_1_2_x86_64.whl
| Download URL | django_vpg-0.6.1-cp313-cp313-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | CPython 3.13 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
9a5c89c35d6713ccd66319a7b2b6cb411202e6e4faa40a14db813514e5a77d2f
|
|
BLAKE2b-256 checksum How to use checksums |
aa6b5b8017183f753be326aece1d5a7a0805d43104dc9e1a89c672cc53500a92
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp313-cp313-musllinux_1_2_aarch64.whl
| Download URL | django_vpg-0.6.1-cp313-cp313-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.13 Linux musl 1.2+ ARM64 |
|
SHA-256 checksum How to use checksums |
053b8db1d89e1165957d8b9aa4959c35cf03fc95fd1ea7683e29f5014d8d838d
|
|
BLAKE2b-256 checksum How to use checksums |
cb1a855554f1c13c39e331e83390d128468bd952f2f5218a6bbe8be04273d8fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | django_vpg-0.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
3514a00fc9d0575672299e779fce48458f629c17773b150fc035a554ee6e0fa1
|
|
BLAKE2b-256 checksum How to use checksums |
253702947771f1bfc4650cd185fde364193aaf97c595c038e588b56f6938b67b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | django_vpg-0.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ ARM64 |
|
SHA-256 checksum How to use checksums |
0f66a0acd9764bbd82a5f45ca0a9c47b9d9f2b25184a9929f14a2b8cb63000de
|
|
BLAKE2b-256 checksum How to use checksums |
81a64f0fbdf118ed661cd029844aa5ef67eecf15236b398dc2b8a60a0a1ad152
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp312-cp312-musllinux_1_2_x86_64.whl
| Download URL | django_vpg-0.6.1-cp312-cp312-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | CPython 3.12 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
059d18d9f36af6df03ba7d811ef5813390bd192b71c34f3d1057ddecda25b6d5
|
|
BLAKE2b-256 checksum How to use checksums |
24fd4b070eedbc812129f9074d9c336d2bf8c96a6ca763a100f0aea01f43b41c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp312-cp312-musllinux_1_2_aarch64.whl
| Download URL | django_vpg-0.6.1-cp312-cp312-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.12 Linux musl 1.2+ ARM64 |
|
SHA-256 checksum How to use checksums |
10184501bc11c183a0c4eb21a9c7fae02b89c2745391dd3727fd1d99536fd3c0
|
|
BLAKE2b-256 checksum How to use checksums |
c889406dffaeaa0b3f4de0f2518b3f6790ff76e214e7c87f25af65801747bc3e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | django_vpg-0.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
4162c0828bc39672882ee51939c2d6e57713df89b42e0ac11b706d878feaca6b
|
|
BLAKE2b-256 checksum How to use checksums |
8ee9ddf1c4b8194beede7fce529311c7bca59130371427b9d96f8c42dc01e064
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_vpg-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | django_vpg-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ ARM64 |
|
SHA-256 checksum How to use checksums |
339d856ad56fa7f7148a17a0c7bd4247a70236ca5e9db7f24d2ccedfbb780937
|
|
BLAKE2b-256 checksum How to use checksums |
3460cb135439cc200b010d2f7811c3b8e09fb0b38e515f1d9673a7acf1b3e5b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for django-vpg 0.6.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.