So schreiben Sie setup.py, um ein Git-Repo als Abhängigkeit einzuschließen


98

Ich versuche setup.pyfür mein Paket zu schreiben . Mein Paket muss eine Abhängigkeit von einem anderen Git-Repo angeben.

Das habe ich bisher:

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

Wenn ich renne:

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

Ich bekomme

Es konnte keine Version gefunden werden, die die Anforderung SomePrivateLib> = 0.1.0 (aus Analyse) (aus Versionen :) erfüllt. Für SomePrivateLib> = 0.1.0 (aus Analyse) wurde keine übereinstimmende Verteilung gefunden.

Was mache ich falsch ?


Beachten Sie, dass setup.py und pip völlig unterschiedliche Systeme sind. Ein Problem, das ich hatte, war, dass ich dies für pip zum Laufen bringen konnte, aber nicht für setup.py.
— Vieh

Antworten:


51

Den richtigen Weg dazu finden Sie hier .

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

Der Schlüssel ist nicht, einen Link zu einem Git-Repository zu geben, sondern einen Link zu einem Tarball. Github erstellt für Sie einen Tarball des Hauptzweigs, wenn Sie /tarball/masterwie oben gezeigt anhängen .


17
Es sieht so aus, als ob diese Methode per github.com/pypa/pip/issues/3939
— muon

3
Diese Methode ist auch für private Repositorys nutzlos, da keine Authentifizierung möglich ist.
— Tedivm

3
Ich habe es geschafft, es zum Laufen zu bringen und habe eine weitere Antwort hinzugefügt.
— Tedivm

1
Die /tarball/masterMethode funktioniert nicht für Gitlab
— Martin Thoma

5
Veraltet. Die richtige Antwort ist die Verwendung von Pep508, beantwortet von @Dick Fox unten
— SwimBikeRun

111

Nachdem ich das von @muon in den obigen Kommentaren verknüpfte Pip-Problem 3939 und dann die PEP-508-Spezifikation durchgearbeitet hatte , fand ich Erfolg darin, meine private Repo-Abhängigkeit setup.pymithilfe dieses Spezifikationsmusters in install_requires(nicht mehr dependency_links) zu installieren :

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

Das @v1.1gibt das auf github erstellte Release-Tag an, das durch einen Zweig, ein Commit oder einen anderen Tag-Typ ersetzt werden kann.


Hinweis: Dies funktioniert gut für lokale / private Pakete. Sie können jedoch kein Paket für PyPI freigeben, das diese Syntax in seiner setup.py verwendet
— Brian

7
@Brian Könnten Sie bitte einen Link zur offiziellen Erklärung angeben?
— Elefant

12
Beachten Sie, git+https://github.comdass Sie dies tun können, wenn Sie SSH nicht verwenden möchten.
— Multithr3at3d

2
Was ist der richtige Ansatz für ein --upgrade? Obwohl ich eine Tag-Version spezifiziere, ignoriert ein Upgrade nur neuere Tag-Versionen
— Piacenti

1
@Elephant Nicht super offiziell, aber dies sind zumindest Kommentare zum Pip GitHub-Projekt von tatsächlichen Mitgliedern des PyPA: github.com/pypa/pip/issues/4187#issuecomment-415667805 und weitere Erklärungen: github.com/pypa/pip / issue / 4187 # issuecomment-415067034
— Dominick Pastore

20

Die folgende Antwort ist für Pip 19+ veraltet


Leider funktioniert die andere Antwort nicht mit privaten Repositorys, was einer der häufigsten Anwendungsfälle dafür ist. Ich habe es schließlich mit einer setup.pyDatei zum Laufen gebracht, die so aussieht:

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

Neuere Versionen von pip machen dies noch einfacher, da "dependency_links" nicht mehr benötigt werden -

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
Könnten Sie bitte -0.1näher erläutern, wofür Ihr Ansatz steht? Nehmen Sie die Versionsnummer aus einer Git-Version oder aus der setup.pyBeschreibung?
— Peteris

2
Wenn Sie in der Datei setup.py einen bestimmten Zweig oder ein bestimmtes Tag verwenden möchten, formatieren Sie die Dinge etwas anders.
— Tedivm

"Leider funktioniert die andere Antwort nicht mit privaten Repositories." Dies ist nicht mehr wahr. Fox ' Antwort funktioniert mit privatem Repo, ohne dass dependency_linksdies erforderlich ist (was veraltet ist )
— Keto,

Danke @Keto! Ich weiß nicht, warum deine Bearbeitung abgelehnt wurde, aber die Mods, aber ich habe diese Ablehnung überschrieben, um der Antwort den Verfallshinweis hinzuzufügen.
— Tedivm

3

Eine allgemeinere Antwort, um die Informationen aus der Datei Requeriments.txt zu erhalten, die ich mache:

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

Wenn Sie Ihre Pakete rekursiv installierbar machen möchten (YourCurrentPackage enthält Ihre SomePrivateLib), z. B. wenn Sie YourCurrentPackage in eine andere einbinden möchten (wie OuterPackage -> YourCurrentPackage -> SomePrivateLib), benötigen Sie beide:

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

Und stellen Sie sicher, dass Sie ein Tag mit Ihrer Versionsnummer erstellt haben.

Auch wenn Ihr Git-Projekt privat ist und Sie es im Container installieren möchten, z. B. Docker oder GitLab Runner, benötigen Sie autorisierten Zugriff auf Ihr Repo. Bitte denken Sie daran, git + https mit Zugriffstoken zu verwenden (wie bei 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

Ich war erfolgreich mit diesen 3 Optionen in Gitlab. Ich benutze Version 11 von Gitlab.

Option 1 - kein Token angegeben. Die Shell fragt nach Benutzername / Passwort.

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

Option 2 - Benutzerzugriffstoken angegeben. Token generiert über gitlab> Konto oben rechts> Einstellungen> Zugriffstoken. Erstellen Sie ein Token mit read_repository-Rechten.

Beispiel:

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

Option 3 - Token auf Repository-Ebene angegeben. Token, das generiert wird, indem Sie zu Repository> Einstellungen> Repository> Token bereitstellen gehen. Erstellen Sie von hier aus ein Token mit den Rechten read_repository.

Beispiel:

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 allen drei Fällen konnte ich einfach Folgendes tun: "SomePrivateLib @ git + https: //gitlab.server.com/abc/SomePrivateLib.git" ohne die Markierung #egg am Ende.

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.