当一个新的开发者加入团队,或者 Jenkins 运行一个完整的构建时,我需要创建一个新的 virtualenv。我经常发现使用 Pip 和大量(超过 10 个)需求设置 virtualenv 需要很长时间才能从 PyPI 安装所有内容。通常它完全失败了:
Downloading/unpacking Django==1.4.5 (from -r requirements.pip (line 1))
Exception:
Traceback (most recent call last):
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/basecommand.py", line 107, in main
status = self.run(options, args)
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/commands/install.py", line 256, in run
requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/req.py", line 1018, in prepare_files
self.unpack_url(url, location, self.is_download)
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/req.py", line 1142, in unpack_url
retval = unpack_http_url(link, location, self.download_cache, self.download_dir)
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/download.py", line 463, in unpack_http_url
download_hash = _download_url(resp, link, temp_location)
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/download.py", line 380, in _download_url
chunk = resp.read(4096)
File "/usr/lib64/python2.6/socket.py", line 353, in read
data = self._sock.recv(left)
File "/usr/lib64/python2.6/httplib.py", line 538, in read
s = self.fp.read(amt)
File "/usr/lib64/python2.6/socket.py", line 353, in read
data = self._sock.recv(left)
timeout: timed out
我知道 Pip 的--use-mirrors
标志,有时我团队中的人已经通过使用--index-url http://f.pypi.python.org/simple
(或另一个镜像)来解决问题,直到他们有一个及时响应的镜像。我们在英国,但在德国有一个 PyPI 镜像,我们从其他站点下载数据没有问题。
所以,我正在为我们的团队寻找在内部镜像 PyPI 的方法。
我看过的选项是:
运行我自己的 PyPI 实例。有官方的 PyPI 实现:CheeseShop以及几个第三方实现,例如:djangopypi和pypiserver(见脚注)
这种方法的问题是我对文件上传的完整 PyPI 功能不感兴趣,我只想镜像它提供的内容。
使用pep381client或pypi-mirror运行 PyPI镜像。
这看起来可以工作,但它需要我的镜像首先从 PyPI 下载所有内容。我已经设置了一个 pep381client 的测试实例,但是我的下载速度在 5 Kb/s 和 200 Kb/s 之间变化(位,而不是字节)。除非在某个地方有完整的 PyPI 存档的副本,否则我需要几周的时间才能拥有一个有用的镜像。
使用 PyPI 循环代理,例如yopypi。
这已经无关紧要了,因为http://pypi.python.org本身由几个地理上不同的服务器组成。
在开发人员之间复制 virtualenv,或托管当前项目依赖项的文件夹。
这无法扩展:我们有几个不同的 Python 项目,它们的依赖关系会随着时间(缓慢地)发生变化。一旦任何项目的依赖关系发生变化,就必须更新这个中央文件夹以添加新的依赖关系。复制 virtualenv 比复制包更糟糕,因为任何带有 C 模块的 Python 包都需要为目标系统编译。我们的团队同时拥有 Linux 和 OS X 用户。
(这看起来仍然是一群坏人的最佳选择。)
使用智能 PyPI 缓存代理:collective.eggproxy
这似乎是一个很好的解决方案,但PyPI 的最后一个版本是 2009 年并讨论了 mod_python。
其他大型 Python 团队是做什么的?快速安装同一组 python 包的最佳解决方案是什么?
脚注:
- 我已经看到了如何推出我自己的 PyPI 的问题?,但该问题与托管私有代码有关。
- Python wiki列出了替代的 PyPI 实现
- 我最近还发现了Crate.io,但我不相信这对我使用 Pip 有帮助。
- 有一个网站监控PyPI 镜像状态
- PyPI 上的一些包将它们的文件托管在其他地方,因此即使是完美的镜像也无法帮助所有依赖项