如何使用pip从本地缓存安装?


142

我在不同的virtualenv环境中安装了许多相同的软件包。有没有一种方法可以下载一次软件包,然后从本地缓存安装pip

这将减少下载带宽和时间。


1
请注意,自pip 6.0(2014-12-22)起,pip将默认缓存。有关详细信息,请参见pip.pypa.io/en/stable/reference/pip_install.html#caching
Pi Delport

它不仅可以减少下载带宽时间,还可以消除花在爬网PyPI索引上以检查包的可用版本的时间,如果您正在缓存轮子,还可以节省花费时间为不提供轮子的包建造轮子。它大大提高了速度。
乔纳森·哈特利

Answers:


125

更新的答案15年11月19日

根据Pip文档

从v6.0开始,pip默认提供了一个on缓存,其功能类似于Web浏览器。默认情况下,当缓存处于打开状态并且被设计为默认时,您可以禁用缓存并始终通过使用该--no-cache-dir选项来访问PyPI 。

因此,更新的答案是,如果要下载缓存,请仅使用pip及其默认值。

原始答案

pip news版本0.1.4:

增加了对环境变量$ PIP_DOWNLOAD_CACHE的支持,该变量将缓存软件包下载,因此以后的安装将不需要大量下载。仍然需要网络访问,但是使用此网络时将避免某些下载。

为了利用这一点,我在我的内容中添加了以下内容~/.bash_profile

export PIP_DOWNLOAD_CACHE=$HOME/.pip_download_cache

或者,如果您使用的是Mac,则:

export PIP_DOWNLOAD_CACHE=$HOME/Library/Caches/pip-downloads

笔记

  1. 如果检测到软件包的较新版本,它将被下载并添加到PIP_DOWNLOAD_CACHE目录中。例如,我现在有很多Django软件包。
  2. 正如pip新闻所述,这并不能消除对网络访问的需求,因此,这并不是virtualenvs在飞机上创建新飞机的答案,但这仍然很棒。

4
也许更好的主意是将其放入.bashrc中,因为bash_profile仅在登录期间执行。这取决于您,无论如何这是一个很好的建议:)
Nikita Hismatov,2012年

1
在Mac上,它是在任何Shell的开头加载的。
saul.shanabrook 2012年

3
PIP_DOWNLOAD_CACHE存在严重缺陷,我不建议将其用于将软件包发送到部署计算机等事情。它还仍然依赖pypi.python.org的可达性。非常适合本地开发缓存,但不适合大量使用。
slacy 2012年

1
@slacy您能否评论为什么它存在严重缺陷?如果您不希望PyPI可以访问,那就是--no-index的目的。下载缓存肯定与达到PyPI正交!
lvh 2013年

@lvh slacy在下面的回答解释了为什么Pip的下载缓存存在缺陷。我还看到奇怪的是,启用缓存后pip的安装花费的时间更长。点子加速似乎是更好的选择。
qris 2014年

52

我认为,这pip2pi是一个解决此问题的更优雅,更可靠的解决方案。

从文档:

pip2pi根据pip要求构建与PyPI兼容的软件包存储库

pip2pi 允许您使用两个简单的命令来创建自己的PyPI索引:

  1. 要反映软件包及其所有要求,请使用pip2tgz

    $ cd /tmp/; mkdir package/
    $ pip2tgz packages/ httpie==0.2
    ...
    $ ls packages/
    Pygments-1.5.tar.gz
    httpie-0.2.0.tar.gz
    requests-0.14.0.tar.gz
    
  2. 要从先前的目录构建包索引:

    $ ls packages/
    bar-0.8.tar.gz
    baz-0.3.tar.gz
    foo-1.2.tar.gz
    $ dir2pi packages/
    $ find packages/
    /httpie-0.2.0.tar.gz
    /Pygments-1.5.tar.gz
    /requests-0.14.0.tar.gz
    /simple
    /simple/httpie
    /simple/httpie/httpie-0.2.0.tar.gz
    /simple/Pygments
    /simple/Pygments/Pygments-1.5.tar.gz
    /simple/requests
    /simple/requests/requests-0.14.0.tar.gz
    
  3. 要从您在步骤2中构建的索引进行安装,您可以简单地使用:

    pip install --index-url=file:///tmp/packages/simple/ httpie==0.2
    

您甚至可以使用将自己的索引镜像到远程主机pip2pi


+1 pip2pip很棒!!我不太喜欢网络连接。当您最需要它时,它会失败。
MGP

这很好用,它回答了我的问题stackoverflow.com/questions/18052217 / ...,您还能在那里回答吗?
拉里·蔡

1
也许是隐含的,但值得一提:pip2tgz检测您是否已将软件包下载到指定目录,因此,如果您运行相同的安装行或具有重叠依赖性的多个安装行,则每个软件包只会下载一次。
clacke 2014年

32

对于较新的Pip版本:

现在,默认情况下,较新的Pip版本会缓存下载内容。请参阅此文档:

https://pip.pypa.io/zh_CN/stable/reference/pip_install/#caching

对于较早的Pip版本:

创建一个名为的配置文件~/.pip/pip.conf,并添加以下内容:

[global]
download_cache = ~/.cache/pip

在OS X上,一个更好的选择路径是,~/Library/Caches/pip因为它遵循其他OS X程序使用的约定。


如果我想将它们全局存储以供同一台PC的其他用户访问?我该怎么办?我认为配置文件必须放在/ etc之内
Batandwa 2014年

@batandwa:这可能有用。如果没有,您可以尝试以下操作:确保所有用户pip.confdownload_cache设置都指向同一系统范围的目录。
Flimm 2014年

28

PIP_DOWNLOAD_CACHE有一些严重的问题。最重要的是,它将下载的主机名编码到缓存中,因此使用镜像变得不可能。

管理pip下载缓存的更好方法是将“下载软件包”步骤与“安装软件包”步骤分开。下载的文件通常称为“ sdist文件”(源分发),我将它们存储在$ SDIST_CACHE目录中。

最后两个步骤是:

pip install --no-install --use-mirrors -I --download=$SDIST_CACHE <package name>

它将下载软件包并将其放置在$ SDIST_CACHE指向的目录中。它不会安装软件包。然后运行:

pip install --find-links=file://$SDIST_CACHE --no-index --index-url=file:///dev/null <package name> 

将软件包安装到您的虚拟环境中。理想情况下,$ SDIST_CACHE将在您的源代码控制下提交。部署到生产环境时,仅运行第二个pip命令即可安装软件包,而无需下载它们。


Gabriel-它没有被下载两次,在第一步中只有一次,然后在第二步中从本地缓存安装。你在看什么
slacy 2012年

如果我将第一步运行两次,它将下载两次,对吗?至少它发生在这里。我需要知道该程序包的第一步已经执行了至少一次,然后才能执行,否则它将下载相同的文件两次。如何检查我是否需要执行它或之前已经下载了它?
加百利·雅丹(GabrielJordão)2012年

您可能只想使用pip2pi作为其他答案。:)
slacy 2012年

这也会下载依赖项吗?
monkut

我使用pip 18.1,选项--no-install不存在。关于如何更新此答案有任何想法吗?
paolof89

13

6.0版开始,pip现在进行自己的缓存:

  • 不建议使用DEPRECATION pip install --download-cachepip wheel --download-cache命令行标志,并删除功能。由于pip现在可以自动配置和使用其内部HTTP缓存,从而取代了--download-cache现有选项,使其无法使用,但在pip v8.0中将其删除之前,这些选项仍将被接受。有关更多信息,请参见https://pip.pypa.io/en/latest/reference/pip_install.html#caching

来自以上链接的更多信息:

从v6.0开始,pip默认提供了一个on缓存,其功能类似于Web浏览器。默认情况下,当缓存处于打开状态并且被设计为默认时,您可以禁用缓存并始终通过使用该--no-cache-dir选项来访问PyPI 。


9

pip wheel是一个出色的选择,它具有预编译软件包的额外功能,可以满足您的需求。从官方文档

为需求(及其所有依赖项)构建轮子:

$ pip wheel --wheel-dir=/tmp/wheelhouse SomePackage

现在您的/tmp/wheelhouse目录已经预编译了所有依赖项,因此您可以将该文件夹复制到另一台服务器并使用以下命令安装所有内容:

$ pip install --no-index --find-links=/tmp/wheelhouse SomePackage

请注意,并非所有软件包都可以完全跨机器移植。某些软件包将专门针对您使用的Python版本,操作系统发行版和/或硬件体系结构而构建。这将在文件名中指定,例如-cp27-none-linux_x86_64在64位Linux上的CPython 2.7等。


3

仅使用pip(我的版本是1.2.1),您还可以像这样建立本地存储库:

if ! pip install --find-links="file://$PIP_SDIST_INDEX" --no-index <package>; then
    pip install --download-directory="$PIP_SDIST_INDEX" <package>
    pip install --find-links="file://$PIP_SDIST_INDEX" --no-index <package>
fi

在第一次调用pip时,将在本地存储库中(仅)查找需求文件中的软件包,然后从那里进行安装。如果失败,则pip从其通常的位置(例如PyPI)中检索软件包并将其下载到PIP_SDIST_INDEX(但未安装任何东西!)。“重复”第一个调用以从本地索引正确安装软件包。

--download-cache创建一个本地文件名,它是完整的(转义的)URL,并且pip不能将其用作带有--find-links。的索引。 --download-cache如果找到,它将使用缓存的文件。我们可以将此选项添加到pip的第二次调用中,但是由于索引已经作为一种缓存起作用了,它并不一定带来很多。例如,如果清空索引,这将有所帮助。)


3

有一个名为pip-accel的新解决方案,它是pip内置缓存的替代品。

pip-accel程序是Python包管理器pip的包装。给定一个或多个需求文件,它可以加快使用pip初始化Python虚拟环境的速度。它通过组合以下两种方法来做到这一点:

  • 源分发下载被缓存并用于生成源分发档案的本地索引。

  • 二进制分发用于加速使用二进制组件(例如M2Crypto和LXML)安装依赖项的过程。无需为每个虚拟环境重新编译这些依赖关系,我们只编译一次并将其缓存为二进制* .tar.gz分发。

Paylogic使用pip-accel在其不断集成的从属服务器场中快速可靠地初始化虚拟环境,这些服务器不断运行单元测试(这是开发pip-accel的原始用例之一)。我们还在构建服务器上使用它。

从切换到pip,我们已经看到了大约10倍的加速pip-accel


2

一个更简单的选择是basket

给定一个程序包名称,它将把它和所有依赖项下载到一个中央位置。没有pip缓存的任何缺点。这非常适合离线使用。

然后,您可以将此目录用作以下文件的源pip

pip install --no-index -f file:///path/to/basket package

easy_install

easy_install -f ~/path/to/basket -H None package

您还可以在在线时使用它来更新购物篮。


限制(从官方页面开始):Basket只下载源代码发行版,不能下载未托管在PyPI上的软件包,并且忽略版本要求(例如“ nose> = 1.1.2”),始终下载最新版本。
hdiogenes

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.