Python setuptools: Jak mogę wyświetlić prywatne repozytorium w install_requires?

85

Tworzę setup.pyplik dla projektu, który zależy od prywatnych repozytoriów GitHub. Odpowiednie części pliku wyglądają następująco:

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

Używam setuptoolszamiast, distutilsponieważ ten ostatni nie obsługuje argumentów install_requiresi dependency_linksna odpowiedź.

Powyższy plik instalacyjny nie uzyskuje dostępu do prywatnych repozytoriów z błędem 404 - czego należy się spodziewać, ponieważ GitHub zwraca 404 do nieautoryzowanych żądań prywatnego repozytorium. Jednak nie mogę dowiedzieć się, jak dokonać setuptoolsuwierzytelnienia.

Oto kilka rzeczy, które wypróbowałem:

  1. Użyj git+ssh://zamiast https://in, dependency_linkstak jak w przypadku instalowania repozytorium z pip. Nie udaje się to, ponieważ setuptools nie rozpoznaje tego protokołu („nieznany typ adresu URL: git + ssh”), chociaż dokumentacja dystrybucji mówi, że powinien. Jak wyżej git+httpsi git+http.

  2. https://<username>:<password>@github.com/...- jeszcze dostać 404. (ta metoda nie działa z curllub wgetz linii poleceń albo - choć curl -u <username> <repo_url> -O <output_file_name>nie działa).

  3. Aktualizacja setuptools (0.9.7) i virtualenv (1.10) do najnowszych wersji. Próbowałem również zainstalować dystrybucję, chociaż w tym przeglądzie stwierdzono, że została ona ponownie scalona z narzędziami instalacyjnymi. Tak czy inaczej, bez kości.

Obecnie właśnie setup.pywydrukowałem ostrzeżenie, że prywatne repozytoria należy pobrać osobno. To jest oczywiście mniej niż idealne. Czuję, że jest coś oczywistego, czego mi brakuje, ale nie mogę pomyśleć, co to może być. :)

Zduplikowane pytanie bez odpowiedzi tutaj .

Eric P.
źródło
Proszę, zaakceptuj rozwiązanie.
wieczorek1990

Odpowiedzi:

69

Próbowałem zmusić to do zainstalowania za pomocą pip, ale powyższe nie działało dla mnie. Z [1] zrozumiałem, że PEP508należy zastosować standard, z [2] wyszukałem przykład, który faktycznie działa (przynajmniej w moim przypadku).

Proszę zanotować; to jest pip 20.0.2włączonePython 3.7.4

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

Po określeniu mojego pakietu w ten sposób instalacja działa dobrze (również z -eustawieniami i bez potrzeby określania --process-dependency-links).

Źródła [1] https://github.com/pypa/pip/issues/4187 [2] https://github.com/pypa/pip/issues/5566

Tom Hemmes
źródło
Ta #egg=...część wydaje się teraz niepotrzebna.
Huazuo Gao
1
Dzięki! Masz absolutną rację, jedno #eggi drugie branchjest opcjonalne (patrz edycja) i działa również w przypadku git+https.
Tom Hemmes
1
Jeśli używasz ssh://i napotkasz Could not resolve hostnamezmieniana jest :, aby /w swoim klonie URL. Miałem ten błąd w gitlab.
delijati
11
Wydaje się, że to już nie działa, ponieważ setuptools wydaje się szukać pakietu na PyPi o nazwie zależności:, Reading https://pypi.org/simple/some-fake-name/a następnie Couldn't find index page for 'some_fake_name' (maybe misspelled?). Ostatecznie ostatni wyświetlany błąd toerror: Could not find suitable distribution for Requirement.parse('some_fake_name@ git+ssh://[email protected]/cglacet/quadtree.git')
cglacet
1
Podkreśl, że <dependency_name> to nie to samo co <repo_name> ORAZ możesz zamienić „ssh: // git @” na „https: //”, jeśli jest to publiczne repozytorium
Phil P
41

Oto, co zadziałało dla mnie:

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

Zauważ, że musisz mieć numer wersji w nazwie jajka, w przeciwnym razie powie, że nie może znaleźć pakietu.

vadimg
źródło
3
Cześć vadimg - Z której wersji setuptools / Distribute korzystasz? Otrzymuję komunikat „Nieznany typ adresu URL: git + ssh” przy użyciu dystrybucji 0.7.3 (najnowsza wersja).
Eric P
2
To nie zadziałało 3 lata później ... Dostałem: Nie mogłem znaleźć wersji spełniającej wymagania
jsmedmar
7
Od 28 października 2016 r. To podejście wydaje się zepsute
maks.
1
Z nowoczesnymi pipami musisz dodać opcję, na przykładpip install --process-dependency-links ...
Ash Berlin-Taylor
2
--process-dpendency-linksjest przestarzały, zobacz moją odpowiedź przy użyciu specyfikacji adresu URL PEP508
Tom Hemmes,
10

Nie mogłem znaleźć żadnej dobrej dokumentacji na ten temat, ale natknąłem się na rozwiązanie głównie metodą prób i błędów. Co więcej, instalacja z pip & setuptools ma pewne subtelne różnice; ale ten sposób powinien działać dla obu.

GitHub nie oferuje (obecnie, stan na sierpień 2016 r.) Łatwego sposobu na pobranie archiwum ZIP / tarball z prywatnych repozytoriów. Musisz więc wskazać setuptools, aby poinformować setuptools, że wskazujesz repozytorium 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)
        ] 

Kilka uwag:

  • W przypadku prywatnych repozytoriów musisz uwierzytelnić się w GitHub; najprostszym sposobem, jaki znalazłem, jest utworzenie tokena OAuth, upuszczenie go w swoim środowisku, a następnie dołączenie go do adresu URL
  • Trzeba podać jakiś numer wersji (Oto 0) na końcu łącza, nawet jeśli nie ma pakiet na PyPI. To musi być rzeczywista liczba, a nie słowo.
  • Musisz git+poprzedzić słowo, aby powiedzieć setuptools, że ma sklonować repozytorium zamiast wskazywać na plik zip / tarball
  • version może być gałęzią, znacznikiem lub hashem zatwierdzenia
  • Musisz dostarczyć, --process-dependency-linksjeśli instalujesz z pip
Maksymiliana
źródło
Otrzymuję komunikat „Nie można znaleźć tagu lub gałęzi”. Pomimo faktu, że prywatne repozytorium, które próbuję sklonować, ma tag.
trendsetter37
1
zorientowałem się, na czym polega problem. Tag miał vprzedrostek na githubie. Więc musiałem użyć v1.1.0zamiast 1.1.0w moim skrypcie setup.py.
trendsetter37
4

Znalazłem (hacky) obejście:

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

Rozumiem, że istnieją problemy etyczne z wywołaniem systemowym w skrypcie konfiguracyjnym, ale nie mogę wymyślić innego sposobu, aby to zrobić.

cjohnson318
źródło
tak, to również było dla nas brzydkie obejście, ponieważ: github.com/pypa/pip/issues/2822
Tommy,
To jedyny sposób, w jaki mogłem go uruchomić, chociaż poszedłem z import pip. Ani odpowiedź @ vadimg, ani ta sugestia w pypa / pip nie zadziałały.
ród
4
Spowoduje to zainstalowanie zależności, nawet jeśli uruchomisz coś niezwiązanego z instalacją, np python setup.py --version.
WhyNotHugo,
1

Dzięki odpowiedzi Toma Hemmesa stwierdziłem, że jest to jedyna rzecz, która działa dla mnie:

    install_requires=[
        '<package> @ https://github.com/<username>/<package>/archive/<branch_name>.zip']
PidgeyBE
źródło
0

Użycie adresu URL archiwum z github działa dla mnie w przypadku repozytoriów publicznych. Na przykład

dependency_links = [
  'https://github.com/username/reponame/archive/master.zip#egg=eggname-version',
]
Podkręcony
źródło
Jak znajdujesz eggname-version?
cglacet
-1

Edycja: wydaje się, że działa tylko z publicznymi repozytoriami github, zobacz komentarze.

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

Powyższa składnia wydaje mi się działać z setuptools 1.0. W tej chwili przynajmniej składnia dodawania "# egg = nazwa_projektu-wersja" do zależności VCS jest udokumentowana w linku, który podałeś do dystrybucji dokumentacji .

wor
źródło
Nadal otrzymuję ten sam błąd 404. Czy repozytoria w Twoim przypadku są prywatne? Znam składnię # egg =, ale nie wiem, czy ma ona wpływ na uwierzytelnianie.
Eric P
Przepraszamy, to oczywiście był projekt repozytorium publicznego. Prawdopodobnie nie ma sposobu, aby to zrobić z obecnymi narzędziami konfiguracyjnymi, jeśli https // <nazwa użytkownika>: <hasło> @ ... adresy URL archiwum nie działają z prywatnymi repozytoriami github, ponieważ to pytanie wydaje się również wskazywać: problem z pobieraniem -git-archive-tarballs-from-private-repo
wor
Możesz także wypróbować wersję rozwojową setuptools i / lub sprawdzić kod. Wydaje się, że odpowiedni kod to: package_index: fetch_distribution (): 534 package_index.py:_download_url():736
wor
-2

Ta praca dla naszego scenariusza:

  1. pakiet jest na github w prywatnym repozytorium
  2. chcemy zainstalować go w pakietach witryn (nie w ./src z -e)
  3. możliwość korzystania z pip install -r Requirements.txt
  4. możliwość korzystania z pip install -e reposdir (lub z github), gdzie zależności są określone tylko w Requirements.txt

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

kotrfa
źródło