Инструменты установки Python: как я могу указать частный репозиторий в install_requires?

85

Я создаю setup.pyфайл для проекта, который зависит от частных репозиториев GitHub. Соответствующие части файла выглядят так:

from setuptools import setup
setup(name='my_project',
    ...,
    install_requires=[
        'public_package',
        'other_public_package',
        'private_repo_1',
        'private_repo_2',
    ],
    dependency_links=[
        'https://github.com/my_account/private_repo_1/master/tarball/',
        'https://github.com/my_account/private_repo_2/master/tarball/',
    ],
    ...,
)

Я использую setuptoolsвместо того , distutilsпотому что последнее не поддерживают install_requiresи dependency_linksаргументы за этот ответ.

Вышеупомянутый установочный файл не может получить доступ к частным репозиториям с ошибкой 404 - чего и следовало ожидать, поскольку GitHub возвращает 404 на неавторизованные запросы для частного репозитория. Однако я не могу понять, как сделать setuptoolsаутентификацию.

Вот несколько вещей, которые я пробовал:

  1. Используйте git+ssh://вместо https://in, dependency_linksкак если бы я устанавливал репо с pip. Это не удается, потому что setuptools не распознает этот протокол («неизвестный тип URL: git + ssh»), хотя в документации по распространению указано, что это необходимо. То же git+httpsи git+http.

  2. https://<username>:<password>@github.com/...- до сих пор получить 404. (Этот метод не работает с curlили wgetиз командной строки либо - хотя curl -u <username> <repo_url> -O <output_file_name>делает работу.)

  3. Обновление setuptools (0.9.7) и virtualenv (1.10) до последних версий. Также попытался установить дистрибутив, хотя в этом обзоре говорится, что он был снова объединен с setuptools. В любом случае, никаких кубиков.

В настоящее время я только что setup.pyраспечатал предупреждение о том, что частные репозитории необходимо загружать отдельно. Это явно далеко не идеально. Я чувствую, что мне не хватает чего-то очевидного, но не могу представить, что это могло быть. :)

Дубликат иш вопрос, без ответа здесь .

Эрик П.
источник
Пожалуйста, примите решение.
wieczorek1990

Ответы:

69

Я пытался заставить это работать для установки с помощью pip, но вышеуказанное не сработало для меня. Из [1] я понял, что PEP508следует использовать стандарт, из [2] я получил пример, который действительно работает (по крайней мере, для моего случая).

Пожалуйста, обратите внимание; это с pip 20.0.2наPython 3.7.4

setup(
    name='<package>',
...
    install_requires=[
        '<normal_dependency>',
         # Private repository
        '<dependency_name> @ git+ssh://git@github.com/<user>/<repo_name>@<branch>',
         # Public repository
        '<dependency_name> @ git+https://github.com/<user>/<repo_name>@<branch>',
    ],
)

После указания моего пакета установка работает нормально (также с -eнастройками и без необходимости указывать --process-dependency-links).

Ссылки [1] https://github.com/pypa/pip/issues/4187 [2] https://github.com/pypa/pip/issues/5566

Том Хеммс
источник
Теперь эта #egg=...часть кажется ненужной.
Хуазуо Гао
1
Благодаря! Вы абсолютно правы, и то, #eggи другое branchнеобязательно (см. Править), и это тоже работает git+https.
Tom Hemmes
1
Если вы используете ssh://и бегите Could not resolve hostnameизменить , :чтобы /в вашем клоне ссылке. У меня была эта ошибка с gitlab.
Delivejati
11
Кажется, это больше не работает, поскольку кажется, что setuptools ищет пакет на PyPi с именем зависимости:, Reading https://pypi.org/simple/some-fake-name/а затем Couldn't find index page for 'some_fake_name' (maybe misspelled?). В конце концов, последняя отображаемая ошибкаerror: Could not find suitable distribution for Requirement.parse('some_fake_name@ git+ssh://git@github.com/cglacet/quadtree.git')
cglacet
1
Подчеркните, что <dependency_name> - это не то же самое, что <repo_name> И вы можете заменить 'ssh: // git @' на 'https: //', если это публичное репо
Фил П.
41

Вот что у меня сработало:

  install_requires=[
      'private_package_name==1.1',
  ],
  dependency_links=[
      'git+ssh://git@github.com/username/private_repo.git#egg=private_package_name-1.1',
  ]

Обратите внимание, что в названии яйца должен быть номер версии, иначе он скажет, что не может найти пакет.

вадимг
источник
3
Привет, vadimg - Какую версию setuptools / distribute вы используете? Я получаю "Unknown url type: git + ssh", используя distribute 0.7.3 (последняя версия).
Эрик П.
2
У меня это не сработало 3 года спустя ... Получил: Не удалось найти версию, которая удовлетворяет требованиям
jsmedmar
7
По состоянию на 28 октября 2016 г. этот подход кажется неработоспособным
Макс
1
С современными пипсами вам нужно включить опцию, что-то вродеpip install --process-dependency-links ...
Эш Берлин-Тейлор
2
--process-dpendency-linksустарел, см. мой ответ с использованием спецификации URL-адреса PEP508
Tom Hemmes
10

Я не смог найти никакой хорошей документации по этому поводу, но нашел решение в основном методом проб и ошибок. Кроме того, установка из pip и setuptools имеет некоторые тонкие различия; но этот способ должен работать для обоих.

GitHub (в настоящее время, по состоянию на август 2016 года) не предлагает простой способ получить zip / tarball с частными репозиториями. Итак, вам нужно указать setuptools, чтобы сообщить setuptools, что вы указываете на репозиторий git:

from setuptools import setup
import os
# get deploy key from https://help.github.com/articles/git-automation-with-oauth-tokens/
github_token = os.environ['GITHUB_TOKEN']

setup(
    # ...
    install_requires='package',
    dependency_links = [
    'git+https://{github_token}@github.com/user/{package}.git/@{version}#egg={package}-0'
        .format(github_token=github_token, package=package, version=master)
        ] 

Пара замечаний здесь:

  • Для частных репозиториев вам необходимо пройти аутентификацию с помощью GitHub; Самый простой способ, который я нашел, - создать токен oauth, поместить его в свою среду, а затем включить его с URL-адресом
  • Вы должны включить некоторый номер версии (здесь 0) в конце линии, даже если нет пакета на PyPI. Это должно быть настоящее число, а не слово.
  • Вам нужно git+указать в начале, чтобы указать setuptools, что он клонирует репо, а не указывает на zip / tarball.
  • version может быть веткой, тегом или хешем фиксации
  • Вам необходимо поставить --process-dependency-linksпри установке из pip
Максимилиан
источник
Я получаю сообщение о невозможности найти тег или ветку. Несмотря на то, что частное репо, которое я пытаюсь клонировать, имеет тег.
trendsetter37
1
разобрался, в чем проблема. В vгитхабе к тегу добавлен тег . Поэтому мне нужно было использовать v1.1.0вместо этого 1.1.0в моем скрипте setup.py.
trendsetter37
4

Я нашел (хакерский) обходной путь:

#!/usr/bin/env python

from setuptools import setup
import os

os.system('pip install git+https://github-private.corp.com/user/repo.git@master')

setup( name='original-name'
     , ...
     , install_requires=['repo'] )

Я понимаю, что есть этические проблемы с использованием системного вызова в сценарии установки, но я не могу придумать другого способа сделать это.

cjohnson318
источник
да, это тоже был уродливый обходной путь для нас из-за следующего: github.com/pypa/pip/issues/2822
Tommy
Это единственный способ заставить его работать, хотя я согласился import pip. Ни ответ @ vadimg, ни это предложение в pypa / pip не сработали.
gens
5
Это установит зависимость, даже если запущено что-то, не связанное с установкой, например python setup.py --version.
WhyNotHugo
1

Через ответ Тома Хеммеса я обнаружил, что это единственное, что сработало для меня:

    install_requires=[
        '<package> @ https://github.com/<username>/<package>/archive/<branch_name>.zip']
PidgeyBE
источник
0

Использование URL-адреса архива из github работает для меня для общедоступных репозиториев. Например

dependency_links = [
  'https://github.com/username/reponame/archive/master.zip#egg=eggname-version',
]
Разогнан
источник
Как найти eggname-version?
cglacet
-1

Изменить: похоже, это работает только с общедоступными репозиториями github, см. Комментарии.

dependency_links=[
    'https://github.com/my_account/private_repo_1/tarball/master#egg=private_repo_1',
    'https://github.com/my_account/private_repo_2/tarball/master#egg=private_repo_2',
],

Вышеупомянутый синтаксис, кажется, работает для меня с setuptools 1.0. На данный момент, по крайней мере, синтаксис добавления "# egg = project_name-version" к зависимостям VCS задокументирован в ссылке, которую вы дали для распространения документации .

Wor
источник
Я по-прежнему получаю ту же ошибку 404. Являются ли репо в вашем случае конфиденциальными? Я знаю синтаксис # egg =, но не знаю, влияет ли он на аутентификацию.
Eric P
Извините, конечно, это был публичный репо-проект. Вероятно, нет никакого способа сделать это с текущими инструментами настройки, если URL-адреса https // <username>: <password> @ ... tarball не работают с частными репозиториями githubs, поскольку этот вопрос, похоже, также указывает: has-Trouble -download -git-archive-tarballs-from-private-repo
Wor
Вы также можете попробовать разрабатываемую версию setuptools и / или проверить код. Соответствующий код выглядит так : package_index: fetch_distribution (): 534 package_index.py:_download_url():736
Wor
-2

Это работа для нашего сценария:

  1. пакет находится на github в частном репо
  2. мы хотим установить его в пакеты сайтов (не в ./src с -e)
  3. возможность использовать pip install -r requirements.txt
  4. возможность использовать pip install -e reposdir (или из github), где зависимости указаны только в requirements.txt

https://github.com/pypa/pip/issues/3610#issuecomment-356687173

Котрфа
источник