pip 能够搜索包,但安装失败并出现错误

pip is able to search package but install fails with error

我有本地 pypi 服务器,我在其中上传了 cffi 包。

当我尝试搜索时,它 return 包裹。

$ pip search -i https://localhost --trusted-host localhost cffi
cffi (1.11.4)  - 1.11.4

但是安装的时候报错

$ pip install -i https://localhost  --trusted-host localhost cffi==1.11.4
Collecting cffi==1.11.4
  Could not find a version that satisfies the requirement cffi==1.11.4 (from versions: )
No matching distribution found for cffi==1.11.4

我是 运行 pypi 服务器,在 apache 网络服务器下处理 httpscentos 的请求。

我检查了 apache 日志 /var/log/httpd/ssl_access_log,以获取 install 命令。 return 200 GET Call.

127.0.0.1 - - [25/Jan/2018:16:46:23 +0000] "GET /cffi/ HTTP/1.1" 303 -
127.0.0.1 - - [25/Jan/2018:16:46:23 +0000] "GET /simple/cffi/ HTTP/1.1" 200 339

我再次查看日志。对于 celery 它有效,之后对于 cffi 它失败了。

127.0.0.1 - - [25/Jan/2018:16:50:58 +0000] "GET /celery/ HTTP/1.1" 303 -
127.0.0.1 - - [25/Jan/2018:16:50:58 +0000] "GET /simple/celery/ HTTP/1.1" 200 321
127.0.0.1 - - [25/Jan/2018:16:50:58 +0000] "GET /packages/celery-4.0.2-py2.py3-none-any.whl HTTP/1.1" 200 396437
127.0.0.1 - - [25/Jan/2018:16:50:59 +0000] "GET /cffi/ HTTP/1.1" 303 -
127.0.0.1 - - [25/Jan/2018:16:50:59 +0000] "GET /simple/cffi/ HTTP/1.1" 200 339

问题是,cffi 没有重定向到 /packages/cffi-1.11.4-cp35-cp35m-manylinux1_x86_64.whl。在 celery 中,它在 GET /simple/celery/ 之后转到 /packages/celery*

我尝试curl,检查这两个包之间的响应是否有变化,但没有区别。

$ curl -k https://localhost/simple/celery/ -i
HTTP/1.1 200 OK
Date: Thu, 25 Jan 2018 16:59:27 GMT
Server: Apache/2.2.15 (CentOS)
Content-Length: 321
Connection: close
Content-Type: text/html; charset=UTF-8

    <html>
        <head>
            <title>Links for celery</title>
        </head>
        <body>
            <h1>Links for celery</h1>
                 <a href="/packages/celery-4.0.2-py2.py3-none-any.whl#md5=3ff97b53107b491baeb42f662be14a06">celery-4.0.2-py2.py3-none-any.whl</a><br>
        </body>
    </html>
$ curl -k https://localhost/simple/cffi/ -i
HTTP/1.1 200 OK
Date: Thu, 25 Jan 2018 16:59:29 GMT
Server: Apache/2.2.15 (CentOS)
Content-Length: 339
Connection: close
Content-Type: text/html; charset=UTF-8

    <html>
        <head>
            <title>Links for cffi</title>
        </head>
        <body>
            <h1>Links for cffi</h1>
                 <a href="/packages/cffi-1.11.4-cp35-cp35m-manylinux1_x86_64.whl#md5=c9478cf605b4eb2755fa322cc2bf3ddf">cffi-1.11.4-cp35-cp35m-manylinux1_x86_64.whl</a><br>
        </body>
    </html>

遇到此问题时,两个最常见的问题是平台不匹配或 python 版本不匹配。

python 版本检查

检查您的默认 pip 指的 python 版本 - 是 python3.5pip 吗?

$ pip -V | grep -o "(.*)"

会给你信息。如果默认 pip 引用其他 python 版本,则直接使用 pip3.5:

调用 python3.5pip
$ pip3.5 install -i https://localhost  --trusted-host localhost cffi==1.11.4

平台检查

尝试为 manylinux1_x86_64 平台显式下载 cffi 包 - wheel 会下载吗?

$ pip download cffi --only-binary=:all: --platform manylinux1_x86_64 -i https://localhost --trusted-host localhost

如果下载成功,则表明您的 target 计算机平台不匹配。查看 pip:

识别的平台
$ python3.5 -c "import pip; print(pip.pep425tags.get_platform())"

ABI 检查

一个不太常见的问题是 ABI 不匹配:您可以使用

检查平台的 ABI
$ python3.5 -c "import pip; print(pip.pep425tags.get_abi_tag())"

此字符串应与轮子名称中平台标签之前的前缀相匹配,因此在您的情况下,您的 ABI 应为 cp35m


如果您获得 macosx_10_13_x86_64 平台标签,这意味着您拥有 MacOS High Sierra。在您的本地 PyPI 服务器上,您已经上传了只能安装在 linux 上的 cffi wheel(manylinux wheel)。您将无法在 MacOS High Sierra 上安装它。问题是,cffi 包附带了部分用 C 编写的代码,并且仅为 target 平台编译。你有三种可能性来解决这个问题:

  1. 最简单的解决方案:下载 macosx_10_13_x86_64 wheel from PyPI 并将其与 manylinux1 轮一起上传到您的本地服务器。现在 linux 客户端将获得为 linux 编译的轮子,当 运行 pip install cffi.
  2. 时,您将获得为 MacOS 编译的轮子
  3. "DIY" 解决方案:下载 source tar installer from PyPI 并将其与 manylinux1 轮一起上传到本地服务器。现在 linux 客户端将获得已编译的轮子,而 MacOS 和 Windows 客户端将获得源代码 tar,他们被迫在本地编译包含的 C 代码 - 如果OS没有提供合适的工具,安装会失败。
  4. 配置本地服务器代理 PyPI:如果请求包,但在本地服务器上找不到,它会将请求传递给 pypi.python.org,如果在 public 存储库,它被下载并通过您的本地服务器传递,就像在那里找到的一样。但是,不确定您的服务器是否支持此功能。我们使用 devpi 足以告诉您的索引它的基数中应该有 root/pypidevpi index -m user/index bases=root/pypi.

请注意,这些解决方案并不相互排斥:您可以将 1 与 2 结合使用(linux 客户将获得 manylinux1 轮子,High Sierra 将获得 macos_10_13 轮子,其余获得source tar) 甚至 1、2 和 3 一起。这完全取决于您 want/need/can 在本地服务器上上传和维护的内容。