为什么赢了';从我的个人PyPI服务器安装Python包?
我已经在Debian9/Nginx机器上创建了一个个人PyPI“packages”服务器,这样我就可以使我的服务器构建具有确定性。我锁定了所有Python包,并需要确保每当我需要重建电子商务服务器时,Python包及其子依赖项的确切版本始终可用 我使用包将所需的包填充到此服务器。但是,当我在客户机服务器上运行“pip install”命令来安装我的软件包时,我得到了以下错误:为什么赢了';从我的个人PyPI服务器安装Python包?,python,django,pip,Python,Django,Pip,我已经在Debian9/Nginx机器上创建了一个个人PyPI“packages”服务器,这样我就可以使我的服务器构建具有确定性。我锁定了所有Python包,并需要确保每当我需要重建电子商务服务器时,Python包及其子依赖项的确切版本始终可用 我使用包将所需的包填充到此服务器。但是,当我在客户机服务器上运行“pip install”命令来安装我的软件包时,我得到了以下错误: Looking in indexes: https://packages.example.com/simple Coll
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包将被安装,但pip将因Django扩展包而失败
如果在任何客户端服务器上运行此命令,则会出现上面显示的错误:
pip install -r requirements.txt
需求文件如下所示:
-i https://packages.example.com/simple
Django==1.8.4
django-extensions==1.5.7
(more packages)
现在,在我的包服务器上,根包目录/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连接
我在客户端服务器上使用的是Python3.5.3和PIP19.0.3
我不确定我做错了什么。pip命令看起来是正确的,但我想知道pip2pi包是否正确设置了我的包目录。如果我将客户机需求文件中的index参数更改为默认值,则所有包都会恢复,不会出现错误
更新1
如果我尝试从命令行而不是通过需求文件安装django扩展,我仍然会收到一个错误:
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,每当我尝试安装一个程序包时,如果其中的控制盘文件名包含下划线(“\”),但程序包目录的规范化名称中有一个hypen(“-”),就会发生错误
例如,django rq失败:
directory: simple/django-rq
file: django_rq-0.9.0-py2.py3-none-any.whl
另一方面,django redis缓存不会失败:
directory: simple/django-redis-cache
file: django-redis-cache-1.6.5.tar.gz
但是另一个区别是前者是一个轮子文件,而后者是一个tgz文件,所以这也可以解释这个区别。我会继续调查此事
更新2
根据Ares的建议,我使用verbose选项运行了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)。”我不知道为什么它会跳过链接。对于我的私有包服务器,唯一有效的方法是--额外的索引url:
--extra-index-url https://foo.redacted.com/
Django
my_other_package
这将首先检查pypi,然后检查您的专用服务器。有一件事有助于调试它,那就是使用
--verbose
来显示连接发生了什么情况。您正在使用的pip2pi
项目似乎有问题,而且最近没有维护,关于分发名称中的点/破折号有几个未决问题:
我建议改为退房。它看起来最能满足我的需要。它成功地安装了pip2pi未能安装的包,正如我前面所述。它的设置并不太复杂,可以通过Nginx或Apache在远程服务器上运行。我发现这篇文章非常有帮助(尽管它确实有一些打字错误)。打开
https://packages.example.com/simple
在您的浏览器中?正如您所期望的,我会获得一个指向安装在包服务器上的所有包的控制盘文件的链接列表。然后,我觉得一切正常。尝试在cmdline上为pip安装指定--extra index url选项我尝试了,但仍然出现错误。请参阅我上述问题末尾的更新。感谢您的建议。如果包名称中的破折号被下划线替换,则看起来pip2pi
发送了错误的项目名称。我不确定将控制盘重命名(例如,django_扩展
到django扩展
)是否会有帮助,但如果服务器在包名替换方面有困难,我还建议从pip2pi
移动到devpi
(请参见@wim的答案)。添加详细参数对于调试很有用。但是使用'--extra index url'而不是'--index url'违背了我的目的,因为这样做会导致安装包的最新版本,而不是我的(旧的)固定版本;为什么不将自定义包的版本号设置为普通存储库中不存在的版本号?然后您可以使用--extra index url,因为在正常的pypi repository中找不到该版本。我现在正在学习教程,但devpi似乎创建了整个pypi索引的镜像,这不是我想要的。它是否允许我在我的打包服务器上创建一个与PyPI兼容的私有索引,该索引只包含我所需版本的40个左右的特定包?理想情况下,我需要一个工具,它将获取一个requirements.txt文件,其中包含一个固定包列表,并且只在我的打包服务器上安装这些包(最好是它们的轮子)。我不想镜像所有PyPI,然后安装我的软件包的最新版本。镜像PyPI是devpi服务器
的一个配置选项。如果你不想的话,你可以关闭它。虽然它非常优雅,而且有很好的文档记录,但是devpi看起来并不是一个适合我需要的好解决方案。devppi似乎更倾向于开发Python包的开发团队。我是Python/Django web应用程序的独立开发人员。我没有setup.py文件,也没有使用tox。我有一个需求文件,可以提供给virtualenv或pipenv来创建我的虚拟环境。我只需要一个私有的PyPI索引,在那里我可以上传我所需的Python包的特定版本