如何强制 pip 获取轮包(即使是包依赖项)?



我正在尝试使用一些python软件包构建一个多阶段docker映像。出于某种原因,即使 Pypi 中存在.whl文件,pip wheel命令仍会下载源文件.tar.gz少数包。例如:它为熊猫做,numpy。

以下是我的要求.txt:

# REST client
requests
# ETL
pandas
# SFTP
pysftp
paramiko
# LDAP
ldap3
# SMB
pysmb

Dockerfile 的第一阶段:

ARG IMAGE_TAG=3.7-alpine
FROM python:${IMAGE_TAG} as python-base
COPY ./requirements.txt /requirements.txt
RUN mkdir /wheels && 
apk add build-base openssl-dev pkgconfig libffi-dev
RUN pip wheel --wheel-dir=/wheels --requirement /requirements.txt
ENTRYPOINT tail -f /dev/null

下面的输出显示它正在下载Pandas的源包,但它有一个请求包的轮子。此外,令人惊讶的是,下载和构建这些软件包需要很多时间(我的意思是很多时间)!!

Step 5/11 : RUN pip wheel --wheel-dir=/wheels --requirement /requirements.txt
---> Running in d7bd8b3bd471
Collecting requests (from -r /requirements.txt (line 4))
Downloading https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl (57kB)
Saved /wheels/requests-2.22.0-py2.py3-none-any.whl
Collecting pandas (from -r /requirements.txt (line 7))
Downloading https://files.pythonhosted.org/packages/0b/1f/8fca0e1b66a632b62cc1ae38e197befe48c5cee78f895edf4bf8d340454d/pandas-0.25.0.tar.gz (12.6MB)

我想知道如何强制它为所有必需的包以及这些包中列出的依赖项获取一个轮文件。我观察到一些依赖项获取轮文件,而其他依赖项获取源包。

注意:上面的代码是多个在线资源的组合。

非常感谢任何使此构建过程更容易的帮助。

提前谢谢。

  1. 您正在使用 Alpine Linux。这个有点独特,因为它使用 musl 作为底层 libc 实现,而不是大多数使用 glibc 的其他 Linux 发行版。

  2. 如果一个 Python 项目实现了 C 扩展(例如,这就是numpypandas),它有两个选择:要么

    • 提供一个源码 dist (.tar.gz.tar.bz2.zip),以便使用目标系统上的 C 编译器/库编译 C 扩展,或者
    • 提供一个包含已编译 C 扩展的轮子。如果扩展是针对 glibc 编译的,它们将无法在使用 musl 的系统上使用,反之亦然。

现在,Python 定义了在 PEP 513 中指定并在 PEP 571 中更新的manylinux1平台标记。基本上,这个名字说明了一切 - 带有编译 C 扩展的轮子应该针对 glibc 构建,因此可以在许多发行版(使用 glibc)上运行,但不适用于某些发行版(Alpine 就是其中之一)。

对你来说,这意味着你有两种可能性:要么从源代码构建软件包(这是pip已经做的),要么通过Alpine的包管理器安装预构建的包。 例如,对于py3-pandas,这意味着要做:

# echo "@edge http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
# apk update
# apk add py3-pandas@edge

但是,我认为从源代码构建软件包没有大问题。如果操作正确,您可以在图像中尽可能高的单独图层中捕获它,因此它会被缓存,而不是每次都重新构建。


你可能会问,为什么没有类似于manylinux1的平台标签,而是基于musl的发行版?因为还没有人编写类似于 PEP 513 的 PEP 来定义musllinux平台标签。如果您对它的当前状态感兴趣,请查看问题 #37。

<小时 />

更新

PEP 656 现在接受定义musllinux平台标签,因此(希望)在Alpine的预制车轮开始发货之前,它(希望)不会持续很长时间。您可以在 auditwheel#305 中跟踪当前的实施状态。

对于 Python 3,你的包将从带有普通 pip 调用的轮子上安装:

pip install pandas numpy

从文档中:

Pip更喜欢可用的轮子。要禁用此功能,请使用 --no-binary 标志进行 pip 安装。

如果没有找到满意的轮子,pip 将默认为查找源存档。

最新更新