PyPI Package Download Statistics Scraper
Pricing
from $4.01 / 1,000 package extracteds
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
Maintained by CommunityActor 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:
- resolves public PyPI identity and current-version metadata;
- retrieves recent download totals;
- retrieves the requested daily and Python-version time series;
- keeps the latest requested dates;
- 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?
| Field | Meaning |
|---|---|
recordType | summary, daily, python_major, or python_minor |
package | Canonical package name from PyPI metadata, or the requested name when metadata is unavailable |
displayName | Name from current PyPI package metadata when available |
currentVersion | Current release shown by PyPI when the run executes |
date | Statistics date on timestamped rows |
category | Mirror scope or Python major/minor version |
downloads | Downloads for the row's date and category |
lastDay | Recent one-day total on a summary row |
lastWeek | Recent seven-day total on a summary row |
lastMonth | Recent thirty-day total on a summary row |
includesMirrors | Requested mirror scope for daily totals |
sourceUrl | Public endpoint represented by the row |
retrievedAt | UTC timestamp when the package was fetched |
Unavailable enrichment values are null; they are never replaced with invented values.
How to run the Actor
- Open the Actor in Apify Console.
- Add one or more exact names under PyPI package names.
- Select daily, Python-major, and/or Python-minor reports.
- Choose the number of recent dates to keep.
- Optionally include mirror downloads in daily totals.
- Click Start.
- 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 as3;pythonMinor— daily counts grouped by runtime such as3.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:
- filter
recordType = summaryfor package-level comparison; - filter
recordType = dailyfor one line per package/date; - pivot Python rows by
categoryto produce version-share charts; - use
retrievedAtto 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 ApifyClientclient = 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().itemsprint(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;
currentVersionis 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.
Related automation-lab Actors
- Artifact Hub Packages Scraper for cloud-native package metadata.
- npm Package Intelligence Scraper for npm metadata and ecosystem signals.
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.