如何`pip install` 一个具有 Git 依赖项的包?

Posted

技术标签:

【中文标题】如何`pip install` 一个具有 Git 依赖项的包?【英文标题】:How to `pip install` a package that has Git dependencies? 【发布时间】:2016-08-01 09:06:18 【问题描述】:

我有一个名为 some-library 的私有库(实际名称已更改),其安装文件看起来像这样:

setup(
    name='some-library',

    // Omitted some less important stuff here...

    install_requires=[
        'some-git-dependency',
        'another-git-dependency',
    ],
    dependency_links=[
        'git+ssh://git@github.com/my-organization/some-git-dependency.git#egg=some-git-dependency',
        'git+ssh://git@github.com/my-organization/another-git-dependency.git#egg=another-git-dependency',
    ],
)

所有这些 Git 依赖项可能都是私有的,所以 installation via HTTP 不是一个选项。我可以在some-library 的根目录中使用python setup.py installpython setup.py develop 没有问题。

但是,通过 Git 安装不起作用:

pip install -vvv -e 'git+ssh://git@github.com/my-organization/some-library.git@1.4.4#egg=some-library'

该命令在查找some-git-dependency 时失败,错误地认为它需要从 PyPI 获取依赖项,然后在断定它不在 PyPI 上后失败。我的第一个猜测是尝试使用--process-dependency-links 重新运行命令,但后来发生了这种情况:

   Cannot look at git URL git+ssh://git@github.com/my-organization/some-git-dependency.git#egg=some-git-dependency
   Could not find a version that satisfies the requirement some-git-dependency (from some-library) (from versions: )

为什么会产生这个模糊的错误? pip install 具有可能是私有的 Git 依赖项的包的正确方法是什么?

【问题讨论】:

你试过--process-dependency-links --allow-all-external. 【参考方案1】:

“无法查看 git URL git+ssh://git@github.com/my-organization/some-git-dependency.git#egg=some-git-dependency” 表示@ 987654322@ 无法从该 url 获取 html 页面以查找页面中的直接下载链接,即,pip 无法将该 URL 识别为 vcs 结帐,因为可能在需求说明符和片段部分之间存在一些差异vcs 网址。

在 VCS 结帐的情况下,您还应该附加 #egg=project-version 以确定应该为哪个包使用该结帐。

请务必将名称或版本中的任何破折号替换为下划线。

查看Dependencies that aren’t in PyPI

将包和版本字符串中的- 替换为_

git+ssh://git@github.com/my-organization/some-git-dependency.git#egg=some_git_dependency  

--allow-all-external 可能有用。

【讨论】:

【参考方案2】:

使用可能是私有的 Git 依赖项 pip 安装包的正确方法是什么?

两种选择

    像你一样使用dependency_links。详情见下文。

    除了 setup.py 中的 dependency_links,使用一个特殊的 dependency-links.txt 来收集所有必需的包。然后在 requirements.txt 中添加这个包。这是我的推荐选项,如下所述。

    # dependency-links.txt
    git+ssh://...@tag#egg=package-name1
    git+ssh://...@tag#egg=package-name2
    # requirements.txt (per deployed application)
    -r dependency-links.txt
    

虽然选项 2 增加了包管理的一些额外负担,即保持 dependency-links.txt 最新,但它使安装包变得更加容易,因为您可以'忘记在 pip install 上添加 --process-dependency-link 选项。

也许更重要的是,使用dependency-links.txt,您可以指定要在部署时安装的确切版本,这是您在CI/CD环境中想要的——没有什么比安装风险更大的了some 版本。然而,从包维护者的角度来看,指定最低版本是很常见的,并且被认为是一种很好的做法,例如

    # setup.py in a package
    ...
       install_requires = [ 'foo>1.0', ... ]

这很棒,因为它使您的包可以很好地与具有相似依赖关系但可能在不同版本上的其他包一起工作。但是,在已部署的应用程序中,如果包之间存在冲突的需求,这仍然会造成混乱。例如。包 A 可以使用 foo>1.0,包 B 需要 foo<=1.5,最新版本是 foo==2.0。使用dependency-links.txt,您可以具体,为所有包应用一个版本:

    # dependency-links.txt
    foo==1.5

该命令在查找 some-git-dependency 时失败,

要使其工作,您需要添加--process-dependency-links 以便 pip 识别对 github 的依赖,例如

pip install --process-dependency-links -r private-requirements.txt

注意,由于pip 8.1.0,您可以将此选项添加到 requirements.txt。不利的一面是,它适用于 所有 已安装的软件包,并可能产生意想不到的后果。也就是说,我发现使用dependency-links.txt 是一种更安全、更易于管理的解决方案。

所有这些 Git 依赖项都可能是私有的

共有三个选项:

    在每个所需包的存储库中添加协作者。这些合作者需要在 github 上设置他们的 ssh 密钥才能正常工作。然后使用git+ssh://...

    为每个存储库添加一个部署密钥。这里的缺点是你需要将对应的私钥分发到所有需要部署的机器上。再次使用git+ssh://...

    在包含私有存储库的 github 帐户上添加个人访问令牌。然后你可以使用git+https://accesstoken@github.com/... 缺点是访问令牌将具有对相应github帐户上所有公共和私有存储库的读+写访问权限。从好的方面来说,不再需要分发和管理每个存储库的私钥,并且循环使用密钥要简单得多。在每个开发人员都可以访问所有存储库的全内部环境中,我发现这对每个人来说都是最有效、最轻松的方式。 YMMV

【讨论】:

感谢您的详尽解释! 这是否意味着pip 不能在没有 requirements.txt 的情况下处理 dependency_links?如果是,pip 是否与setuptools 不兼容? OP 说easy_install 有,pip 没有。 @NizamMohamed 你可以pip install --process-dependency-links whatever-package 它会正常工作。 pip 的主要目的是从官方 pypi 存储库安装,因此默认情况下不处理依赖链接。 过时了。不再工作了。 --process-dependency-links 已被弃用。【参考方案3】:

url 和#egg 一起使用时应该使用 git+git,如下所示:

-e git+git@repo.some.la:foo/my-repo.git#egg=my-repo

在生产中使用 git+ssh 不用#egg,但你可以指定@version 或分支@master

git+ssh://git@repo.some.la/foo/my-repo.git@1.1.6

对于应用程序版本,请使用 git 标记 Git Basics - Tagging

【讨论】:

这对我不起作用。另外,我不想在可编辑模式下安装这些依赖项。【参考方案4】:

这也适用于私有存储库:

dependency_links = [
     'git+ssh://git@github.com/my-organization/some-git-dependency.git@master#egg=some-git-dependency',
     'git+ssh://git@github.com/my-organization/another-git-dependency.git@master#egg=another-git-dependency'
],

【讨论】:

显式添加 @master 对我没有用。查看详细日志,现在甚至没有提到 Git 存储库。只有这个:Collecting some-git-dependency (from some-library) 1 location(s) to search for versions of some-git-dependency: * https://pypi.python.org/simple/some-git-dependency/我在 pip 8.1.1 和 setuptools 20.10.1。【参考方案5】:

如果我提到“pip install dependency links”,你不会指代 GitHub 存储库本身,而是与该 GitHub 存储库关联的 tarball 图像:

dependency_links=[
        'git+ssh://git@github.com/my-organization/some-git-dependency/tarball/master/#egg=some-git-dependency',
        'git+ssh://git@github.com/my-organization/another-git-dependency/tarball/master/#egg=another-git-dependency',
    ],

其中“some-git-dependency”是依赖项的名称*和版本。

【讨论】:

这似乎不适用于 SSH,只能通过 HTTP(S)。它需要通过 SSH 工作,因为存储库可能是私有的,我想使用 SSH 密钥进行身份验证。你能提供一个通过 SSH 的工作示例吗?

以上是关于如何`pip install` 一个具有 Git 依赖项的包?的主要内容,如果未能解决你的问题,请参考以下文章

使用 pip3 install windows 失败,错误代码 1

virtualenv pip install mysql-python 失败

配置以便 pip install 可以从 github 工作

来自私人 github 存储库的 Pip install wheel

哪些pip包可以下载sudo apt-get install python3-pip的源代码?

无法在具有 OpenSSL 1.0.2g 和 Python 2.7 的 Docker Alpine Linux 3.3 中“pip install cryptography”