PyPI很慢。我如何运行自己的服务器?

时间:2013-03-21 19:11:40

标签: python caching pip mirroring pypi

当一个新的开发人员加入团队,或者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。

我看过的选项是:

  1. 运行我自己的PyPI实例。有正式的PyPI实施:CheeseShop以及几个第三方实施,例如:djangopypipypiserver(见脚注)

    这种方法的问题在于我对文件上传的完整PyPI功能不感兴趣,我只想反映它提供的内容。

  2. 使用pep381clientpypi-mirror运行PyPI镜像。

    看起来它可以工作,但它需要我的镜像首先从PyPI下载所有内容。我已经设置了pep381client的测试实例,但我的下载速度在5 Kb / s和200 Kb / s之间变化(位,而不是字节)。除非在某个地方有完整的PyPI档案副本,否则我需要几周时间才能有一个有用的镜像。

  3. 使用yopypi之类的PyPI循环代理。

    由于http://pypi.python.org本身由several geographically distinct servers组成,因此无关紧要。

  4. 在开发者之间复制virtualenv,或托管folder of the current project's dependencies

    这不会扩展:我们有几个不同的Python项目,其依赖关系随着时间的推移而变化(缓慢)。只要任何项目的依赖项发生更改,就必须更新此中央文件夹以添加新的依赖项。复制virtualenv比复制软件包更糟糕,因为任何带有C模块的Python软件包都需要为目标系统进行编译。我们的团队拥有Linux和OS X用户。

    (这看起来仍然是坏群的最佳选择。)

  5. 使用智能PyPI缓存代理:collective.eggproxy

    这似乎是一个非常好的解决方案,但the last version on PyPI is dated 2009并讨论了mod_python。

  6. 其他大型Python团队做了什么?什么是快速安装同一组python包的最佳解决方案?

    脚注:

5 个答案:

答案 0 :(得分:28)

你有共享文件系统吗?

因为我会使用pip的缓存设置。这很简单。例如,在/ mnt中创建一个名为pip-cache的文件夹。

mkdir /mnt/pip-cache

然后每个开发人员都会将以下行放入他们的pip配置中(unix = $ HOME / .pip / pip.conf,win =%HOME%\ pip \ pip.ini)

[global]
download-cache = /mnt/pip-cache

它仍会检查PyPi,寻找最新版本。然后检查该版本是否在缓存中。如果是这样,它从那里安装它。如果没有,则下载它。将其存储在缓存中并进行安装。因此,每个新版本只会下载一次。

答案 1 :(得分:9)

虽然它无法解决您的PyPI问题,但可以使用 Terrarium 将构建的virtualenvs交给开发人员(或部署)。

使用terrarium打包,压缩和保存virtualenvs。您可以在本地甚至store them on S3存储它们。从GitHub上的文档:

$ pip install terrarium
$ terrarium --target testenv --storage-dir /mnt/storage install requirements.txt

在构建新环境后,terrarium将归档并压缩环境,然后将其复制到storage-dir指定的位置。

在指定相同storage-dir的相同需求集的后续安装中,terrarium将从/ mnt / storage复制并解压缩压缩存档。

要准确显示玻璃容器如何命名存档,您可以运行以下命令:

$ terrarium key requirements.txt more_requirements.txt
x86_64-2.6-c33a239222ddb1f47fcff08f3ea1b5e1

答案 2 :(得分:7)

我最近在我的开发团队的Vagrant配置中安装了devpi,使其包缓存存在于主机的文件系统中。这允许每个VM拥有自己的devpi-server守护程序,它用作virtualenv / pip的index-url。当VM被销毁并重新配置时,不必一次又一次地下载软件包。只要它们存在于主机的文件系统上,每个开发人员都会下载一次以构建本地缓存。

我们的私有软件包还有一个内部PyPi索引,它目前只是Apache提供的目录。最终,我将把它转换为devpi代理服务器,因此除了托管我们的私有库之外,我们的构建服务器还将为我们的Python依赖项维护包缓存。这将在我们的开发环境,生产部署和公共PyPi之间创建一个额外的缓冲区。

这似乎是迄今为止我发现这些要求的最强大的解决方案。

答案 3 :(得分:3)

看看David Wolever的pip2pi。您可以设置一个cron作业,以保留公司或团队范围内所需软件包的镜像,然后将您的点数指向内部镜像。

答案 4 :(得分:-1)

设置本地服务器,然后修改本地计算机的hosts文件以覆盖实际的URL,而不是指向本地服务器,从而跳过标准DNS。如果完成,则删除主机文件中的行。

或者我想你可以在pip中找到URL并修改它。