我在不同的virtualenv环境中安装了很多相同的包。有没有一种方法可以让我下载一个包,然后从本地缓存中安装pip ?
这将减少下载带宽和时间。
根据Pip 文档:
从 v6.0 开始,pip 默认提供开启缓存,其功能类似于 Web 浏览器。虽然默认情况下缓存处于打开状态并且设计为默认执行正确的操作,但您可以禁用缓存并始终使用该
--no-cache-dir
选项访问 PyPI。
因此,如果您想要下载缓存,更新后的答案是仅使用 pip 及其默认值。
来自pip 新闻,版本 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
PIP_DOWNLOAD_CACHE
目录中。例如,我现在有很多 Django 包。virtualenvs
中所述,这并没有消除对网络访问的需求,因此它不是在飞机上创建新的答案,但它仍然很棒。在我看来,pip2pi
对于这个问题,这是一个更加优雅和可靠的解决方案。
从文档:
pip2pi 从 pip 需求构建一个与 PyPI 兼容的包存储库
pip2pi
允许您使用两个简单的命令创建自己的 PyPI 索引:
要镜像包及其所有要求,请使用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
要从上一个目录构建包索引:
$ 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
要从您在步骤 2 中构建的索引安装,您可以简单地使用:
pip install --index-url=file:///tmp/packages/simple/ httpie==0.2
您甚至可以使用pip2pi
.
较新的 Pip 版本现在默认缓存下载。请参阅此文档:
https://pip.pypa.io/en/stable/reference/pip_install/#caching
创建一个名为 的配置文件~/.pip/pip.conf
,并添加以下内容:
[global]
download_cache = ~/.cache/pip
在 OS X 上,更好的选择是~/Library/Caches/pip
因为它遵循其他 OS X 程序使用的约定。
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 命令来安装软件包而不下载它们。
从版本 6.0开始,pip
现在它有自己的缓存:
- 已弃用 DEPRECATION
pip install --download-cache
和pip wheel --download-cache
命令行标志并删除了该功能。由于 pip 现在自动配置和使用它的内部 HTTP 缓存,它取代了--download-cache
现有的选项已经失效,但仍然会被接受,直到它们在 pip v8.0 中被删除。有关更多信息,请参阅https://pip.pypa.io/en/latest/reference/pip_install.html#caching
来自上述链接的更多信息:
从 v6.0 开始,pip 默认提供开启缓存,其功能类似于 Web 浏览器。虽然默认情况下缓存处于打开状态并且设计为默认执行正确的操作,但您可以禁用缓存并始终使用该
--no-cache-dir
选项访问 PyPI。
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 等。
一个更简单的选择是basket
.
给定一个包名,它将把它和所有依赖项下载到一个中心位置;没有任何 pip 缓存的缺点。这非常适合离线使用。
然后,您可以使用此目录作为源pip
:
pip install --no-index -f file:///path/to/basket package
或者easy_install
:
easy_install -f ~/path/to/basket -H None package
您还可以在在线时使用它来更新购物篮。
仅使用 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 的第二次调用,但由于索引已经作为一种缓存发挥作用,它不一定会带来很多。例如,如果您的索引被清空,它会有所帮助。)
有一个名为pip-accelpip
的新解决方案,它是内置缓存的替代品。
pip-accel 程序是 Python 包管理器 pip 的包装器。在给定一个或多个需求文件的情况下,它加速了 pip 的使用来初始化 Python 虚拟环境。它通过结合以下两种方法来实现:
源分发下载被缓存并用于生成源分发档案的本地索引。
二进制发行版用于加速使用二进制组件(如 M2Crypto 和 LXML)安装依赖项的过程。我们无需为每个虚拟环境重新编译这些依赖项,而是将它们编译一次并将结果缓存为二进制 *.tar.gz 分发。
Paylogic 使用 pip-accel 快速可靠地初始化其持续集成从属服务器场上的虚拟环境,这些从属服务器不断运行单元测试(这是开发 pip-accel 的原始用例之一)。我们还在构建服务器上使用它。
我们已经看到从切换pip
到pip-accel
.
我认为包“pip-accel”一定是个不错的选择。
我发现以下内容对于下载软件包然后从这些下载中安装很有用:
pip download -d "$SOME_DIRECTORY" some-package
然后安装:
pip install --no-index --no-cache-dir --find-links="$SOME_DIRECTORY"
$SOME_DIRECTORY
要将包下载到的目录的路径在哪里。