如何编写setup.py以包含git repo作为依赖项

Ank*_*wal 61 python git django packaging setuptools

我正在尝试为我的包编写setup.py.我的包需要指定对另一个git仓库的依赖.

这是我到目前为止:

from setuptools import setup, find_packages

setup(
    name='abc',
    packages=find_packages(),
    url='https://github.abc.com/abc/myabc',
    description='This is a description for abc',
    long_description=open('README.md').read(),
    install_requires=[
        "requests==2.7.0",
        "SomePrivateLib>=0.1.0",
        ],
    dependency_links = [
     "git+git://github.abc.com/abc/SomePrivateLib.git#egg=SomePrivateLib",
    ],
    include_package_data=True,
)
Run Code Online (Sandbox Code Playgroud)

当我跑:

pip install -e https://github.abc.com/abc/myabc.git#egg=analyse
Run Code Online (Sandbox Code Playgroud)

我明白了

找不到满足要求的版本SomePrivateLib> = 0.1.0(来自analyze)(来自版本:)未找到SomePrivateLib的匹配分布> = 0.1.0(来自analyze)

我究竟做错了什么 ?

Dic*_*Fox 52

在通过上面的评论中由@muon链接的pip问题3939PEP-508规范进行深入研究之后,我发现通过setup.py使用以下规范模式来安装我的私有repo依赖项是成功的install_requires(没有更多内容dependency_links):

install_requires = [
  'some-pkg @ git+ssh://git@github.com/someorgname/pkg-repo-name@v1.1#egg=some-pkg',
]
Run Code Online (Sandbox Code Playgroud)

@v1.1指示在GitHub上创建的发布标志,并可以用一个分支,提交,或不同类型的标签来代替。

  • 请注意,如果您不想使用 SSH,可以执行 `git+https://github.com`。 (20认同)
  • 是否有一种协议既适用于 pip 需求文件又适用于“install_requires”?我通常使用模式 `install_requires=open("requirements.txt", "r").read().splitlines()` (4认同)
  • @Brian您能否提供官方声明的链接? (3认同)
  • 那么进行 --upgrade 的正确方法是什么?即使我指定了标签版本,升级也会忽略较新的标签版本 (3认同)
  • @Elephant 不是超级官方,但这些至少是 PyPA 实际成员对 pip GitHub 项目的评论:https://github.com/pypa/pip/issues/4187#issuecomment-415667805 和进一步的解释:https:// /github.com/pypa/pip/issues/4187#issuecomment-415067034 (2认同)
  • 在下面的答案之一中,建议删除 #egg= 部分。我需要这条信息才能使其适用于我的存储库。 (2认同)

cel*_*cel 42

你可以在这里找到正确的方法.

dependency_links=['http://github.com/user/repo/tarball/master#egg=package-1.0']
Run Code Online (Sandbox Code Playgroud)

关键是不要提供git存储库的链接,而是指向tarball的链接.如果你附加/tarball/master如上所示,Github会为你创建一个主分支的tarball .

  • 看起来这个方法根据https://github.com/pypa/pip/issues/3939弃用 (8认同)
  • 已弃用。正确答案是使用 Pep508,下面由 @Dick Fox 回答 (6认同)
  • 此方法对于私有存储库也无用,因为无法进行身份验证。 (5认同)
  • 我确实设法使其正常运行,并添加了另一个答案。 (2认同)

ted*_*ivm 9

不幸的是,其他答案不适用于私有存储库,这是最常见的用例之一。我最终的确使用了如下所示的setup.py文件:

from setuptools import setup, find_packages

setup(
    name = 'MyProject',
    version = '0.1.0',
    url = '',
    description = '',
    packages = find_packages(),
    install_requires = [
        # Github Private Repository - needs entry in `dependency_links`
        'ExampleRepo'
    ],

    dependency_links=[
        # Make sure to include the `#egg` portion so the `install_requires` recognizes the package
        'git+ssh://git@github.com/example_organization/ExampleRepo.git#egg=ExampleRepo-0.1'
    ]
)
Run Code Online (Sandbox Code Playgroud)

较新版本的pip消除了使用“ dependency_links”的需要,从而使操作更加轻松-

from setuptools import setup, find_packages

setup(
    name = 'MyProject',
    version = '0.1.0',
    url = '',
    description = '',
    packages = find_packages(),
    install_requires = [
        # Github Private Repository
        'ExampleRepo @ git+ssh://git@github.com/example_organization/ExampleRepo.git#egg=ExampleRepo-0.1'
    ]
)
Run Code Online (Sandbox Code Playgroud)

  • 您能否详细说明您的方法中“-0.1”代表什么?您是否从 git 版本或“setup.py”描述中获取版本号? (2认同)
  • 从 setup.py 文件中 - 如果您想使用特定分支或标签,则格式会略有不同。 (2认同)
  • 这确实应该是最重要的答案,它实际上与当前相关。 (2认同)
  • 当运行“python setup.py install”时,这似乎不起作用 - 它只适用于“pip install -e [module_name]”。对所有人来说都是如此吗?这是在 pip 21.1.3 上 (2认同)
  • 感谢您保持最新状态! (2认同)

dar*_*orp 7

实际上,如果您想让您的软件包可递归安装(YourCurrentPackage 包括您的 SomePrivateLib),例如,当您想将 YourCurrentPackage 包含到另一个软件包中(如 OuterPackage \xe2\x86\x92 YourCurrentPackage \xe2\x86\x92 SomePrivateLib)时,您将需要两个都:

\n
install_requires=[\n    ...,\n    "SomePrivateLib @ git+ssh://github.abc.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib"\n],\ndependency_links = [\n    "git+ssh://github.abc.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib"\n]\n
Run Code Online (Sandbox Code Playgroud)\n

并确保您有一个使用您的版本号创建的标签。

\n

此外,如果您的 Git 项目是私有的,并且您希望将其安装在容器(例如DockerGitLab运行程序)内,则您将需要对存储库的授权访问权限。请考虑使用带有访问令牌的 Git + HTTPS(例如在 GitLab 上: https: //docs.gitlab.com/ee/user/profile/personal_access_tokens.html):

\n
import os\nfrom setuptools import setup\n\nTOKEN_VALUE = os.getenv(\'EXPORTED_VAR_WITH_TOKEN\')\n\nsetup(\n    ....\n\n    install_requires=[\n            ...,\n            f"SomePrivateLib @ git+https://gitlab-ci-token:{TOKEN_VALUE}@gitlab.server.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib"\n    ],\n    dependency_links = [\n            f"git+https://gitlab-ci-token:{TOKEN_VALUE}@gitlab.server.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib"\n    ]\n)\n
Run Code Online (Sandbox Code Playgroud)\n

更新:

\n

如果您希望在requirements.txt文件中包含此依赖项,则必须将#egg=SomePrivateLib放在依赖项行的末尾。否则pip install -rrequirements.txt不会为你工作,你会得到类似的东西:

\n
\n

错误:无法检测\n\'git+https://gitlab-ci-token:gitlabtokenvalue@gitlab.server.com/abc/SomePrivateLib.git@0.1.0\'的需求名称,\n请用 # 指定一个鸡蛋=你的包名称

\n
\n

如果您使用reuirements.txt ,此部分负责将在python_home_dir/src内创建的 dependency\xe2\x80\x99s 文件夹的名称以及site-packages/中的 Egg-link 的名称

\n

您可以使用requirements.txt中的环境变量将您的 dependency\xe2\x80\x99s 令牌值安全地存储在您的存储库中:

\n

本例的requests.txt文件中的示例行:

\n
....\n\n-e git+https://gitlab-ci-token:${EXPORTED_VAR_WITH_TOKEN}@gitlab.server.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib\n....\n
Run Code Online (Sandbox Code Playgroud)\n


Gon*_*ard 5

更一般的答案:要从requirements.txt文件中获取信息,我会执行以下操作:

from setuptools import setup, find_packages
from os import path

loc = path.abspath(path.dirname(__file__))

with open(loc + '/requirements.txt') as f:
    requirements = f.read().splitlines()

required = []
dependency_links = []

# Do not add to required lines pointing to Git repositories
EGG_MARK = '#egg='
for line in requirements:
    if line.startswith('-e git:') or line.startswith('-e git+') or \
            line.startswith('git:') or line.startswith('git+'):
        line = line.lstrip('-e ')  # in case that is using "-e"
        if EGG_MARK in line:
            package_name = line[line.find(EGG_MARK) + len(EGG_MARK):]
            repository = line[:line.find(EGG_MARK)]
            required.append('%s @ %s' % (package_name, repository))
            dependency_links.append(line)
        else:
            print('Dependency to a git repository should have the format:')
            print('git+ssh://git@github.com/xxxxx/xxxxxx#egg=package_name')
    else:
        required.append(line)

setup(
    name='myproject',  # Required
    version='0.0.1',  # Required
    description='Description here....',  # Required
    packages=find_packages(),  # Required
    install_requires=required,
    dependency_links=dependency_links,
)
Run Code Online (Sandbox Code Playgroud)