Cài đặt các gói Python từ thư mục hệ thống tệp cục bộ vào virtualenv với pip


346

Có thể cài đặt các gói bằng cách sử dụng pip từ hệ thống tập tin cục bộ?

Tôi đã chạy python setup.py sdistcho gói của mình, nó đã tạo ra tệp tar.gz thích hợp. Tập tin này được lưu trữ trên hệ thống của tôi tại /srv/pkg/mypackage/mypackage-0.1.0.tar.gz.

Bây giờ trong một môi trường ảo, tôi muốn cài đặt các gói đến từ pypi hoặc từ vị trí địa phương cụ thể /srv/pkg.

Điều này có thể không?

PS tôi biết rằng tôi có thể chỉ định pip install /srv/pkg/mypackage/mypackage-0.1.0.tar.gz. Điều đó sẽ hoạt động, nhưng tôi đang nói về việc sử dụng /srv/pkgvị trí này như một nơi khác để tìm kiếm nếu tôi gõ pip install mypackage.


Tôi đang tìm cách cài đặt gói PyPi mà không có setup.py, từ bánh xe WHL và nó đã được cài đặt sau khi tôi tải xuống một phiên bản chính xác cho phiên bản Python của mình và chạy pip install <Path-to-WHL-file>.
Wiktor Stribiż

Câu trả lời:


136

Tôi khá chắc chắn rằng những gì bạn đang tìm kiếm được gọi là --find-linkstùy chọn.

Mặc dù bạn có thể cần phải tạo một hình nộm index.htmlcho chỉ mục gói cục bộ liệt kê các liên kết đến tất cả các gói. Công cụ này giúp:

https://github.com/wolever/pip2pi


100
pip install mypackage --no-index --find-links file:///srv/pkg/mypackagenên làm việc.
jfs

1
Nó giúp. Và chúng ta có thể sử dụng tùy chọn -i của pip để coi nó như một PyPI cục bộ.
diabloneo

Lệnh easy_install tương đương làeasy_install --allow-hosts=None --find-links file:///srv/pkg/mypackage mypackage
Wilfred Hughes

Tôi đã phải tạo một tệp phân phối nguồn chứ không chỉ trỏ nó vào thư mục gói hoặc dự án trước khi nó hoạt động. Điều này làm tôi vấp ngã. docs.python.org/3.6/distutils/sourcedist.html
Josh

3
Lưu ý rằng --find-linksvẫn sẽ cho phép tìm kiếm trên PyPI nếu không tìm thấy gói ở vị trí đã chỉ định hoặc nếu có phiên bản mới hơn. Trên Windows, tôi thấy rằng việc kết hợp điều này với --only-binary=packagename(hoặc --only-binary=:all:) cực kỳ hữu ích. Điều này ngăn pip cố gắng tải xuống bất kỳ gói nào có phụ thuộc riêng chỉ có phân phối nguồn trên PyPI (và do đó yêu cầu biên dịch), đó là lý do phổ biến nhất mà tôi phải cố gắng cài đặt từ thư mục. Không giống như --no-index, tôi vẫn có thể cài đặt các gói khác từ PyPI.
jpmc26

463

Thế còn::

pip install --help
...
  -e, --editable <path/url>   Install a project in editable mode (i.e. setuptools
                              "develop mode") from a local project path or a VCS url.

ví dụ, pip install -e /srv/pkg

trong đó / srv / pkg là thư mục cấp cao nhất có thể tìm thấy 'setup.py'.


49
Điều này sẽ cài đặt gói trong chế độ phát triển, có nghĩa là nó sẽ chỉ liên kết trở lại nơi các nguồn. Nếu có bất kỳ cơ hội nào các nguồn được di chuyển hoặc xóa, nhập gói sẽ thất bại.
Trasplazio Garzuglio

3
@MarcoDinacci Điều thú vị --editablelà dường như nó nhìn vào thư mục của gói cục bộ và đặt nguồn là một repo git nếu có một - linh hoạt hơn một chút so với chỉ một thư mục. Tôi không thể tìm thấy tài liệu cho việc này mặc dù.
NotSimon

3
Trong khi điều này là chính xác để cài đặt một gói cụ thể, đặc biệt là một gói trong phát triển hiện tại / chuyên sâu trên máy cục bộ hoặc url VCS. Nó không trả lời câu hỏi về việc tìm kiếm một thư mục mẹ cho tất cả các nguồn gói cục bộ trái ngược với một nguồn gói cụ thể . Câu trả lời được chấp nhận hoạt động khi bạn có một thư mục hoặc url với nhiều gói bạn muốn cài đặt pip.
Gavin

@MarcoDinacci Tuy nhiên, giả sử người dùng tải xuống mã. Họ đặt nó ở nơi họ muốn chương trình trở thành, nếu họ thông minh. Tại sao họ muốn di chuyển nó?
Zelphir Kaltstahl

1
@Simon có cách nào để bảo pip không tìm kiếm repo git không? Nếu tôi do pip install -ekiểm tra mã từ git remote, tôi muốn cài đặt mã như hiện tại (với những thay đổi chưa có trong điều khiển từ xa).
Pedru

39

Tôi đang cài đặt pyfuzzynhưng không có trong PyPI; nó trả về tin nhắn : No matching distribution found for pyfuzzy.

Tôi đã thử câu trả lời được chấp nhận

pip install  --no-index --find-links=file:///Users/victor/Downloads/pyfuzzy-0.1.0 pyfuzzy

Nhưng nó cũng không hoạt động và trả về lỗi sau:

Bỏ qua các chỉ mục: https://pypi.python.org/simple Thu thập pyfuzzy Không thể tìm thấy phiên bản thỏa mãn yêu cầu pyfuzzy (từ các phiên bản :) Không tìm thấy phân phối phù hợp cho pyfuzzy

Cuối cùng, tôi đã tìm thấy một cách tốt đơn giản ở đó: https://pip.pypa.io/en/latest/reference/pip_install.html

Install a particular source archive file.
$ pip install ./downloads/SomePackage-1.0.4.tar.gz
$ pip install http://my.package.repo/SomePackage-1.0.4.zip

Vì vậy, lệnh sau đây làm việc cho tôi:

pip install ../pyfuzzy-0.1.0.tar.gz.

Hy vọng nó có thể giúp bạn.


4
Điều này làm việc cho tôi. Tôi đã thử các cách tiếp cận khác và bị vấp ngã vì Could not find a version that satisfieslỗi. Cảm ơn.
Rair

21

Đây là giải pháp mà tôi đã kết thúc bằng cách sử dụng:

import pip


def install(package):
    # Debugging
    # pip.main(["install", "--pre", "--upgrade", "--no-index",
    #         "--find-links=.", package, "--log-file", "log.txt", "-vv"])
    pip.main(["install", "--upgrade", "--no-index", "--find-links=.", package])


if __name__ == "__main__":
    install("mypackagename")
    raw_input("Press Enter to Exit...\n")

Tôi đã ghép cái này lại với nhau từ các ví dụ cài đặt pip cũng như từ câu trả lời của Rikard cho một câu hỏi khác . Đối số "--pre" cho phép bạn cài đặt các phiên bản không sản xuất. Đối số "--no-index" tránh tìm kiếm các chỉ mục PyPI. "--Find-links =." tìm kiếm đối số trong thư mục cục bộ (điều này có thể là tương đối hoặc tuyệt đối). Tôi đã sử dụng các đối số "--log-file", "log.txt" và "-vv" để gỡ lỗi. Đối số "--up tiến" cho phép bạn cài đặt các phiên bản mới hơn các phiên bản cũ hơn.

Tôi cũng tìm thấy một cách tốt để gỡ cài đặt chúng. Điều này rất hữu ích khi bạn có một vài môi trường Python khác nhau. Đó là định dạng cơ bản giống nhau, chỉ sử dụng "gỡ cài đặt" thay vì "cài đặt", với một biện pháp an toàn để ngăn chặn việc gỡ cài đặt ngoài ý muốn:

import pip


def uninstall(package):
    response = raw_input("Uninstall '%s'? [y/n]:\n" % package)
    if "y" in response.lower():
        # Debugging
        # pip.main(["uninstall", package, "-vv"])
        pip.main(["uninstall", package])
    pass


if __name__ == "__main__":
    uninstall("mypackagename")
    raw_input("Press Enter to Exit...\n")

Thư mục cục bộ chứa các tệp này: install.py, Uninstall.py, mypackagename-1.0.zip


1
Cảm ơn. "--Find-links =." và "--no-index", trong đó khóa gắn kết tập lệnh python bên trong gói tiện ích của tôi, trước tiên loại bỏ gói phiên bản cũ khỏi gói trang web sau đó cài đặt gói tar.gz'ed từ thư mục con của thư mục gói-tiện ích (không biết về --find-links =.), sau đó tạo bánh xe và cài đặt nó. Tất cả tự động thông qua plumbum và nhấp chuột. Nếu ai đó muốn nó, tôi sẽ đăng một liên kết. Nâng cao.
JackLeEmmerdeur

15

Một tùy chọn - tìm kiếm liên kết thực hiện công việc và nó hoạt động từ requirements.txttệp!

Bạn có thể đặt lưu trữ gói trong một số thư mục và lấy tệp mới nhất mà không thay đổi tệp yêu cầu, ví dụ requirements:

.
└───requirements.txt
└───requirements
    ├───foo_bar-0.1.5-py2.py3-none-any.whl
    ├───foo_bar-0.1.6-py2.py3-none-any.whl
    ├───wiz_bang-0.7-py2.py3-none-any.whl
    ├───wiz_bang-0.8-py2.py3-none-any.whl
    ├───base.txt
    ├───local.txt
    └───production.txt

Bây giờ được requirements/base.txtđưa vào:

--find-links=requirements
foo_bar
wiz_bang>=0.8

Một cách gọn gàng để cập nhật các gói độc quyền, chỉ cần thả cái mới vào thư mục

Theo cách này, bạn có thể cài đặt các gói từ local folderAND pypivới cùng một cuộc gọi:pip install -r requirements/production.txt

Tái bút Xem ngã ba cookiecutter-djangopackage của tôi để xem cách phân chia yêu cầu và sử dụng tổ chức yêu cầu dựa trên thư mục.


Cảm ơn, điều này thậm chí còn tốt hơn những gì tôi đã nghĩ!
FoundNil

11

Từ trang gói cài đặt, bạn chỉ cần chạy:

cài đặt pip / srv / pkg / mypackage

trong đó / srv / pkg / mypackage là thư mục, chứa setup.py .


Ngoài ra 1 , bạn có thể cài đặt nó từ tệp lưu trữ:

cài đặt pip ./mypackage-1.0.4.tar.gz

1 Mặc dù lưu ý trong câu hỏi, do sự phổ biến của nó, nó cũng được bao gồm.


2
Đây phải là câu trả lời mặc định. Không cần phải thực hiện săn tìm pip xung quanh với --find-links nếu bạn biết chính xác gói hàng của bạn ở đâu trên máy cục bộ.
Robert

6

Giả sử bạn có virtualenv và một requirements.txttệp, thì bạn có thể xác định bên trong tệp này để lấy các gói:

# Published pypi packages 
PyJWT==1.6.4
email_validator==1.0.3
# Remote GIT repo package, this will install as django-bootstrap-themes
git+https://github.com/marquicus/django-bootstrap-themes#egg=django-bootstrap-themes
# Local GIT repo package, this will install as django-knowledge
git+file:///soft/SANDBOX/python/django/forks/django-knowledge#egg=django-knowledge

5

Có yêu cầu trong requirements.txtegg_dirnhư một thư mục

bạn có thể xây dựng bộ đệm cục bộ của mình:

$ pip download -r requirements.txt -d eggs_dir

sau đó, sử dụng "bộ đệm" đó là đơn giản như:

$ pip install -r requirements.txt --find-links=eggs_dir


1

Để chỉ cài đặt từ địa phương, bạn cần 2 tùy chọn:

  • --find-links: nơi để tìm kiếm sự phụ thuộc. Không cần file://tiền tố được đề cập bởi những người khác.
  • --no-index: không tìm kiếm trong các chỉ mục pypi cho các phụ thuộc bị thiếu (các phụ thuộc không được cài đặt và không trong --find-linksđường dẫn).

Vì vậy, bạn có thể chạy từ bất kỳ thư mục sau đây:

pip install --no-index --find-links /srv/pkg /path/to/mypackage-0.1.0.tar.gz

Nếu gói của bạn được thiết lập đúng, nó sẽ liệt kê tất cả các phụ thuộc của nó và nếu bạn đã sử dụng tải xuống pip để tải xuống tầng phụ thuộc (tức là phụ thuộc của phụ thuộc, v.v.), mọi thứ sẽ hoạt động.

Nếu bạn muốn sử dụng chỉ số pypi nếu có thể truy cập được, nhưng nếu không có bánh xe cục bộ, bạn có thể loại bỏ --no-indexvà thêm --retries 0. Bạn sẽ thấy pip tạm dừng một chút trong khi nó cố gắng kiểm tra pypi xem có phụ thuộc bị thiếu không (một cái chưa được cài đặt) và khi nó tìm thấy nó không thể chạm tới nó, sẽ rơi trở lại cục bộ. Dường như không có cách nào để bảo pip "tìm kiếm địa phương trước, sau đó là chỉ mục".


-1

Tôi đã cố gắng để đạt được một cái gì đó thực sự đơn giản và thất bại thảm hại, có lẽ tôi ngu ngốc.

Dù sao, nếu bạn có tập lệnh / Dockerfiletải xuống tệp zip gói python (ví dụ từ GitHub) và sau đó bạn muốn cài đặt nó, bạn có thể sử dụng file:///tiền tố để cài đặt nó như trong ví dụ sau :

$ wget https://example.com/mypackage.zip
$ echo "${MYPACKAGE_MD5}  mypackage.zip" | md5sum --check -
$ pip install file:///.mypackage.zip

LƯU Ý : Tôi biết rằng bạn có thể cài đặt gói ngay lập tức bằng cách sử dụng pip install https://example.com/mypackage.zipnhưng trong trường hợp của tôi, tôi muốn xác minh tổng kiểm tra (không bao giờ đủ hoang tưởng) và tôi đã thất bại thảm hại khi cố gắng sử dụng các tùy chọn khác nhau mà pip cung cấp / #md5đoạn.

Thật đáng ngạc nhiên khi làm điều gì đó đơn giản trực tiếp với pip. Tôi chỉ muốn vượt qua một checksum và có pipxác minh rằng zip được phù hợp trước cài đặt nó.

Tôi có lẽ đã làm điều gì đó rất ngu ngốc nhưng cuối cùng tôi đã từ bỏ và lựa chọn cho việc này. Tôi hy vọng nó sẽ giúp những người khác cố gắng làm điều gì đó tương tự.

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.