Встановлення пакетів Python з локальної папки файлової системи у virtualenv з допомогою pip


346

Чи можливо встановити пакети за допомогою pip з локальної файлової системи?

Я запустив python setup.py sdistсвій пакет, який створив відповідний файл tar.gz. Цей файл зберігається в моїй системі за адресою /srv/pkg/mypackage/mypackage-0.1.0.tar.gz.

Тепер у віртуальному середовищі я хотів би встановити пакети або з pypi, або з певного локального місця /srv/pkg.

Чи можливо це?

PS Я знаю, що можу вказати pip install /srv/pkg/mypackage/mypackage-0.1.0.tar.gz. Це буде спрацьовувати, але я говорю про використання /srv/pkgмісця розташування як іншого місця для пошуку для запиту, якщо я набрав pip install mypackage.


Я шукав, щоб встановити пакет PyPi без setup.py, з колеса WHL, і він встановився після завантаження правильної версії для моєї версії Python, і запустив pip install <Path-to-WHL-file>.
Wiktor Stribiżew

Відповіді:


136

Я майже впевнений, що те, що ви шукаєте, називається --find-linksваріантом.

Хоча вам може знадобитися створити фіктивний код index.htmlдля вашого індексу локальних пакетів, у якому перераховані посилання на всі пакунки. Цей інструмент допомагає:

https://github.com/wolever/pip2pi


100
pip install mypackage --no-index --find-links file:///srv/pkg/mypackageповинен працювати.
jfs

1
Це допомагає. І ми можемо використовувати -i варіант pip, щоб розглянути його як локальний PyPI.
diabloneo

Еквівалентна команда easy_installeasy_install --allow-hosts=None --find-links file:///srv/pkg/mypackage mypackage
Вільфред Х'юз

Мені довелося створити файл розповсюдження джерела, а не просто вказувати його на проект чи каталог пакунків, перш ніж він запрацює. Це мене спонукало. docs.python.org/3.6/distutils/sourcedist.html
Джош

3
Зауважте, що --find-linksвсе ще буде доступний пошук на PyPI, якщо пакет не знайдений у вказаному місці або якщо доступна нова версія. У Windows я вважаю, що поєднувати це з --only-binary=packagename(або --only-binary=:all:) надзвичайно корисно. Це заважає pip намагатися завантажувати будь-які пакунки з нативними залежностями, які мають лише дистрибутивні джерела на PyPI (і, таким чином, вимагають компіляції), що є найпоширенішою причиною, яку я маю намагатися встановити з каталогу. На відміну від цього --no-index, я все ще можу встановити інші пакети від PyPI.
jpmc26

463

А як на рахунок::

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.

наприклад, pip install -e /srv/pkg

де / srv / pkg - каталог верхнього рівня, де можна знайти "setup.py".


49
Це дозволить встановити пакет у режимі розробки, тобто він просто посилатиметься туди, де є джерела. Якщо випадково перенести або видалити джерела, імпортувати пакет не вдасться.
Trasplazio Garzuglio

3
@MarcoDinacci Що цікавого --editableполягає в тому, що він, схоже, загляне в каталог локального пакету і встановить джерело як git repo, якщо такий є - трохи більш гнучким, ніж просто папка. Я не можу знайти документацію для цього.
NotSimon

3
Хоча це правильно для встановлення певного пакету, особливо такого, який знаходиться в поточній / інтенсивній розробці на локальній машині або URL-адресі VCS. Він не відповідає на питання про пошук батьківського каталогу для всіх локальних джерел пакунків на відміну від одного конкретного джерела пакета . Прийнята відповідь працює, коли у вас є каталог або URL з декількома пакетами, з яких ви хочете встановити файл.
Гавін

@MarcoDinacci Однак припустимо, що користувач завантажує код. Вони ставлять його там, де хочуть, щоб програма була, якщо вони такі розумні. Чому вони хочуть перенести це?
Зельфір Кальтшталь

1
@Simon є спосіб сказати pip не шукати git repo? Якщо я do pip install -eперевіряю код з git remote, я хотів би встановити код таким, який він є (із змінами ще не у віддаленому).
Педру

39

Я встановлюю, pyfuzzyале немає в PyPI; він повертає повідомлення: No matching distribution found for pyfuzzy.

Я спробував прийняту відповідь

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

Але це не працює і повертає таку помилку:

Ігнорування індексів: https://pypi.python.org/simple Збір pyfuzzy Не вдалося знайти версію, яка б задовольняла вимогу pyfuzzy (з версій:) Не знайдено відповідного розподілу для pyfuzzy

Нарешті, я знайшов там простий хороший спосіб: 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

Отже, наступна команда працювала для мене:

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

Сподіваюся, це може вам допомогти.


4
Це працювало для мене. Я спробував інші підходи і натрапив на Could not find a version that satisfiesпомилку. Дякую.
Rair

21

Це рішення, яке я вирішив використовувати:

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

Я зібрав це разом із прикладів встановлення pip , а також з відповіді Рікарда на інше питання . Аргумент "--pre" дозволяє встановлювати невиробничі версії. Аргумент "--no-index" дозволяє уникнути пошуку індексів PyPI. Посилання "--find-links =." пошук аргументів у локальній папці (це може бути відносно або абсолютно). Я використовував аргументи "--log-file", "log.txt" та "-vv" для налагодження. Аргумент "- Upgrade" дозволяє встановлювати новіші версії над старими.

Я також знайшов хороший спосіб їх видалення. Це корисно, якщо у вас є кілька різних середовищ Python. Це той самий базовий формат, просто використовуючи "видалити" замість "встановити", із заходом безпеки, щоб запобігти ненавмисним видаленням:

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

Локальна папка містить ці файли: install.py, uninstall.py, mypackagename-1.0.zip


1
Дякую. Посилання "--find-links =." та "--no-index", де ключ у склеюванні python-скрипта всередині мого утилітного пакета, який спочатку видаляє стару версію пакета з пакунків-сайтів, а потім встановлює tar.gz'ed пакет з subdir папки utility-package-package (не знав про --find-links =.), потім створює колесо і встановлює його. Все автоматизовано за допомогою плюмбуму та клацання. Якщо хтось цього хоче, я опублікую посилання. Оголошено.
JackLeEmmerdeur

15

Варіант --find-links виконує роботу, і вона працює з requirements.txtфайлу!

Ви можете помістити архіви пакетів у якусь папку і взяти останню, не змінюючи файл вимог, наприклад 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

Зараз у складі requirements/base.txt:

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

Акуратний спосіб оновити власні пакети, просто занесіть новий у папку

Таким чином ви можете встановити пакети від local folderAND pypiза допомогою одного і того ж одного виклику:pip install -r requirements/production.txt

PS. Дивіться мою виделку cookie-djangopackage, щоб дізнатися, як розділити вимоги та використовувати організацію вимог на основі папок.


Дякую, це навіть краще, ніж те, що я думав робити!
ЗнайденоНіль

12

На сторінці встановлення-пакети можна просто запустити:

pip install / srv / pkg / mypackage

де / srv / pkg / mypackage - це каталог, що містить setup.py .


Додатково 1 , ви можете встановити його з архівного файлу:

встановлення піп ./mypackage-1.0.4.tar.gz

1 Хоча зазначається у питанні, завдяки його популярності він також входить.


2
Це має бути відповідь за замовчуванням. Не потрібно здійснювати пошук піп-файлів за допомогою --find-links, якщо ви точно знаєте, де знаходиться ваш пакет на локальній машині.
Роберт

6

Якщо припустити, що у вас є virtualenv і requirements.txtфайл, то ви можете всередині цього файлу визначити, де взяти пакунки:

# 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

Маючи вимоги до requirements.txtта egg_dirяк каталог

ви можете створити свій локальний кеш:

$ pip download -r requirements.txt -d eggs_dir

то, використовуючи цей "кеш", просто:

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


1

Для встановлення лише з локальних потрібні 2 варіанти:

  • --find-links: де шукати залежності. Немає потреби в file://префіксі, згаданому іншими.
  • --no-index: не шукайте в індексах pypi для відсутніх залежностей (залежності не встановлені та не знаходяться в --find-linksшляху).

Отже, ви можете запустити з будь-якої папки наступне:

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

Якщо мій пакунок налаштований належним чином, він перелічить усі його залежності, і якщо ви використовували завантаження через pip для завантаження каскаду залежностей (тобто залежностей від покарань тощо), все буде працювати.

Якщо ви хочете скористатися індексом pypi, якщо він доступний, але якщо немає, то резервні місцеві колеса, якщо ні, ви можете видалити --no-indexта додати --retries 0. Ви побачите піп-паузу на деякий час, поки спробуєте перевірити pypi на відсутність залежності (одна не встановлена), і коли вона виявить, що не може її досягти, повернеться до локальної. Здається, не існує способу сказати pip, щоб "спочатку шукати локальні, потім індекс".


-1

Я намагався досягти чогось насправді простого і невдалого, мабуть, я дурний.

У будь-якому випадку, якщо у вас є сценарій / Dockerfileякий завантажує zip-файл пакету python (наприклад, з GitHub), а потім ви хочете його встановити, ви можете використовувати file:///префікс, щоб встановити його, як показано в наступному прикладі :

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

ПРИМІТКА : Я знаю, що ви можете встановити пакет відразу, використовуючи, pip install https://example.com/mypackage.zipале в моєму випадку я хотів перевірити контрольну суму (ніколи не вистачає параноїдальних), і мені не вдалося скористатися різними параметрами, які надає піп / #md5фрагмент.

Напрочуд було дуже важко робити щось так просто безпосередньо pip. Я просто хотів здати контрольну суму і pipпереконатися, що поштовий індекс збігається перед його встановленням.

Я, мабуть, робив щось дуже дурне, але врешті-решт я відмовився від цього. Я сподіваюся, що це допомагає іншим, намагаючись зробити щось подібне.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.