Python setuptools: Wie kann ich ein privates Repository unter install_requires auflisten?


83

Ich erstelle eine setup.pyDatei für ein Projekt, das von privaten GitHub-Repositorys abhängt. Die relevanten Teile der Datei sehen folgendermaßen aus:

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/',
    ],
    ...,
)

Ich verwende setuptoolsanstelle von, distutilsweil letzteres die install_requiresund dependency_linksArgumente gemäß dieser Antwort nicht unterstützt .

Die obige Setup-Datei greift nicht mit einem 404-Fehler auf die privaten Repos zu - was zu erwarten ist, da GitHub einen 404 an nicht autorisierte Anforderungen für ein privates Repository zurückgibt. Ich kann jedoch nicht herausfinden, wie ich mich setuptoolsauthentifizieren soll.

Hier sind einige Dinge, die ich versucht habe:

  1. Verwenden Sie git+ssh://statt https://in dependency_linkswie bei der Installation des Repos mit pip. Dies schlägt fehl, weil setuptools dieses Protokoll nicht erkennt ("unbekannter URL-Typ: git + ssh"), obwohl die Distributionsdokumentation dies vorschreibt . Ditto git+httpsund git+http.

  2. https://<username>:<password>@github.com/...- Erhalte immer noch eine 404. (Diese Methode funktioniert auch nicht mit curloder wgetüber die Befehlszeile - obwohl curl -u <username> <repo_url> -O <output_file_name>sie funktioniert.)

  3. Aktualisieren von setuptools (0.9.7) und virtualenv (1.10) auf die neuesten Versionen. Ich habe auch versucht, Distribute zu installieren, obwohl diese Übersicht besagt, dass es wieder in Setuptools zusammengeführt wurde. So oder so, keine Würfel.

Derzeit habe ich nur setup.pyeine Warnung ausgedruckt, dass die privaten Repos separat heruntergeladen werden müssen. Dies ist offensichtlich nicht ideal. Ich habe das Gefühl, dass etwas Offensichtliches fehlt, kann mir aber nicht vorstellen, was es sein könnte. :) :)

Doppelte Frage ohne Antworten hier .


Bitte akzeptieren Sie eine Lösung.
wieczorek1990

Antworten:


65

Ich habe versucht, dies für die Installation mit pip zum Laufen zu bringen, aber das oben Genannte hat bei mir nicht funktioniert. Aus [1] habe ich verstanden, dass der PEP508Standard verwendet werden sollte, aus [2] habe ich ein Beispiel abgerufen, das tatsächlich funktioniert (zumindest für meinen Fall).

Bitte beachten Sie; das ist mit pip 20.0.2aufPython 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>',
    ],
)

Nachdem Sie mein Paket auf diese Weise angegeben haben, funktioniert die Installation einwandfrei (auch mit -eEinstellungen und ohne Angabe --process-dependency-links).

Referenzen [1] https://github.com/pypa/pip/issues/4187 [2] https://github.com/pypa/pip/issues/5566


Der #egg=...Teil scheint jetzt unnötig.
Huazuo Gao

1
Vielen Dank! Sie haben absolut Recht, beide #eggund branchsind optional (siehe Bearbeiten) und es funktioniert auch für git+https.
Tom Hemmes

1
Wenn Sie ssh://in und führen Could not resolve hostnameÄnderung der :zu /Ihrer Klon URL. Ich hatte diesen Fehler mit Gitlab.
Delijati

11
Das scheint nicht mehr zu funktionieren, da setuptools auf PyPi nach einem Paket mit dem Abhängigkeitsnamen zu suchen scheint: Reading https://pypi.org/simple/some-fake-name/und dann Couldn't find index page for 'some_fake_name' (maybe misspelled?). Am Ende ist der letzte angezeigte Fehlererror: Could not find suitable distribution for Requirement.parse('some_fake_name@ git+ssh://git@github.com/cglacet/quadtree.git')
cglacet

1
Hervorheben, dass <Abhängigkeitsname> nicht mit <Repo-Name> identisch ist UND Sie 'ssh: // git @' durch 'https: //' ersetzen können, wenn es sich um ein öffentliches Repo handelt
Phil P

41

Folgendes hat bei mir funktioniert:

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

Beachten Sie, dass Sie die Versionsnummer im Eiernamen haben müssen, da sonst das Paket nicht gefunden werden kann.


3
Hallo vadimg - Welche Version von setuptools / Distribute verwenden Sie? Ich erhalte "Unbekannter URL-Typ: git + ssh" mit Distribute 0.7.3 (die neueste Version).
Eric P

2
Dies funktionierte nicht für mich 3 Jahre später ... Got: Konnte keine Version finden, die die Anforderung erfüllt
jsmedmar

7
Ab dem 28. Oktober 2016 scheint dieser Ansatz gebrochen
Max

1
Mit modernen Pip benötigen Sie eine Option , um, so etwas wiepip install --process-dependency-links ...
Ash Berlin-Taylor

2
--process-dpendency-linksist veraltet, siehe meine Antwort mit PEP508 URL-Spezifikation
Tom Hemmes

10

Ich konnte keine gute Dokumentation dazu finden, bin aber hauptsächlich durch Ausprobieren auf die Lösung gestoßen. Darüber hinaus weist die Installation von pip & setuptools einige subtile Unterschiede auf. aber dieser Weg sollte für beide funktionieren.

GitHub bietet (derzeit ab August 2016) keine einfache Möglichkeit, den Zip / Tarball von privaten Repos zu erhalten. Sie müssen also auf setuptools zeigen, um setuptools mitzuteilen, dass Sie auf ein Git-Repo zeigen:

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

Ein paar Anmerkungen hier:

  • Für private Repos müssen Sie sich bei GitHub authentifizieren. Der einfachste Weg, den ich gefunden habe, besteht darin, ein Oauth-Token zu erstellen, dieses in Ihrer Umgebung abzulegen und es dann in die URL aufzunehmen
  • Sie müssen am Ende des Links eine Versionsnummer (hier ist 0) einfügen, auch wenn auf PyPI kein Paket vorhanden ist. Dies muss eine tatsächliche Zahl sein, kein Wort.
  • Sie müssen ein Vorwort verwenden git+, um setuptools mitzuteilen, dass das Repo geklont werden soll, anstatt auf einen Reißverschluss / Tarball zu zeigen
  • version kann ein Zweig, ein Tag oder ein Commit-Hash sein
  • Sie müssen liefern, --process-dependency-linkswenn Sie von Pip installieren

Ich erhalte die Meldung Tag oder Zweig nicht gefunden. Trotz der Tatsache, dass das private Repo, das ich zu klonen versuche, ein Tag hat.
Trendsetter37

1
fand heraus, was das Problem war. Dem Tag war ein vGithub vorangestellt. Also musste ich v1.1.0statt 1.1.0in meinem setup.py-Skript verwenden.
Trendsetter37

4

Ich habe eine (hackige) Problemumgehung gefunden:

#!/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'] )

Ich verstehe, dass es ethische Probleme mit einem Systemaufruf in einem Setup-Skript gibt, aber ich kann mir keinen anderen Weg vorstellen, dies zu tun.


Ja, dies war auch eine hässliche Problemumgehung für uns aufgrund der folgenden: github.com/pypa/pip/issues/2822
Tommy

Dies ist der einzige Weg, wie ich es zum Laufen bringen kann, obwohl ich mitgemacht habe import pip. Weder die Antwort von @ vadimg noch dieser Vorschlag in pypa / pip funktionierten.
Gens

4
Dadurch wird eine Abhängigkeit installiert, selbst wenn etwas ausgeführt wird, das nichts mit der Installation zu tun hat python setup.py --version.
WhyNotHugo

1

Über die Antwort von Tom Hemmes stellte ich fest, dass dies das einzige ist, was für mich funktioniert hat:

    install_requires=[
        '<package> @ https://github.com/<username>/<package>/archive/<branch_name>.zip']

0

Die Verwendung der Archiv-URL von github funktioniert für mich in öffentlichen Repositorys. Z.B

dependency_links = [
  'https://github.com/username/reponame/archive/master.zip#egg=eggname-version',
]

Wie findest du das eggname-version?
Cglacet

-1

Bearbeiten: Dies scheint nur mit öffentlichen Github-Repositorys zu funktionieren, siehe Kommentare.

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',
],

Die obige Syntax scheint für mich mit setuptools 1.0 zu funktionieren. Derzeit ist zumindest die Syntax zum Hinzufügen von "#gg = project_name-version" zu VCS-Abhängigkeiten in dem Link dokumentiert, den Sie zum Verteilen der Dokumentation angegeben haben .


Ich erhalte immer noch den gleichen 404-Fehler. Sind die Repos in Ihrem Fall privat? Ich kenne die Syntax # ei =, weiß aber nicht, dass sie die Authentifizierung beeinflusst.
Eric P

Entschuldigung, es war natürlich ein öffentliches Repo-Projekt. Es gibt wahrscheinlich keine Möglichkeit, dies mit aktuellen Setuptools zu tun, wenn https // <Benutzername>: <Kennwort> @ ... Tarball-URLs nicht mit privaten Githubs-Repositorys funktionieren, da diese Frage auch darauf hindeutet, dass Probleme beim Herunterladen auftreten -git-archive-tarballs-from-private-repo
wor

Sie können auch die Entwicklungsversion von setuptools ausprobieren und / oder den Code überprüfen. Der relevante Code scheint zu sein: package_index: fetch_distribution (): 534 package_index.py:_download_url():736
wor

-2

Diese Arbeit für unser Szenario:

  1. Paket ist auf Github in einem privaten Repo
  2. wir wollen es in Site-Paketen installieren (nicht in ./src mit -e)
  3. in der Lage sein, pip install -r require.txt zu verwenden
  4. In der Lage sein, pip install -e reposdir (oder von github) zu verwenden, wobei die Abhängigkeiten nur in den Anforderungen.txt angegeben sind

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.