Cách viết setup.py để bao gồm git repo làm phụ thuộc


95

Tôi đang cố gắng viết setup.pycho gói của tôi. Gói của tôi cần chỉ định sự phụ thuộc vào một git repo khác.

Đây là những gì tôi có cho đến nay:

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

Khi tôi chạy:

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

tôi có

Không thể tìm thấy phiên bản đáp ứng yêu cầu SomePrivateLib> = 0.1.0 (từ phân tích) (từ các phiên bản:) Không tìm thấy phân phối phù hợp cho SomePrivateLib> = 0.1.0 (từ phân tích)

Tôi đang làm gì sai?


Lưu ý rằng setup.py và pip là các hệ thống hoàn toàn khác nhau. Một vấn đề mà tôi gặp phải là tôi có thể làm cho điều này hoạt động cho pip nhưng không cho setup.py.
bcattle

Câu trả lời:


50

Bạn có thể tìm thấy cách thích hợp để làm điều đó tại đây .

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

Điều quan trọng không phải là cung cấp liên kết đến kho lưu trữ git, mà là liên kết đến tarball. Github tạo một tarball của nhánh chính cho bạn nếu bạn thêm /tarball/mastervào như hình trên.


17
có vẻ như phương pháp này không được dùng nữa per github.com/pypa/pip/issues/3939
muon

3
Phương pháp này cũng vô dụng đối với các kho lưu trữ riêng tư, vì không có cách nào để xác thực.
tedivm 13/02/19

3
Tôi đã cố gắng làm cho nó hoạt động và đã thêm một câu trả lời khác.
tedivm

1
Các /tarball/masterphương pháp không làm việc cho gitlab
Martin Thoma

3
Không được chấp nhận. Câu trả lời đúng là sử dụng Pep508, được trả lời bởi @Dick Fox bên dưới
SwimBikeRun

105

Sau khi tìm hiểu vấn đề về pip 3939 được liên kết bởi @muon trong các nhận xét ở trên và sau đó là thông số kỹ thuật PEP-508 , tôi đã tìm thấy thành công khi cài đặt phụ thuộc repo riêng tư của mình setup.pybằng cách sử dụng mẫu đặc tả này trong install_requires(không còn nữa dependency_links):

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

Thẻ @v1.1cho biết thẻ phát hành được tạo trên github và có thể được thay thế bằng một nhánh, cam kết hoặc loại thẻ khác.


Lưu ý: Điều này hoạt động tốt cho các gói cục bộ / riêng tư, tuy nhiên, bạn không thể phát hành một gói cho PyPI sử dụng cú pháp này trong setup.py
Brian

7
@Brian Bạn có thể vui lòng cung cấp một liên kết đến tuyên bố chính thức không?
Con voi

11
Lưu ý bạn có thể làm git+https://github.comnếu không muốn sử dụng SSH.
multithr3at3d

2
Vậy cách tiếp cận đúng để thực hiện - nâng cấp là gì? Mặc dù tôi chỉ định phiên bản thẻ, bản nâng cấp chỉ bỏ qua các phiên bản thẻ mới hơn
Piacenti

1
@Elephant Không phải là siêu chính thức, nhưng ít nhất đây là những nhận xét về dự án pip GitHub từ các thành viên thực tế của PyPA: github.com/pypa/pip/issues/4187#issuecomment-415667805 và giải thích thêm: github.com/pypa/pip / issue / 4187 # releaseecomment-415067034
Dominick Pastore

19

Câu trả lời sau không được dùng cho Pip 19+


Thật không may, câu trả lời khác không hoạt động với kho lưu trữ riêng, đây là một trong những trường hợp sử dụng phổ biến nhất cho việc này. Cuối cùng tôi đã làm cho nó hoạt động với một setup.pytệp trông giống như sau:

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

Các phiên bản mới hơn của pip giúp việc này trở nên dễ dàng hơn bằng cách loại bỏ nhu cầu sử dụng "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://git@github.com/example_organization/ExampleRepo.git#egg=ExampleRepo-0.1'
    ]
)

1
bạn có thể vui lòng giải thích những gì -0.1đại diện cho cách tiếp cận của bạn? Bạn lấy số phiên bản từ bản phát hành git hay từ setup.pymô tả?
Peteris

2
Từ tệp setup.py- nếu bạn muốn sử dụng một nhánh hoặc thẻ cụ thể, bạn định dạng mọi thứ hơi khác một chút.
tedivm

"Thật không may, câu trả lời khác không hoạt động với kho riêng" Điều này không còn đúng với Fox Câu trả lời hoạt động trên riêng tư mà không cần dependency_links( không được dùng nữa )
Keto

Cảm ơn @Keto! Tôi không biết tại sao bản chỉnh sửa của bạn bị từ chối trừ các bản sửa đổi, nhưng tôi đã tiếp tục và ghi đè từ chối đó để thêm thông báo không dùng nữa vào câu trả lời.
tedivm

3

Một câu trả lời chung hơn, để lấy thông tin từ tệp requeriments.txt, tôi thực hiện:

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

Trên thực tế, nếu bạn muốn làm cho các gói của mình có thể cài đặt một cách đệ quy (YourCurrentPackage bao gồm SomePrivateLib của bạn), ví dụ: khi bạn muốn bao gồm YourCurrentPackage vào một gói khác (như OuterPackage -> YourCurrentPackage -> SomePrivateLib), bạn sẽ cần cả hai:

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

Và đảm bảo rằng bạn đã tạo thẻ có số phiên bản của mình.

Ngoài ra nếu dự án git của bạn là riêng tư và bạn muốn cài đặt nó bên trong vùng chứa, ví dụ như Docker hoặc GitLab runner, bạn sẽ cần quyền truy cập được ủy quyền vào kho lưu trữ của mình. Vui lòng xem xét sử dụng git + https với mã thông báo truy cập (như trên 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

Tôi đã thành công với 3 tùy chọn này trong gitlab. Tôi đang sử dụng phiên bản 11 của gitlab.

tùy chọn 1 - không có mã thông báo nào được chỉ định. shell sẽ nhắc nhập tên người dùng / mật khẩu.

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

tùy chọn 2 - mã thông báo truy cập người dùng được chỉ định. mã thông báo được tạo bằng cách truy cập gitlab> tài khoản trên cùng bên phải> cài đặt> mã thông báo truy cập. tạo mã thông báo với quyền read_repository.

thí dụ:

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

tùy chọn 3 - mã thông báo cấp kho lưu trữ được chỉ định. mã thông báo được tạo bằng cách đi tới kho lưu trữ> cài đặt> kho lưu trữ> triển khai mã thông báo. từ đây tạo mã thông báo có quyền read_repository.

thí dụ:

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

Trong cả 3, tôi có thể thực hiện đơn giản: "SomePrivateLib @ git + https: //gitlab.server.com/abc/SomePrivateLib.git" mà không cần đánh dấu #egg ở cuối.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.