PyPI Package Download Statistics Scraper avatar

PyPI Package Download Statistics Scraper

Pricing

from $4.01 / 1,000 package extracteds

Go to Apify Store
PyPI Package Download Statistics Scraper

PyPI Package Download Statistics Scraper

Export recent totals, daily download trends, and Python-version breakdowns for named PyPI packages and recurring dependency adoption monitoring.

Pricing

from $4.01 / 1,000 package extracteds

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

PyPI Package Download Statistics

Export PyPI package download statistics for exact package names as structured, timestamped dataset rows. The Actor combines recent one-day, one-week, and one-month totals with daily trends and Python major/minor-version breakdowns.

Use it to compare dependency adoption, watch ecosystem changes on a schedule, or feed package-usage signals into a spreadsheet, warehouse, dashboard, or internal data pipeline. It runs anonymously against public PyPI metadata and ClickPy's public read-only PyPI download dataset; no PyPI account, API key, browser, or user-supplied proxy configuration is required.

What does this Actor do?

For each package name, the Actor:

  1. resolves public PyPI identity and current-version metadata;
  2. retrieves recent download totals;
  3. retrieves the requested daily and Python-version time series;
  4. keeps the latest requested dates;
  5. writes normalized rows to the default Apify dataset.

Every successful package starts with a summary row. Selected reports then add daily, python_major, or python_minor rows. This row-oriented shape is convenient for SQL, pivot tables, time-series charts, and scheduled comparisons.

Who is it for?

  • Platform and infrastructure teams comparing adoption of candidate dependencies.
  • Open-source maintainers tracking package reach and supported Python-runtime usage.
  • Developer-relations teams monitoring package adoption after releases or campaigns.
  • Security and supply-chain teams adding usage context to dependency inventories.
  • Data analysts building recurring Python ecosystem datasets.

Why use this PyPI statistics exporter?

  • Batch up to 20 exact package names in one run.
  • Get recent totals and timestamped breakdowns in one stable schema.
  • Choose only the reports your workflow needs.
  • Bound history to 1–180 available dates and output to 20,000 rows.
  • Schedule runs with Apify and compare snapshots downstream.
  • Pay once per successfully fetched package, not once per historical row.
  • Use lightweight public JSON requests rather than browser automation.

What data can I extract?

FieldMeaning
recordTypesummary, daily, python_major, or python_minor
packageCanonical package name from PyPI metadata, or the requested name when metadata is unavailable
displayNameName from current PyPI package metadata when available
currentVersionCurrent release shown by PyPI when the run executes
dateStatistics date on timestamped rows
categoryMirror scope or Python major/minor version
downloadsDownloads for the row's date and category
lastDayRecent one-day total on a summary row
lastWeekRecent seven-day total on a summary row
lastMonthRecent thirty-day total on a summary row
includesMirrorsRequested mirror scope for daily totals
sourceUrlPublic endpoint represented by the row
retrievedAtUTC timestamp when the package was fetched

Unavailable enrichment values are null; they are never replaced with invented values.

How to run the Actor

  1. Open the Actor in Apify Console.
  2. Add one or more exact names under PyPI package names.
  3. Select daily, Python-major, and/or Python-minor reports.
  4. Choose the number of recent dates to keep.
  5. Optionally include mirror downloads in daily totals.
  6. Click Start.
  7. Open the default dataset to preview, download, or integrate the rows.

A practical first input is:

{
"packages": ["requests", "pandas", "fastapi"],
"reports": ["daily", "pythonMajor"],
"days": 30,
"includeMirrors": false,
"maxRows": 5000
}

Input parameters

packages

Required array of 1–20 exact PyPI project names. Names may contain letters, numbers, dots, underscores, and hyphens. Duplicate names in one input are removed.

reports

Choose one or more values:

  • daily — daily download totals;
  • pythonMajor — daily counts grouped by major runtime such as 3;
  • pythonMinor — daily counts grouped by runtime such as 3.11.

A recent-totals summary is always included and does not need a separate selection.

days

Number of latest available dates to retain in every selected time series. Allowed range: 1–180. Statistics can lag the current date, so “30 days” means the latest 30 dates returned by the source rather than an assurance that today is present.

includeMirrors

When true, daily rows use totals including downloads reported by mirrors. When false, daily rows exclude mirrors. Python-version reports use the source's version categories and are not separately split by mirror status.

maxRows

Global safety limit across summary and breakdown rows. Allowed range: 1–20,000. The Actor stops accepting output when the limit is reached.

Output example

A current summary row has this shape:

{
"recordType": "summary",
"package": "requests",
"displayName": "requests",
"currentVersion": "2.34.2",
"date": null,
"category": null,
"downloads": null,
"lastDay": 27982200,
"lastWeek": 268877908,
"lastMonth": 1497444432,
"includesMirrors": false,
"sourceUrl": "https://clickpy.clickhouse.com/dashboard/requests",
"retrievedAt": "2026-09-07T20:09:26.542Z"
}

A timestamped breakdown row uses date, category, and downloads; recent-total fields are null. Counts change whenever the public source updates.

Understanding the record types

Summary

One row per successfully fetched package. Use lastDay, lastWeek, and lastMonth for quick package comparisons.

Daily

One row per date for the selected mirror scope. Use these rows for trend lines, moving averages, or before-and-after release analysis.

Python major version

One row per date and Python major category. This shows the broad Python 2/3 or future major-version distribution reported by the source.

Python minor version

One row per date and reported minor category. Use it to assess runtime adoption, but remember that client metadata can be missing or nonstandard.

How much does it cost to monitor PyPI packages?

The Actor uses pay-per-event pricing:

  • $0.00005 once when a run starts;
  • $0.0066767 per successfully fetched package on the Bronze tier.

Timestamped rows included for that package have no separate event charge. At Bronze pricing, 1 package costs about $0.00673, 10 packages about $0.06682, and 20 packages about $0.13358. Other account tiers use the prices shown by Apify before the run starts.

A package is charged only after useful rows are saved. Invalid inputs and a package request that fails before output do not create a package event.

Schedule dependency adoption monitoring

Create an Apify Schedule to run daily or weekly with a stable package list. Send each completed dataset to your warehouse, or use an integration to append rows to a spreadsheet. Compare retrievedAt snapshots and source dates downstream rather than expecting the Actor to maintain hidden state between runs.

For example, track fastapi, flask, and django with daily and pythonMajor reports. This gives both package-level totals and runtime-adoption context in every run.

Export to spreadsheets and data pipelines

The default dataset is available as JSON, CSV, Excel, XML, RSS, and other Apify-supported formats. For tabular tools:

  1. filter recordType = summary for package-level comparison;
  2. filter recordType = daily for one line per package/date;
  3. pivot Python rows by category to produce version-share charts;
  4. use retrievedAt to identify the collection snapshot.

Avoid summing the summary totals together with daily or Python rows: they represent overlapping views of the same download activity.

Run through the Apify API

Replace YOUR_TOKEN with an Apify API token.

cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~pypi-package-download-stats/runs?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"packages":["requests","pandas"],"reports":["daily"],"days":30}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/pypi-package-download-stats').call({
packages: ['requests', 'pandas'],
reports: ['daily', 'pythonMajor'],
days: 30,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation-lab/pypi-package-download-stats").call(run_input={
"packages": ["requests", "pandas"],
"reports": ["daily", "pythonMajor"],
"days": 30,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)

Use with Apify MCP

Add this Actor as a tool in Claude Code:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/pypi-package-download-stats"

Claude Desktop

Add this server in Claude Desktop's MCP configuration:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/pypi-package-download-stats"
}
}
}

Cursor

Use the same JSON under Cursor Settings → MCP, then enable the apify server.

VS Code

Add the same HTTP server URL to your VS Code MCP configuration and start the apify server from the MCP tools view.

Example prompts:

  • “Fetch 30 days of daily download statistics for requests, httpx, and aiohttp.”
  • “Compare Python minor-version usage for pandas and polars over the latest 60 dates.”
  • “Run my PyPI dependency monitoring task and summarize changes from the previous dataset.”

Reliability and retries

The Actor queries ClickPy's public read-only ClickHouse service over pre-aggregated tables sourced from official PyPI download logs. It retries temporary throttling, server errors, timeouts, and network failures with bounded backoff; no proxy or browser is required.

It does not hide a failed statistics fetch as an empty successful result. If optional PyPI metadata is unavailable but statistics work, rows are still emitted with nullable metadata.

Limits and data interpretation

  • The Actor accepts exact names; it does not search PyPI by keyword.
  • Public download data is aggregated and can be delayed or revised.
  • Download counts are not equivalent to unique people, production installations, or revenue.
  • CI systems, caches, mirrors, bots, and repeated installs can affect totals.
  • Python-version categories depend on installer metadata observed by the source.
  • PyPI no longer exposes trustworthy download counts by individual package release through this route; currentVersion is identity context, not a per-release download statistic.
  • The maximum supported history is the latest 180 dates exposed by the public ClickPy dataset.
  • The Actor does not send alerts or calculate change percentages itself; use schedules and downstream comparison for those jobs.

Legality and responsible use

The Actor reads anonymous public aggregate statistics and public package metadata. Follow the source's terms, attribution guidance, and request etiquette. Do not use aggregate download counts to identify individuals or make unsupported claims about specific organizations. Apply appropriate review before using popularity signals in security, procurement, or governance decisions.

Troubleshooting

Why did the run fail with a throttling message?

A shared public statistics endpoint may be temporarily busy. The Actor already applies bounded retries. Wait before starting another run, reduce the number of packages or reports, and avoid launching many parallel Tasks against the same source.

Why is the newest date not today?

PyPI download statistics are processed in batches. days selects the latest available source dates and does not manufacture missing dates.

Why are there many Python-version rows?

Each date can contain several runtime categories. Lower days, choose only pythonMajor, or reduce maxRows when you need a smaller dataset.

Why is currentVersion null?

The metadata enrichment request can fail while the statistics endpoint succeeds. Package statistics remain useful and retain the requested package name.

Does includeMirrors affect Python-version rows?

No. It selects the daily overall mirror category. Version reports use the categories returned by their dedicated endpoints.

FAQ

Can I monitor multiple packages?

Yes. Supply up to 20 unique exact package names. Runs process them sequentially to respect public endpoint etiquette.

Can I get weekly and monthly history rows?

The summary includes recent one-week and one-month totals. Timestamped history is daily; aggregate it downstream into calendar weeks or months when needed.

Can I get downloads by package release version?

No. The Actor exports Python interpreter-version breakdowns, not download counts for each package release. currentVersion reports the current PyPI release only.

Does it require a PyPI token?

No. Both data sources used by the Actor are anonymous public endpoints.

Can I use the results in a recurring workflow?

Yes. Run the same input on an Apify Schedule and persist or compare the resulting datasets in your destination system.

These tools cover different sources and should not be treated as substitutes for PyPI's aggregate download statistics.

Support

For reproducible support requests, include the Actor run URL, redacted input, package names, selected reports, and the first relevant error message. Do not post your Apify token or other credentials.