Linux中國

使用 requests 訪問 Python 包索引(PyPI)的 JSON API

PyPIPython 軟體包索引)提供了有關其軟體包信息的 JSON API。本質上,它是機器可以直接使用的數據源,與你在網站上直接訪問是一樣的的。例如,作為人類,我可以在瀏覽器中打開 Numpy 項目頁面,點擊左側相關鏈接,查看有哪些版本,哪些文件可用以及發行日期和支持的 Python 版本等內容:

![NumPy project page](/data/attachment/album/202105/03/112014gwknqnfnauunun6w.png "NumPy project page")

但是,如果我想編寫一個程序來訪問此數據,則可以使用 JSON API,而不必在這些頁面上抓取和解析 HTML。

順便說一句:在舊的 PyPI 網站上,還託管在 pypi.python.org 時,NumPy 的項目頁面位於 pypi.python.org/pypi/numpy,訪問其 JSON API 也很簡單,只需要在最後面添加一個 /json ,即 https://pypi.org/pypi/numpy/json。現在,PyPI 網站託管在 pypi.org,NumPy 的項目頁面是 pypi.org/project/numpy。新站點不會有單獨的 JSON API URL,但它仍像以前一樣工作。因此,你不必在 URL 後添加 /json,只要記住 URL 就夠了。

你可以在瀏覽器中打開 NumPy 的 JSON API URL,Firefox 很好地渲染了數據:

![JSON rendered in Firefox](/data/attachment/album/202105/03/112014ze99pm77pmerzpr8.png "JSON rendered in Firefox")

你可以查看 inforeleaseurls 其中的內容。或者,你可以將其載入到 Python Shell 中,以下是幾行入門教程:

import requests
url = "https://pypi.org/pypi/numpy/json"
r = requests.get(url)
data = r.json()

獲得數據後(調用 .json() 提供了該數據的 字典),你可以對其進行查看:

![Inspecting data](/data/attachment/album/202105/03/112014zzr80jv8yj5vyx0r.png "Inspecting data")

查看 release 中的鍵:

![Inspecting keys in releases](/data/attachment/album/202105/03/112014rcc5b8xc8vbscc6c.png "Inspecting keys in releases")

這表明 release 是一個以版本號為鍵的字典。選擇一個並查看以下內容:

![Inspecting version](/data/attachment/album/202105/03/112015g9a4mxgaxmfnnla9.png "Inspecting version")

每個版本都包含一個列表,release 包含 24 項。但是每個項目是什麼?由於它是一個列表,因此你可以索引第一項並進行查看:

![Indexing an item](/data/attachment/album/202105/03/112015u05ktukzcw16k0zc.png "Indexing an item")

這是一個字典,其中包含有關特定文件的詳細信息。因此,列表中的 24 個項目中的每一個都與此特定版本號關聯的文件相關,即在 https://pypi.org/project/numpy/1.20.1/#files 列出的 24 個文件。

你可以編寫一個腳本在可用數據中查找內容。例如,以下的循環查找帶有 sdist(源代碼包)的版本,它們指定了 requires_python 屬性並進行列印:

for version, files in data['releases'].items():
    for f in files:
        if f.get('packagetype') == 'sdist' and f.get('requires_python'):
            print(version, f['requires_python'])

![sdist files with requires_python attribute](/data/attachment/album/202105/03/112015lzuqnbu95ll52qlu.png "sdist files with requires_python attribute ")

piwheels

去年,我在 piwheels 網站上實現了類似的 APIpiwheels.org 是一個 Python 軟體包索引,為樹莓派架構提供了 wheel(預編譯的二進位軟體包)。它本質上是 PyPI 軟體包的鏡像,但帶有 Arm wheel,而不是軟體包維護者上傳到 PyPI 的文件。

由於 piwheels 模仿了 PyPI 的 URL 結構,因此你可以將項目頁面 URL 的 pypi.org 部分更改為 piwheels.org。它將向你顯示類似的項目頁面,其中詳細說明了構建的版本和可用的文件。由於我喜歡舊站點允許你在 URL 末尾添加 /json 的方式,所以我也支持這種方式。NumPy 在 PyPI 上的項目頁面為 pypi.org/project/numpy,在 piwheels 上,它是 piwheels.org/project/numpy,而 JSON API 是 piwheels.org/project/numpy/json 頁面。

沒有必要重複 PyPI API 的內容,所以我們提供了 piwheels 上可用內容的信息,包括所有已知發行版的列表,一些基本信息以及我們擁有的文件列表:

![JSON files available in piwheels](/data/attachment/album/202105/03/112016nfk00450ukq75kku.png "JSON files available in piwheels")

與之前的 PyPI 例子類似,你可以創建一個腳本來分析 API 內容。例如,對於每個 NumPy 版本,其中有多少 piwheels 文件:

import requests

url = "https://www.piwheels.org/project/numpy/json"
package = requests.get(url).json()

for version, info in package['releases'].items():
    if info['files']:
        print('{}: {} files'.format(version, len(info['files'])))
    else:
        print('{}: No files'.format(version))

此外,每個文件都包含一些元數據:

![Metadata in JSON files in piwheels](/data/attachment/album/202105/03/112016j2a9mo2io23xab6b.png "Metadata in JSON files in piwheels")

方便的是 apt_dependencies 欄位,它列出了使用該庫所需的 Apt 軟體包。本例中的 NumPy 文件,或者通過 pip 安裝 Numpy,你還需要使用 Debian 的 apt 包管理器安裝 libatlas3-baselibgfortran

以下是一個示例腳本,顯示了程序包的 Apt 依賴關係:

import requests

def get_install(package, abi):
    url = 'https://piwheels.org/project/{}/json'.format(package)
    r = requests.get(url)
    data = r.json()
    for version, release in sorted(data['releases'].items(), reverse=True):
        for filename, file in release['files'].items():
            if abi in filename:
                deps = ' '.join(file['apt_dependencies'])
                print("sudo apt install {}".format(deps))
                print("sudo pip3 install {}=={}".format(package, version))
                return

get_install('opencv-python', 'cp37m')
get_install('opencv-python', 'cp35m')
get_install('opencv-python-headless', 'cp37m')
get_install('opencv-python-headless', 'cp35m')

我們還為軟體包列表提供了一個通用的 API 入口,其中包括每個軟體包的下載統計:

import requests

url = "https://www.piwheels.org/packages.json"
packages = requests.get(url).json()
packages = {
    pkg: (d_month, d_all)
    for pkg, d_month, d_all, *_ in packages
}

package = 'numpy'
d_month, d_all = packages[package]

print(package, "has had", d_month, "downloads in the last month")
print(package, "has had", d_all, "downloads in total")

pip search

pip search 因為其 XMLRPC 介面過載而被禁用,因此人們一直在尋找替代方法。你可以使用 piwheels 的 JSON API 來搜索軟體包名稱,因為軟體包的集合是相同的:

#!/usr/bin/python3
import sys

import requests

PIWHEELS_URL = 'https://www.piwheels.org/packages.json'

r = requests.get(PIWHEELS_URL)
packages = {p[0] for p in r.json()}

def search(term):
    for pkg in packages:
        if term in pkg:
            yield pkg

if __name__ == '__main__':
    if len(sys.argv) == 2:
        results = search(sys.argv[1].lower())
        for res in results:
            print(res)
    else:
        print("Usage: pip_search TERM")

有關更多信息,參考 piwheels 的 JSON API 文檔.

本文最初發表在 Ben Nuttall 的 Tooling Tuesday 博客上,經許可轉載使用。

via: https://opensource.com/article/21/3/python-package-index-json-apis-requests

作者:Ben Nuttall 選題:lujun9972 譯者:MjSeven 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國