分析 PyPI 包下载量

本节介绍如何使用公共 PyPI 下载统计数据集,以了解有关 PyPI 上托管的一个或多个包的下载量。例如,您可以使用它来发现用于下载包的 Python 版本分布。

背景

PyPI 不显示下载统计数据,原因有多种:[1]

  • 与内容分发网络 (CDN) 配合使用效率低下: 下载统计数据不断变化。将其包含在项目页面(这些页面被大量缓存)中,将需要更频繁地使缓存失效,并降低缓存的整体效率。

  • 高度不准确: 许多因素会阻止下载计数准确,其中包括:

    • pip 的下载缓存(降低下载计数)

    • 内部或非官方镜像(可以提高或降低下载计数)

    • 未托管在 PyPI 上的包(用于比较)

    • 非官方脚本或试图夸大下载计数(提高下载计数)

    • 已知历史数据质量问题(降低下载计数)

  • 不是特别有用: 一个项目被下载了很多次并不意味着它很好;同样,一个项目没有被下载很多次并不意味着它很糟糕!

简而言之,由于其价值因各种原因而较低,并且使其工作所需的权衡成本较高,因此它一直未能有效利用有限的资源。

公共数据集

作为替代方案,Linehaul 项目 将 PyPI 的下载日志流式传输到 Google BigQuery [2],在那里它们被存储为公共数据集。

设置

为了使用 Google BigQuery 查询 公共 PyPI 下载统计数据集,您需要一个 Google 帐户,并在 Google Cloud Platform 项目上启用 BigQuery API。您可以使用 BigQuery 免费套餐每月运行多达 1TB 的查询,无需信用卡。

有关如何开始使用 BigQuery 的更详细说明,请查看 BigQuery 快速入门指南

数据模式

Linehaul 为每个下载在 bigquery-public-data.pypi.file_downloads 表中写入一个条目。该表包含有关下载了哪个文件以及如何下载的信息。来自 表模式 的一些有用列包括:

Description

示例

时间戳

日期和时间

2020-03-09 00:33:03 UTC

file.project

项目名称

pipenv, nose

file.version

包版本

0.1.6, 1.4.2

details.installer.name

安装程序

pip, bandersnatch

details.python

Python 版本

2.7.12, 3.6.4

有用查询

通过点击“编写查询”按钮在 BigQuery Web UI 中运行查询。

请注意,行存储在分区表中,这有助于限制查询成本。这些示例查询通过过滤 timestamp 列来分析最近的下载量。

统计包下载量

以下查询统计了项目“pytest”的总下载量。

#standardSQL
SELECT COUNT(*) AS num_downloads
FROM `bigquery-public-data.pypi.file_downloads`
WHERE file.project = 'pytest'
  -- Only query the last 30 days of history
  AND DATE(timestamp)
    BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
    AND CURRENT_DATE()

下载次数

26190085

仅统计来自 pip 的下载量,请过滤 details.installer.name 列。

#standardSQL
SELECT COUNT(*) AS num_downloads
FROM `bigquery-public-data.pypi.file_downloads`
WHERE file.project = 'pytest'
  AND details.installer.name = 'pip'
  -- Only query the last 30 days of history
  AND DATE(timestamp)
    BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
    AND CURRENT_DATE()

下载次数

24334215

包下载量随时间变化

要按月下载量分组,请使用 TIMESTAMP_TRUNC 函数。同时按此列过滤可降低相应的成本。

#standardSQL
SELECT
  COUNT(*) AS num_downloads,
  DATE_TRUNC(DATE(timestamp), MONTH) AS `month`
FROM `bigquery-public-data.pypi.file_downloads`
WHERE
  file.project = 'pytest'
  -- Only query the last 6 months of history
  AND DATE(timestamp)
    BETWEEN DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 6 MONTH), MONTH)
    AND CURRENT_DATE()
GROUP BY `month`
ORDER BY `month` DESC

下载次数

1956741

2018-01-01

2344692

2017-12-01

1730398

2017-11-01

2047310

2017-10-01

1744443

2017-09-01

1916952

2017-08-01

Python 版本随时间变化

details.python 列中提取 Python 版本。警告:此查询处理超过 500 GB 的数据。

#standardSQL
SELECT
  REGEXP_EXTRACT(details.python, r"[0-9]+\.[0-9]+") AS python_version,
  COUNT(*) AS num_downloads,
FROM `bigquery-public-data.pypi.file_downloads`
WHERE
  -- Only query the last 6 months of history
  DATE(timestamp)
    BETWEEN DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 6 MONTH), MONTH)
    AND CURRENT_DATE()
GROUP BY `python_version`
ORDER BY `num_downloads` DESC

python

下载次数

3.7

18051328726

3.6

9635067203

3.8

7781904681

2.7

6381252241

null

2026630299

3.5

1894153540

注意事项

除了上述背景中列出的注意事项外,Linehaul 曾存在一个 bug,导致其在 2018 年 7 月 26 日之前严重低估下载统计数据。此日期之前的下载数据在比例上是准确的(例如,Python 2 与 Python 3 下载的百分比),但总数比实际低一个数量级。

附加工具

除了使用 BigQuery 控制台外,还有一些附加工具可能在分析下载统计数据时很有用。

google-cloud-bigquery

您还可以通过 BigQuery API 和 google-cloud-bigquery 项目(BigQuery 的官方 Python 客户端库)以编程方式访问公共 PyPI 下载统计数据集。

from google.cloud import bigquery

# Note: depending on where this code is being run, you may require
# additional authentication. See:
# https://cloud.google.com/bigquery/docs/authentication/
client = bigquery.Client()

query_job = client.query("""
SELECT COUNT(*) AS num_downloads
FROM `bigquery-public-data.pypi.file_downloads`
WHERE file.project = 'pytest'
  -- Only query the last 30 days of history
  AND DATE(timestamp)
    BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
    AND CURRENT_DATE()""")

results = query_job.result()  # Waits for job to complete.
for row in results:
    print("{} downloads".format(row.num_downloads))

pypinfo

pypinfo 是一个命令行工具,提供对数据集的访问并可以生成几个有用的查询。例如,您可以使用命令 pypinfo package_name 查询包的总下载量。

使用 pip 安装 pypinfo

python3 -m pip install pypinfo

用法

$ pypinfo requests
Served from cache: False
Data processed: 6.87 GiB
Data billed: 6.87 GiB
Estimated cost: $0.04

| download_count |
| -------------- |
|      9,316,415 |

pandas-gbq

pandas-gbq 项目允许通过 Pandas 访问查询结果。

参考资料