django 如何编写setup.py以包含Git存储库作为依赖项

2cmtqfgy  于 2023-01-06  发布在  Go
关注(0)|答案(7)|浏览(112)

我正在尝试为我的包写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,
)

当我跑步时:

pip install -e https://github.abc.com/abc/myabc.git#egg=analyse

我得到
找不到满足SomePrivateLib〉= 0.1.0要求的版本(来自分析)(来自版本:)未找到SomePrivateLib〉= 0.1.0的匹配分布(来自分析)
我哪里做错了?

fafcakar

fafcakar1#

在深入研究了上面注解中通过@muon链接的pip issue 3939PEP-508 specification之后,我发现使用install_requires中的以下规范模式(不再使用dependency_links),通过setup.py成功地安装了我的私有repo依赖项:

install_requires = [
  'some-pkg @ git+ssh://git@github.com/someorgname/pkg-repo-name@v1.1#egg=some-pkg',
]

@v1.1表示在github上创建的release标签,可以替换为分支、commit或其他类型的标签。

n6lpvg4x

n6lpvg4x2#

随着Python的发展,这个答案会定期更新。滚动到底部查看最新的答案,或者通读一遍,看看它是如何发展的。
不幸的是,另一个答案不适用于私有仓库,这是最常见的用例之一,我最终使用了一个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_org/ExampleRepo.git#egg=ExampleRepo-0.1'
    ]
)

更新版本的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_org/ExampleRepo.git#egg=ExampleRepo-0.1'
    ]
)

然而,使用最新的pip,你会遇到EGG格式处理程序的问题,这是因为当egg被忽略时,pip现在正在进行直接的URL匹配,并会认为两个URL,一个有egg片段,另一个没有,是完全不同的版本,即使它们指向同一个包。

2021年6月-setup.py

因此,从Github添加一个依赖项到您的www.example.com的最佳方法(截至2021年6月)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
        'ExampleRepo @ git+ssh://git@github.com/example_org/ExampleRepo.git'
    ]
)

2022年2月- setup.cfg

显然,setup.py正在被弃用(尽管我猜它还会存在一段时间),而setup.cfg是新事物。

[metadata]
name = MyProject
version = 0.1.1

[options]
packages = :find

install_requires =
  ExampleRepo @ git+ssh://git@github.com/example_org/ExampleRepo.git

2022年6月16日-我的项目.toml

setup.cfg是already "pre" deprecated.,因为setuptools现在实验性地支持pyproject.toml文件。
这是未来的趋势,但由于它仍处于实验阶段,目前还不应该在真实的项目中使用。即使setup.cfg即将过时,您也应该将其用于声明格式,否则setup.py仍是未来的发展方向。当setuptools稳定了对新标准的支持后,此答案将更新。

2023年1月4日- pyproject.toml

现在可以在pyproject.toml中定义所有依赖项,其他选项(如setup.cfg)仍然有效。

[build-system]
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"

[project]
dependencies = [
    'ExampleRepo @ git+ssh://git@github.com/example_org/ExampleRepo.git',
]

[project.optional-dependencies]
dev = ['ExtraExample @ git+ssh://git@github.com/example_org/ExtraExample.git']
qcuzuvrc

qcuzuvrc3#

**注意:**此答案现已过时。请查看@Dick Fox的此答案以获取最新说明:https://stackoverflow.com/a/54794506/2272172

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

dependency_links=['http://github.com/user/repo/tarball/master#egg=package-1.0']

关键不是给予一个Git仓库的链接,而是一个tarball的链接。如果你如上所示添加/tarball/master,GitHub会为你创建一个master分支的tarball。

ao218c7q

ao218c7q4#

更一般的回答是:要从 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,
)
ercv8c1e

ercv8c1e5#

实际上,如果你想让你的包可以递归安装(YourCurrentPackage包含你的SomePrivateLib),例如当你想把YourCurrentPackage包含到另一个包中(像OuterPackage → YourCurrentPackage → SomePrivateLib),你需要这两个包:

install_requires=[
    ...,
    "SomePrivateLib @ git+ssh://github.abc.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib"
],
dependency_links = [
    "git+ssh://github.abc.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib"
]

并确保您有一个使用版本号创建的标记。
另外,如果你的Git项目是私有的,并且你想把它安装在容器中,例如DockerGitLab runner,那么你需要授权访问你的仓库。请考虑使用带有访问令牌的Git + HTTPS(如GitLab:https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html):

import os
from setuptools import setup

TOKEN_VALUE = os.getenv('EXPORTED_VAR_WITH_TOKEN')

setup(
    ....

    install_requires=[
            ...,
            f"SomePrivateLib @ git+https://gitlab-ci-token:{TOKEN_VALUE}@gitlab.server.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib"
    ],
    dependency_links = [
            f"git+https://gitlab-ci-token:{TOKEN_VALUE}@gitlab.server.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib"
    ]
)

更新:

如果你想在 * requirements. txt * 文件中包含这个依赖项,你必须在依赖项行的末尾加上**#egg = SomePrivateLib**。否则pip install-r requirements. txt将不起作用,你将得到如下结果:
错误:无法检测到"git + https://gitlab-ci-token:gitlabtokenvalue@gitlab.server.com/abc/SomePrivateLib.git@0.1.0"的需求名称,请使用#egg =您的软件包名称指定一个名称
如果您使用 * reuirements. txt *,则此部分负责将在 * python_home_dir/src * 中创建的依赖项文件夹的名称以及 * site-packages/*中的egg-link的名称
您可以在 * requirements. txt * 中使用一个环境变量来将依赖项的令牌值安全地存储在存储库中:
这种情况下 * requirements. txt * 文件中的示例行:

....

-e git+https://gitlab-ci-token:${EXPORTED_VAR_WITH_TOKEN}@gitlab.server.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib
....
p1tboqfb

p1tboqfb6#

我在GitLab中成功地使用了这三个选项。我使用的是GitLab的第11版。
选项1-未指定标记。shell将提示输入用户名/密码。

from setuptools import setup

TOKEN_VALUE = os.getenv('EXPORTED_VAR_WITH_TOKEN')

setup(
    install_requires=[
        "SomePrivateLib @ git+https://gitlab.server.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib"
    ]
)

选项2-指定用户访问令牌。通过GitLab →账户右上角→设置→访问令牌生成令牌。创建具有read_repository权限的令牌。
示例:

import os
from setuptools import setup

TOKEN_VALUE = os.getenv('EXPORTED_VAR_WITH_TOKEN')

setup(
    install_requires=[
        f"SomePrivateLib @ git+https://gitlab-ci-token:{TOKEN_VALUE}@gitlab.server.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib"
    ]
)

选项3-指定了存储库级别的令牌。通过进入存储库→设置→存储库→部署令牌来生成令牌。从这里,创建一个具有read_repository权限的令牌。
示例:

import os
from setuptools import setup

TOKEN_USER = os.getenv('EXPORTED_TOKEN_USER')
TOKEN_VALUE = os.getenv('EXPORTED_VAR_WITH_TOKEN')

setup(
    install_requires=[
        f"SomePrivateLib @ git+https://{TOKEN_USER}:{TOKEN_VALUE}@gitlab.server.com/abc/SomePrivateLib.git@0.1.0#egg=SomePrivateLib"
    ]
)

In all three, I was able to do simply: "SomePrivateLib @ git+https://gitlab.server.com/abc/SomePrivateLib.git" without the #egg marking at the end.

krcsximq

krcsximq7#

当我运行python www.example.com install时,这个解决方案对我有效setup.py:

setuptools.setup(
    ...,
    install_requires=[
        'numpy',
        'pandas',
        'my_private_pkg'
        ],
    dependency_links=["git+https://github.com/[username]/[my_private_pkg].git@main#egg=my_private_pkg"],
    ...
)

相关问题