Cara menulis setup.py untuk memasukkan git repo sebagai ketergantungan

95

Saya mencoba menulis setup.pyuntuk paket saya. Paket saya perlu menentukan ketergantungan pada repo git lain.

Inilah yang saya miliki sejauh ini:

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

Saat saya lari:

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

saya mendapat

Tidak dapat menemukan versi yang memenuhi persyaratan SomePrivateLib> = 0.1.0 (dari analisis) (dari versi :) Tidak ada distribusi yang cocok untuk SomePrivateLib> = 0.1.0 (dari analisis)

Apa yang saya lakukan salah?

Ankur Agarwal
sumber
Perhatikan bahwa setup.py dan pip adalah sistem yang sepenuhnya berbeda. Satu masalah yang saya alami adalah saya bisa membuatnya berfungsi untuk pip tetapi tidak untuk setup.py.
bcattle

Jawaban:

50

Anda dapat menemukan cara yang tepat untuk melakukannya di sini .

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

Kuncinya bukanlah memberikan tautan ke repositori git, tetapi tautan ke tarball. Github membuat tarball dari cabang master untuk Anda jika Anda menambahkan /tarball/masterseperti yang ditunjukkan di atas.

cel
sumber
17
Sepertinya metode ini tidak digunakan lagi per github.com/pypa/pip/issues/3939
muon
2
Metode ini juga tidak berguna untuk repositori pribadi, karena tidak ada cara untuk mengautentikasi.
tedivm
3
Saya berhasil membuatnya berfungsi dan telah menambahkan jawaban lain.
tedivm
1
The /tarball/mastermetode tidak bekerja untuk gitlab
Martin Thoma
3
Tidak digunakan lagi. Jawaban yang benar adalah menggunakan Pep508, dijawab oleh @Dick Fox di bawah ini
SwimBikeRun
104

Setelah menggali masalah pip 3939 yang ditautkan oleh @muon di komentar di atas dan kemudian spesifikasi PEP-508 , saya menemukan keberhasilan mendapatkan ketergantungan repo pribadi saya untuk diinstal melalui setup.pymenggunakan pola spesifikasi ini di install_requires(tidak lebih dependency_links):

install_requires = [
  'some-pkg @ git+ssh://[email protected]/someorgname/[email protected]#egg=some-pkg',
]

The @v1.1menunjukkan tag rilis dibuat di github dan bisa diganti dengan cabang, komit, atau berbagai jenis tag.

Dick Fox
sumber
Catatan: Ini berfungsi dengan baik untuk paket lokal / pribadi, namun, Anda tidak dapat merilis paket ke PyPI yang menggunakan sintaks ini di setup.py
Brian
7
@ Brian Bisakah Anda memberikan tautan ke pernyataan resmi?
Gajah
11
Catatan yang dapat Anda lakukan git+https://github.comjika Anda tidak ingin menggunakan SSH.
multithr3at3d
2
Jadi apa pendekatan yang benar untuk melakukan --upgrade? Meskipun saya menentukan versi tag, peningkatan hanya mengabaikan versi tag yang lebih baru
Piacenti
1
@El Elephant Bukan super resmi, tapi ini setidaknya komentar pada proyek pip GitHub dari anggota sebenarnya dari PyPA: github.com/pypa/pip/issues/4187#issuecomment-415667805 dan penjelasan lebih lanjut: github.com/pypa/pip / issues / 4187 # Issuecomment-415067034
Dominick Pastore
19

Jawaban berikut tidak digunakan lagi untuk Pip 19+


Sayangnya, jawaban lain tidak berfungsi dengan repositori pribadi, yang merupakan salah satu kasus penggunaan paling umum untuk ini. Saya akhirnya berhasil membuatnya bekerja dengan setup.pyfile yang terlihat seperti ini:

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://[email protected]/example_organization/ExampleRepo.git#egg=ExampleRepo-0.1'
    ]
)

Versi pip yang lebih baru membuat ini semakin mudah dengan menghilangkan kebutuhan untuk menggunakan "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://[email protected]/example_organization/ExampleRepo.git#egg=ExampleRepo-0.1'
    ]
)
tedivm
sumber
1
bisakah Anda menjelaskan apa yang dimaksud -0.1dalam pendekatan Anda? Apakah Anda mengambil nomor versi dari rilis git atau dari setup.pydeskripsi?
Peteris
2
Dari file setup.py- jika Anda ingin menggunakan cabang atau tag tertentu, Anda memformat sesuatu dengan sedikit berbeda.
tedivm
"Sayangnya, jawaban lain tidak berfungsi dengan repositori pribadi" Ini tidak lagi benar . Jawaban Fox berfungsi pada repo pribadi tanpa perlu dependency_links(yang tidak berlaku lagi )
Keto
Terima kasih @Keto! Saya tidak tahu mengapa hasil edit Anda ditolak tetapi modnya, tetapi saya melanjutkan dan mengesampingkan penolakan itu untuk menambahkan pemberitahuan penghentian ke jawabannya.
tedivm
3

Jawaban yang lebih umum, untuk mendapatkan informasi dari file requeriments.txt saya lakukan:

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://[email protected]/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,
) 
Gonzalo Odiard
sumber
1

Sebenarnya jika Anda ingin membuat paket Anda dapat diinstal secara rekursif (YourCurrentPackage menyertakan SomePrivateLib Anda), misalnya ketika Anda ingin memasukkan YourCurrentPackage ke paket lain (seperti OuterPackage -> YourCurrentPackage -> SomePrivateLib) Anda akan memerlukan keduanya:

install_requires=[
    ...,
    "SomePrivateLib @ git+ssh://github.abc.com/abc/[email protected]#egg=SomePrivateLib"
],
dependency_links = [
    "git+ssh://github.abc.com/abc/[email protected]#egg=SomePrivateLib"
]

Dan pastikan Anda memiliki tag yang dibuat dengan nomor versi Anda.

Juga jika proyek git Anda bersifat pribadi dan Anda ingin menginstalnya di dalam wadah misalnya Docker atau runner GitLab, Anda akan memerlukan akses resmi ke repo Anda. Harap pertimbangkan untuk menggunakan git + https dengan token akses (seperti di 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/[email protected]#egg=SomePrivateLib"
    ],
    dependency_links = [
            f"git+https://gitlab-ci-token:{TOKEN_VALUE}@gitlab.server.com/abc/[email protected]#egg=SomePrivateLib"
    ]
)
darencorp
sumber
0

Saya berhasil dengan 3 opsi ini di gitlab. Saya menggunakan gitlab versi 11.

opsi 1 - tidak ada token yang ditentukan. shell akan meminta nama pengguna / kata sandi.

from setuptools import setup

TOKEN_VALUE = os.getenv('EXPORTED_VAR_WITH_TOKEN')

setup(
    install_requires=[
        "SomePrivateLib @ git+https://gitlab.server.com/abc/[email protected]#egg=SomePrivateLib"
    ]
)

opsi 2 - token akses pengguna ditentukan. token yang dibuat dengan membuka gitlab> kanan atas akun> pengaturan> token akses. buat token dengan hak read_repository.

contoh:

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/[email protected]#egg=SomePrivateLib"
    ]
)

opsi 3 - token tingkat repositori ditentukan. token yang dibuat dengan membuka repositori> pengaturan> repositori> gunakan token. dari sini buat token dengan hak read_repository.

contoh:

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/[email protected]#egg=SomePrivateLib"
    ]
)

Pada ketiganya, saya dapat melakukan dengan mudah: "SomePrivateLib @ git + https: //gitlab.server.com/abc/SomePrivateLib.git" tanpa tanda #egg di bagian akhir.

ErikW
sumber