{"id":13813644,"url":"https://github.com/ofek/pypinfo","last_synced_at":"2025-10-26T01:45:49.871Z","repository":{"id":37994880,"uuid":"91201231","full_name":"ofek/pypinfo","owner":"ofek","description":"Easily view PyPI download statistics via Google's BigQuery.","archived":false,"fork":false,"pushed_at":"2025-03-01T18:33:45.000Z","size":204,"stargazers_count":430,"open_issues_count":7,"forks_count":33,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-13T23:54:03.762Z","etag":null,"topics":["bigquery","pypi","python","statistics"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ofek.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.rst","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-05-13T20:33:25.000Z","updated_at":"2025-03-21T15:16:52.000Z","dependencies_parsed_at":"2023-01-21T01:16:53.471Z","dependency_job_id":"cbc4d096-9094-4ceb-812c-a3706bacab90","html_url":"https://github.com/ofek/pypinfo","commit_stats":{"total_commits":197,"total_committers":10,"mean_commits":19.7,"dds":0.583756345177665,"last_synced_commit":"6deaf49c2c0545d2fbc430b9b38477e975b96c7a"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofek%2Fpypinfo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofek%2Fpypinfo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofek%2Fpypinfo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofek%2Fpypinfo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ofek","download_url":"https://codeload.github.com/ofek/pypinfo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254254043,"owners_count":22039792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bigquery","pypi","python","statistics"],"created_at":"2024-08-04T04:01:24.162Z","updated_at":"2025-10-26T01:45:49.863Z","avatar_url":"https://github.com/ofek.png","language":"Python","readme":"# pypinfo: View PyPI download statistics with ease.\n\n[![PyPI version](https://img.shields.io/pypi/v/pypinfo.svg?style=flat-square)](https://pypi.org/project/pypinfo)\n[![Supported Python versions](https://img.shields.io/pypi/pyversions/pypinfo.svg?style=flat-square)](https://pypi.org/project/pypinfo)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)\n[![Code style: Black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/psf/black)\n\npypinfo is a simple CLI to access [PyPI](https://pypi.org/) download statistics via Google's BigQuery.\n\n## Table of contents\n\n1. [Usage](#usage)\n2. [Installation](#installation)\n3. [Credits](#credits)\n\n## Usage\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  Click to unfold usage\n  \u003c/summary\u003e\n\n```console\n$ pypinfo\nUsage: pypinfo [OPTIONS] [PROJECT] [FIELDS]... COMMAND [ARGS]...\n\n  Valid fields are:\n\n  project | version | file | pyversion | percent3 | percent2 | impl | impl-version |\n\n  openssl | date | month | year | country | installer | installer-version |\n\n  setuptools-version | system | system-release | distro | distro-version | ci | cpu |\n\n  libc | libc-version\n\nOptions:\n  -a, --auth TEXT         Path to Google credentials JSON file.\n  --run / --test          --test simply prints the query.\n  -n, --dry-run           Don't run query but display how much data would be processed.\n  -j, --json              Print data as JSON, with keys `rows` and `query`.\n  -i, --indent INTEGER    JSON indentation level.\n  -t, --timeout INTEGER   Milliseconds. Default: 120000 (2 minutes)\n  -l, --limit INTEGER     Maximum number of query results. Default: 10\n  -d, --days INTEGER      Number of days in the past to include. Default: 30\n  -sd, --start-date TEXT  Must be negative or YYYY-MM[-DD]. Default: -31\n  -ed, --end-date TEXT    Must be negative or YYYY-MM[-DD]. Default: -1\n  -m, --month TEXT        Shortcut for -sd \u0026 -ed for a single YYYY-MM month.\n  -w, --where TEXT        WHERE conditional. Default: file.project = \"project\"\n  -o, --order TEXT        Field to order by. Default: download_count\n  --all                   Show downloads by all installers, not only pip.\n  -pc, --percent          Print percentages.\n  -md, --markdown         Output as Markdown.\n  -v, --verbose           Print debug messages to stderr.\n  --version               Show the version and exit.\n  -h, --help              Show this message and exit.\n```\n\npypinfo accepts 0 or more options, followed by exactly 1 project, followed by\n0 or more fields. By default only the last 30 days are queried. Let's take a\nlook at some examples!\n\n_Tip_: If queries are resulting in NoneType errors, increase timeout.\n\n### Downloads for a project\n\n```console\n$ pypinfo requests\nServed from cache: False\nData processed: 2.83 GiB\nData billed: 2.83 GiB\nEstimated cost: $0.02\n\n| download_count |\n| -------------- |\n|    116,353,535 |\n```\n\n### All downloads\n\n```console\n$ pypinfo \"\"\nServed from cache: False\nData processed: 116.15 GiB\nData billed: 116.15 GiB\nEstimated cost: $0.57\n\n| download_count |\n| -------------- |\n|  8,642,447,168 |\n```\n\n### Downloads for a project by Python version\n\n```console\n$ pypinfo django pyversion\nServed from cache: False\nData processed: 967.33 MiB\nData billed: 968.00 MiB\nEstimated cost: $0.01\n\n| python_version | download_count |\n| -------------- | -------------- |\n| 3.8            |      1,735,967 |\n| 3.6            |      1,654,871 |\n| 3.7            |      1,326,423 |\n| 2.7            |        876,621 |\n| 3.9            |        524,570 |\n| 3.5            |        258,609 |\n| 3.4            |         12,769 |\n| 3.10           |          3,050 |\n| 3.3            |            225 |\n| 2.6            |            158 |\n| Total          |      6,393,263 |\n```\n\n### All downloads by country code\n\n```console\n$ pypinfo \"\" country\nServed from cache: False\nData processed: 150.40 GiB\nData billed: 150.40 GiB\nEstimated cost: $0.74\n\n| country | download_count |\n| ------- | -------------- |\n| US      |  6,614,473,568 |\n| IE      |    336,037,059 |\n| IN      |    192,914,402 |\n| DE      |    186,968,946 |\n| NL      |    182,691,755 |\n| None    |    141,753,357 |\n| BE      |    111,234,463 |\n| GB      |    109,539,219 |\n| SG      |    106,375,274 |\n| FR      |     86,036,896 |\n| Total   |  8,068,024,939 |\n```\n\n### Downloads for a project by system and distribution\n\n```console\n$ pypinfo cryptography system distro\nServed from cache: False\nData processed: 2.52 GiB\nData billed: 2.52 GiB\nEstimated cost: $0.02\n\n| system_name | distro_name                     | download_count |\n| ----------- | ------------------------------- | -------------- |\n| Linux       | Ubuntu                          |     19,524,538 |\n| Linux       | Debian GNU/Linux                |     11,662,104 |\n| Linux       | Alpine Linux                    |      3,105,553 |\n| Linux       | Amazon Linux AMI                |      2,427,975 |\n| Linux       | Amazon Linux                    |      2,374,869 |\n| Linux       | CentOS Linux                    |      1,955,181 |\n| Windows     | None                            |      1,522,069 |\n| Linux       | CentOS                          |        568,370 |\n| Darwin      | macOS                           |        489,859 |\n| Linux       | Red Hat Enterprise Linux Server |        296,858 |\n| Total       |                                 |     43,927,376 |\n```\n\n### Most popular projects in the past year\n\n```console\n$ pypinfo --days 365 \"\" project\nServed from cache: False\nData processed: 1.69 TiB\nData billed: 1.69 TiB\nEstimated cost: $8.45\n\n| project         | download_count |\n| --------------- | -------------- |\n| urllib3         |  1,382,528,406 |\n| six             |  1,172,798,441 |\n| botocore        |  1,053,169,690 |\n| requests        |    995,387,353 |\n| setuptools      |    992,794,567 |\n| certifi         |    948,518,394 |\n| python-dateutil |    934,709,454 |\n| idna            |    929,781,443 |\n| s3transfer      |    877,565,186 |\n| chardet         |    854,744,674 |\n| Total           | 10,141,997,608 |\n```\n\n### Downloads between two YYYY-MM-DD dates\n\n\n```console\n$ pypinfo --start-date 2018-04-01 --end-date 2018-04-30 setuptools\nServed from cache: False\nData processed: 571.37 MiB\nData billed: 572.00 MiB\nEstimated cost: $0.01\n\n| download_count |\n| -------------- |\n|      8,972,826 |\n```\n\n### Downloads between two YYYY-MM dates\n\n- A yyyy-mm ``--start-date`` defaults to the first day of the month\n- A yyyy-mm ``--end-date`` defaults to the last day of the month\n\n```console\n$ pypinfo --start-date 2018-04 --end-date 2018-04 setuptools\nServed from cache: False\nData processed: 571.37 MiB\nData billed: 572.00 MiB\nEstimated cost: $0.01\n\n| download_count |\n| -------------- |\n|      8,972,826 |\n```\n\n### Downloads for a single YYYY-MM month\n\n```console\n$ pypinfo --month 2018-04 setuptools\nServed from cache: False\nData processed: 571.37 MiB\nData billed: 572.00 MiB\nEstimated cost: $0.01\n\n| download_count |\n| -------------- |\n|      8,972,826 |\n```\n\n### Percentage of Python 3 downloads of the top 100 projects in the past year\n\nLet's use ``--test`` to only see the query instead of sending it.\n\n```console\n$ pypinfo --test --days 365 --limit 100 \"\" project percent3\nSELECT\n    file.project as project,\n    ROUND(100 * SUM(CASE WHEN REGEXP_EXTRACT(details.python, r\"^([^\\.]+)\") = \"3\" THEN 1 ELSE 0 END) / COUNT(*), 1) as percent_3,\n    COUNT(*) as download_count,\nFROM `bigquery-public-data.pypi.file_downloads`\nWHERE timestamp BETWEEN TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL -366 DAY) AND TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL -1 DAY)\n    AND details.installer.name = \"pip\"\nGROUP BY\n    project\nORDER BY\n    download_count DESC\nLIMIT 100\n```\n\n### Downloads for a given version\n\npypinfo supports [PEP 440 version matching](https://peps.python.org/pep-0440/#version-matching).\n\nWe can use it to query stats on a given major version.\n\n```console\n$ pypinfo -pc 'pip==21.*' pyversion version\nServed from cache: False\nData processed: 34.45 MiB\nData billed: 35.00 MiB\nEstimated cost: $0.01\n\n| python_version | version | percent | download_count |\n| -------------- | ------- | ------- | -------------- |\n| 3.6            | 21.3.1  |  78.74% |         10,430 |\n| 3.8            | 21.3.1  |   7.81% |          1,034 |\n| 3.7            | 21.2.1  |   3.59% |            476 |\n| 3.7            | 21.3.1  |   2.60% |            345 |\n| 3.7            | 21.0.1  |   2.25% |            298 |\n| 3.8            | 21.0.1  |   1.58% |            209 |\n| 3.8            | 21.2.1  |   1.42% |            188 |\n| 3.7            | 21.1.2  |   0.81% |            107 |\n| 3.9            | 21.3.1  |   0.69% |             92 |\n| 3.8            | 21.1.1  |   0.51% |             67 |\n| Total          |         |         |         13,246 |\n```\n\nWe can also use it to query stats on an exact version:\n\n```console\n$ pypinfo -pc 'numpy==1.23rc3' pyversion version\nServed from cache: False\nData processed: 34.01 MiB\nData billed: 35.00 MiB\nEstimated cost: $0.01\n\n| python_version | version   | percent | download_count |\n| -------------- | --------- | ------- | -------------- |\n| 3.9            | 1.23.0rc3 |  63.33% |             38 |\n| 3.8            | 1.23.0rc3 |  28.33% |             17 |\n| 3.10           | 1.23.0rc3 |   8.33% |              5 |\n| Total          |           |         |             60 |\n```\n\nCheck how many downloads came from continuous integration servers:\n\n```console\n❯ pypinfo --percent --days 5 pillow ci\nServed from cache: False\nData processed: 384.22 MiB\nData billed: 385.00 MiB\nEstimated cost: $0.01\n\n| ci    | percent | download_count |\n| ----- | ------- | -------------- |\n| None  |  79.37% |     11,963,127 |\n| True  |  20.63% |      3,109,931 |\n| Total |         |     15,073,058 |\n```\n\n\u003c/details\u003e\n\n## Installation\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  Click to unfold installation\n  \u003c/summary\u003e\n\npypinfo is distributed on **PyPI** as a universal wheel and is available on Linux, macOS and Windows.\n\nThis is relatively painless, I swear.\n\n### Create project\n\n1. Go to https://bigquery.cloud.google.com.\n2. Sign up if you haven't already. The first TB of queried data each month is free. Each additional TB is $5.\n\n3. Sign in on your account if you are not already;\n\n4. Go to https://console.developers.google.com/cloud-resource-manager and click CREATE PROJECT if you don't already have one:\n\n![create](https://user-images.githubusercontent.com/1324225/47172949-6f4ea880-d315-11e8-8587-8b8117efeae9.png \"CREATE PROJECT\")\n\n5. This takes you to [https://console.developers.google.com/projectcreate](https://console.developers.google.com/projectcreate). Fill out the form and click CREATE. Any name is fine, but I recommend you choose something to do with PyPI like pypinfo. This way you know what the project is designated for:\n\n![click](https://user-images.githubusercontent.com/1324225/47173020-986f3900-d315-11e8-90ab-4b2ecd85b88e.png) \n\n6. A while after creation, at the left-top corner, select the project name of your choice on dropdown component AND at the left-top corner \"Navigation Menu\", select option \"Cloud Overview \u003e Dashboard\":\n\n![show](https://user-images.githubusercontent.com/1324225/47173170-0b78af80-d316-11e8-879e-01f34e139b80.png)\n\n### Enable BigQuery API\n\n7. Click on top-left button \"Navigation Menu\" and click on option \"API and services \u003e Library\":\n\n![api_library](https://user-images.githubusercontent.com/13961685/224557997-6842161c-6589-4c2a-8974-6bb3c8dc0b0b.png)\n\n8. Perform a search with keywords \"big query api\" on available text field: \n\n![big_query_api_search](https://user-images.githubusercontent.com/13961685/224558113-4f3a3006-3216-41e9-9554-3ce60da60fd1.png)\n\n9. Enable Big Query API by button \"Enable\" press: \n\n![big_query_api](https://user-images.githubusercontent.com/13961685/224558381-4af65bf6-348b-4e48-bd14-d667c4a6e1c7.png)\n\n10. After enabling, click CREATE CREDENTIALS:\n\n![credentials](https://user-images.githubusercontent.com/1324225/47173432-bc7f4a00-d316-11e8-8152-6a0e6cfab70f.png)\n\n**Note**: You will be requested to go back to Big Query panel. In this case, click on top-left button \"Navigation Menu\", option \"API and services \u003e Enabled APIs and services\" and on consequent page, on item \"Big Query API\": \n\n![enabled_credentials](https://user-images.githubusercontent.com/13961685/224572489-402be9b3-a441-45f0-a469-df3a292b2d80.png)\n\n11. On the page after clicking the \"CREATE CREDENTIALS\" button, choose \"BigQuery API\", \"Application Data\" and \"No, I'm not using them\":\n\n![credentials_page_1](https://user-images.githubusercontent.com/13961685/224556508-e57d9ea0-564c-45db-b553-a53f60c307af.png)\n\n12. Fill account details and press button \"Create and Continue\":\n\n![credentials_page_2](https://user-images.githubusercontent.com/13961685/224557099-e0e4785d-5af8-41d8-b179-5df7c49fca79.png)\n\n13. Select role \"BigQuery User\" (option path \"BigQuery \u003e Big Query User\"), press button \"Done\":\n\n![credentials_page_3](https://user-images.githubusercontent.com/13961685/224557170-73532a10-ad64-4e74-9018-8c5f8ad205d7.png)\n\n14. On Big Query API panel (See **Note** on item *10*), click on tab \"CREDENTIALS\". On section \"Service accounts\", click on created credentials on items 11, 12 and 13.\n\n![create_service_credential_key](https://user-images.githubusercontent.com/13961685/224572983-d005fef7-9490-429a-bd6b-58616dd6cc86.png)\n\n15. On page from credential click, click on tab \"KEYS\". On dropdown menu \"ADD KEY\", click on option \"Create new key\":\n\n![create_credential_key](https://user-images.githubusercontent.com/13961685/224573182-5d812f47-c1c5-4aaa-a774-6ae00ce8250d.png)\n\n16. On appearing box, click on option \"JSON\" and press button \"CREATE\": This will start the download of credentials on a JSON file with name pattern `{name}-{credentials_hash}.json`:\n\n![create_private_key](https://user-images.githubusercontent.com/13961685/224573235-70f35826-73bb-4dad-bcbf-e6267d105121.png)\n\n### Installation and authentication\n\n17. Run `python -m pip install pypinfo` in the terminal.\n18. `pypinfo --auth path/to/your_credentials.json`, or set an environment variable `GOOGLE_APPLICATION_CREDENTIALS` that points to the file.\n\n\u003c/details\u003e\n\n\n## Credits\n\n- [Donald Stufft](https://github.com/dstufft) for maintaining [PyPI](https://pypi.org) all these years;\n- [Google](https://github.com/google) for donating BigQuery capacity to [PyPI](https://pypi.org);\n- [Paul Kehrer](https://github.com/reaperhulk) for his [awesome blog post](https://langui.sh/2016/12/09/data-driven-decisions).\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fofek%2Fpypinfo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fofek%2Fpypinfo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fofek%2Fpypinfo/lists"}