为什么 Python 包无法从我的个人 PyPI 服务器安装?



我已经在debian 9/nginx框上创建了一个个人pypi" packages"服务器,以便我可以使我的服务器构建确定性。我将所有的Python包装固定,并需要确保我的Python软件包的确切版本以及它们的亚依赖性时始终可以在我需要重建我的电子商务服务器时可用。

我使用PIP2PI软件包用所需的软件包填充了这台服务器。但是,当我在客户端服务器上运行" pip install"命令以安装我的软件包时,我会收到以下错误:

Looking in indexes: https://packages.example.com/simple
Collecting Django==1.8.4 (from -r requirements.txt (line 2))
Collecting django-extensions==1.5.7 (from -r requirements.txt (line 3))
  Could not find a version that satisfies the requirement django-extensions==1.5.7 (from -r requirements.txt (line 3)) (from versions: )
No matching distribution found for django-extensions==1.5.7 (from -r requirements.txt (line 3))

我的需求文件中有大约40个软件包,因此这只是发生的情况。Django软件包将安装,但使用Django-Extensions软件包会失败。

如果我在任何客户端服务器上运行此命令,我将获得上面显示的错误:

pip install -r requirements.txt

需求文件看起来像这样:

-i https://packages.example.com/simple
Django==1.8.4
django-extensions==1.5.7
(more packages)

现在在我的软件包服务器上root软件包目录,/var/www/packages具有以下结构:

# /var/www/packages:
├── Django-1.8.4-py2.py3-none-any.whl
├── django_extensions-1.5.7-py2.py3-none-any.whl
├── simple
    ├── django
    │   ├── Django-1.8.4-py2.py3-none-any.whl -> ../../Django-1.8.4-py2.py3-none-any.whl
    │   └── index.html
    ├── django-extensions
    │   ├── django-extensions-1.5.7-py2.py3-none-any.whl -> ../../django_extensions-1.5.7-py2.py3-none-any.whl
    │   └── index.html
    ├── index.html

构建了此目录结构,并使用pip2pi的pip2tgz命令安装了包装:

pip2tgz /var/www/packages/ -r requirements.txt

这是pip2tgz读取的要求输入文件:

-i https://pypi.org/simple
django==1.8.4
django-extensions=1.5.7
(more packages)

这是软件包服务器上的NGINX根目录的方式:

server {
    ...
    root /var/www/packages;
    ...
}

设置了我的软件包服务器上的防火墙以允许ping,允许我进入SSH,以及所有HTTP和HTTPS连接。

我在客户服务器上使用Python 3.5.3和PIP 19.0.3。

我不确定我在做什么错。PIP命令看起来正确,但我想知道PIP2PI软件包是否正确设置了我的软件包目录。如果我将客户端要求文件中的索引参数更改为默认值,则https://pypi.org/simple,所有包装都没有错误。

更新1

如果我尝试从命令行安装django-extensions,而不是通过要求文件,我仍然会出现错误:

pip install --index-url=https://packages.example.com/simple/ django-extensions
Looking in indexes: https://packages.example.com/simple/
Collecting django-extensions
  Could not find a version that satisfies the requirement django-extensions (from versions: )
No matching distribution found for django-extensions

在检查我的其他软件包时,我确实在这里看到了一个模式。每当我尝试安装一个软件包中包含下划线(" _")的软件包时,就会发生错误,但是软件包目录的归一化名称在每个python pep 503中都有一个过度(" - ")。

例如,django-rq失败:

directory: simple/django-rq
file: django_rq-0.9.0-py2.py3-none-any.whl

另一方面,django-redis-cache不会失败:

directory: simple/django-redis-cache
file: django-redis-cache-1.6.5.tar.gz

,但另一个区别是前者是车轮文件,而后者是TGZ文件,因此也可以解释差异。我将继续调查。

更新2

根据Ares的建议,我使用冗长的选项进行了pip安装:

pip install --verbose --index-url=https://packages.example.com/simple/ django-rq

这是错误:

Created temporary directory: /tmp/pip-ephem-wheel-cache-g_hx5tb1
Created temporary directory: /tmp/pip-req-tracker-1bt5psaw
Created requirements tracker '/tmp/pip-req-tracker-1bt5psaw'
Created temporary directory: /tmp/pip-install-dqvtv6ek
Looking in indexes: https://packages.example.com/simple/
Collecting django-rq
  1 location(s) to search for versions of django-rq:
  * https://packages.example.com/simple/django-rq/
  Getting page https://packages.example.com/simple/django-rq/
  Looking up "https://packages.example.com/simple/django-rq/" in the cache
  Request header has "max_age" as 0, cache bypassed
  Starting new HTTPS connection (1): packages.example.com:443
  https://packages.example.com:443 "GET /simple/django-rq/ HTTP/1.1" 304 0
  Analyzing links from page https://packages.example.com/simple/django-rq/
    Skipping link https://packages.example.com/simple/django-rq/django-rq-0.9.0-py2.py3-none-any.whl (from https://packages.example.com/simple/django-rq/); wrong project name (not django-rq)
Cleaning up...
Removed build tracker '/tmp/pip-req-tracker-1bt5psaw'
Exception information:
Traceback (most recent call last):
  File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/cli/base_command.py", line 179, in main
    status = self.run(options, args)
  File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/commands/install.py", line 315, in run
    resolver.resolve(requirement_set)
  File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/resolve.py", line 131, in resolve
    self._resolve_one(requirement_set, req)
  File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/resolve.py", line 294, in _resolve_one
    abstract_dist = self._get_abstract_dist_for(req_to_install)
  File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/resolve.py", line 242, in _get_abstract_dist_for
    self.require_hashes
  File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/operations/prepare.py", line 269, in prepare_linked_requirement
    req.populate_link(finder, upgrade_allowed, require_hashes)
  File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/req/req_install.py", line 196, in populate_link
    self.link = finder.find_requirement(self, upgrade)
  File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/index.py", line 688, in find_requirement
    'No matching distribution found for %s' % req
pip._internal.exceptions.DistributionNotFound: No matching distribution found for django-rq

钥匙似乎是第15行,上面写着"跳过链接...错误的项目名称(不是django-rq)"。我不确定为什么要跳过链接。

对于我的私人软件包服务器,唯一有效的是-extra-index-url:

--extra-index-url https://foo.redacted.com/
Django
my_other_package

这将首先检查PYPI,然后检查您的专用服务器。调试它的一件事是使用--verbose显示连接发生的事情。

看起来您正在使用的pip2pi项目是越野车,并且没有最近维护,有关发行名称中的点/破折号的几个开放性问题:

带有连字符的包裹的问题#84

修复了带有连字符的包裹的不当二进制文件名正常化,名称为#67

更改了dir2pi以在文件链接中使用原始文件名。#85

我建议改用devpi-server

看起来PYPI-Server最能满足我的需求。如我所述,它成功地安装了PIP2PI失败的软件包。它并不是过于复杂的设置,并且可以通过NGINX或APACHE在远程服务器上运行。我发现这篇文章设置了PYPI服务器非常有帮助(尽管它确实有几个错别字)。

最新更新