Як написати setup.py, щоб включити репозиторій git як залежність


95

Я намагаюся написати 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 (з аналізу)

Що я роблю не так?


Зверніть увагу, що setup.py та pip - це абсолютно різні системи. У мене виникло одне питання - я зміг отримати цю роботу для pip, але не для setup.py.
bcattle

Відповіді:


50

Ви можете знайти правильний спосіб зробити це тут .

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

Ключ не в тому, щоб надати посилання на сховище git, а посилання на tarball. Github створює для вас тарбол головної гілки, якщо ви додаєте, /tarball/masterяк показано вище.


17
схоже, цей метод застарілий за github.com/pypa/pip/issues/3939
muon

2
Цей метод також марний для приватних сховищ, оскільки немає можливості автентифікації.
tedivm

3
Мені вдалося змусити його працювати і додав ще одну відповідь.
tedivm

1
/tarball/masterМетод не працює для gitlab
Martin Thoma

3
Застаріле. Правильна відповідь - використовувати Pep508, на який відповів @Dick Fox нижче
SwimBikeRun

104

Після того, як копатися в проблемі 3939 пипа пов'язаний @muon в коментарях вище , а потім специфікацій PEP-508 , я знайшов успіх отримую мою залежність приватного сховища , щоб встановити через setup.pyне використовуючи цю специфікацію шаблону в install_requires(не більше dependency_links):

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

@v1.1Указует реліз тег , створений на GitHub і може бути замінено на гілки, фіксації чи інший тип тега.


Примітка: Це добре працює для локальних / приватних пакетів, однак, ви не можете випустити пакет до PyPI, який використовує цей синтаксис у своєму setup.py
Брайан,

7
@Brian Не могли б ви надати посилання на офіційну заяву?
Слон

11
Зверніть увагу, що ви можете зробити, git+https://github.comякщо не хочете використовувати SSH.
multithr3at3d

2
Тож яким є правильний підхід для здійснення --upgrade? Незважаючи на те, що я вказую версію тегу, оновлення просто ігнорує новіші версії тегів
Piacenti

1
@Elephant Не надзвичайно офіційно, але це принаймні коментарі до проекту pip GitHub від фактичних членів PyPA: github.com/pypa/pip/issues/4187#issuecomment-415667805 та подальші пояснення: github.com/pypa/pip / issues / 4187 # issuecomment-415067034
Домінік

19

Наступна відповідь застаріла для Pip 19+


На жаль, інша відповідь не працює з приватними сховищами, що є одним із найпоширеніших випадків використання для цього. Зрештою, я змусив його працювати з 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'
    ]
)

Новіші версії 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'
    ]
)

1
не могли б ви розказати, що -0.1означає ваш підхід? Чи берете ви номер версії з випуску git або з setup.pyопису?
Петеріс

2
З файлу setup.py - якщо ви хочете використовувати певну гілку або тег, ви форматуєте речі дещо інакше.
tedivm

"На жаль, інша відповідь не працює з приватними сховищами" Це вже не відповідає дійсності Відповідь Fox працює на приватному репо без необхідності dependency_links(що застаріло )
Кето,

Дякую @Keto! Я не знаю, чому ваше редагування було відхилено, але модифікації, але я продовжив і скасував це відхилення, щоб додати до відповіді повідомлення про припинення роботи.
tedivm

3

Більш загальна відповідь, щоб отримати інформацію із файлу requeriments.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+'):
        if EGG_MARK in line:
            package_name = line[line.find(EGG_MARK) + len(EGG_MARK):]
            required.append(package_name)
            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,
) 

1

Насправді, якщо ви хочете зробити свої пакунки рекурсивно встановлюваними (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 є приватним, і ви хочете встановити його всередині контейнера, наприклад Docker або GitLab 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"
    ]
)

0

Я мав успіх із цими 3 варіантами у gitlab. Я використовую версію 11 gitlab.

варіант 1 - жоден маркер не вказаний. оболонка запитає ім’я користувача / пароль.

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"
    ]
)

В усіх 3 я зміг зробити просто: "SomePrivateLib @ git + https: //gitlab.server.com/abc/SomePrivateLib.git" без позначення #egg в кінці.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.