Skip to main content

Self-hosted PyPI download badge service that winnows CI traffic out of download counts.

Project description

pypi-winnow-downloads

PyPI version Python versions License CI Coverage pip*/uv/poetry/pdm downloads

Self-hosted PyPI download badge service that winnows CI traffic out of download counts. Produces shields.io-compatible endpoint badges filtered by BigQuery's details.ci flag and an interactive-installer allowlist (pip, uv, poetry, pdm, pipenv, pipx) — more honest than any existing alternative for small or young Python packages.

The pip*/uv/poetry/pdm badge above is served by this project itself — eating our own dogfood. The endpoint went live with milestone M3 deployment on 2026-04-24 and currently shows 0 until the first release lands on PyPI; after that the count climbs automatically.

What the badge actually counts

The hero badge — labelled pip*/uv/poetry/pdm (Nd) — counts downloads that meet all of these conditions over the configured rolling window:

  • details.ci != True (BigQuery's CI-detection flag is not set)
  • details.installer.name is one of the interactive Python packaging tools: pip, uv, poetry, pdm, pipenv, or pipx (the asterisk in pip* covers pip itself plus pipenv and pipx, which delegate to pip and inherit its installer telemetry pattern)

Excluded (the things that inflate other badges):

  • Mirrors: bandersnatch, Nexus, devpi, Artifactory, z3c.pypimirror
  • Browser fetches via the PyPI web UI (installer_name == "Browser")
  • Generic HTTP UAs used by scrapers and scanners (requests, curl, etc.)
  • Unknown installer (installer_name == "None") — uncategorised traffic that in practice is dominated by automated scanners

For context on how much these can dwarf real installs: at v1 deploy time, one of the seed packages had 2,771 "non-CI" downloads in 30 days under a naïve mirror-and-all-installers query, of which 1,325 (48%) was bandersnatch alone and only 14 came from pip + uv + poetry + pdm. The honest signal is the 14.

The filter is fail-closed: a future pypinfo emitting a new mainstream installer will be excluded until the allowlist in src/pypi_winnow_downloads/collector.py is updated explicitly. That's a feature for a project whose pitch is honesty.

Install

pip install pypi-winnow-downloads

The collector queries Google's public PyPI BigQuery dataset via pypinfo, so before the first run you'll need a Google Cloud service account JSON key. Pypinfo's installation guide walks the full setup (create a GCP project, enable the BigQuery API, generate the JSON key) and recommends the broad BigQuery User role; the narrower pair BigQuery Job User + BigQuery Data Viewer also works and is what config.example.yaml and the reference deploy document. Then point service.credential_file in your config at the resulting file.

Run with a YAML config — copy config.example.yaml and edit:

winnow-collect --config /path/to/config.yaml

To deploy as a daily systemd timer plus a Caddy HTTPS service serving the output directory, see deploy/README.md.

Status

Alpha. Self-hosted reference deployment running at pypi-badges.intfar.com, producing daily badges for four target packages (the three seed packages in config.example.yaml plus pypi-winnow-downloads itself for the dogfood badge). Expect rough edges and possible breaking changes in the 0.x series.

Acknowledgments

This project rests on three pieces of upstream work:

  • pypinfo by Ofek Lev: the BigQuery query layer for the PyPI download dataset. pypi-winnow-downloads is essentially a filter and badge writer wrapped around pypinfo.
  • shields.io renders the endpoint badges. The collector emits the JSON shape that shields.io's endpoint badge consumes, so badges inherit its caching, theming, and SVG rendering.
  • The bigquery-public-data.pypi.file_downloads dataset, hosted by Google as a public BigQuery dataset and populated by the PyPI Linehaul pipeline, is the underlying data source. Without it, no installer-level breakdown of PyPI downloads would be possible.

Designed and built collaboratively with Claude Code (Anthropic) across planning, implementation, review, and QA. Significant subsystems (the pypinfo XDG_DATA_HOME isolation, the sys.executable-based pypinfo resolver, the installer-allowlist filter, the deploy/ examples) emerged through that planner / Dev / QA loop.

License

Licensed under the Apache License, Version 2.0.

© 2026 Chris Means.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pypi_winnow_downloads-0.1.2.tar.gz (129.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pypi_winnow_downloads-0.1.2-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

Details for the file pypi_winnow_downloads-0.1.2.tar.gz.

File metadata

  • Download URL: pypi_winnow_downloads-0.1.2.tar.gz
  • Upload date:
  • Size: 129.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pypi_winnow_downloads-0.1.2.tar.gz
Algorithm Hash digest
SHA256 5042e8a8ed69cada8bcd5391f9429c97d3f20e4f5790ef74a3c149725bbec75c
MD5 a6ac41634015cd6c19161429008d0ca2
BLAKE2b-256 807f49fe8d7a7f20d41d2db7fd626dcac06c65e74e084a00aac0f58eb153454b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypi_winnow_downloads-0.1.2.tar.gz:

Publisher: publish.yml on cmeans/pypi-winnow-downloads

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypi_winnow_downloads-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for pypi_winnow_downloads-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0b76dd4bf2d6770ac31cd7f3690c10dadb579bbf7c88c792e6f79a36f85f45a5
MD5 24ddb71c909fa93062a95106bb4e4981
BLAKE2b-256 df6f6df92f10c8bfb15d0cb470e40b0c9fe48ce5cebca343d452c1c0b2a70364

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypi_winnow_downloads-0.1.2-py3-none-any.whl:

Publisher: publish.yml on cmeans/pypi-winnow-downloads

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page