Установка пакетов 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.

chadgh
источник
Я искал установить пакет 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».

drpoo
источник
49
Это установит пакет в режиме разработки, то есть просто свяжется с исходными текстами. Если по какой-либо причине источники будут перемещены или удалены, импорт пакета завершится неудачно.
Trasplazio Garzuglio
3
@MarcoDinacci Что интересно, так --editableэто то, что он, похоже, просматривает каталог локального пакета и устанавливает источник как git-репо, если он есть - немного более гибкий, чем просто папка. Я не могу найти документацию для этого, хотя.
NotSimon
3
Хотя это правильно для установки определенного пакета, особенно в текущей / интенсивной разработке на локальном компьютере или URL VCS. Он не отвечает на вопрос о поиске в родительском каталоге всех локальных источников пакетов, в отличие от одного конкретного источника пакетов . Принятый ответ работает, когда у вас есть каталог или URL с несколькими пакетами, из которых вы хотите установить pip.
Гэвин
@MarcoDinacci Однако предположим, что пользователь загружает код. Они помещают его туда, где хотят, чтобы программа была, если они такие умные. Почему они хотят переместить это?
Зельфир Кальцталь
1
@ Симон, есть ли способ сказать Пипу, что не нужно искать git-репо? Если я do pip install -eпроверяю код с удаленного git, я хотел бы установить код как есть (с изменениями еще не в удаленном).
Педру
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-скрипта внутри моего служебного пакета, который сначала удаляет старый-version-пакет из site-packages, а затем устанавливает tar.gz'ed-пакет из subdir утилиты package-folder (не знал о --find-links =.), затем создает колесо и устанавливает его. Все автоматизировано с помощью свинца и клика. Если кто-то захочет, я выложу ссылку. Upvoted.
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. См. Мою ветку cookiecutter-djangopackage, чтобы узнать, как разделить требования и использовать организацию требований на основе папок.

Януш Сконечны
источник
Спасибо, это даже лучше, чем я думал!
найденоNil
12

На странице установки пакетов вы можете просто запустить:

pip install / srv / pkg / mypackage

где / srv / pkg / mypackage - это каталог, содержащий setup.py .


Дополнительно 1 , вы можете установить его из архива:

pip install ./mypackage-1.0.4.tar.gz

1 Хотя отмечается в вопросе, из-за его популярности, он также включен.

dim8
источник
2
Это должен быть ответ по умолчанию. Не нужно запускать pip hunt с помощью --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
marquicus
источник
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

Если ваш mypackage настроен правильно, он перечислит все его зависимости, и если вы использовали pip download для загрузки каскада зависимостей (т.е. зависимостей зависимостей и т. Д.), Все будет работать.

Если вы хотите использовать индекс pypi, если он доступен, но в противном случае можете использовать запасные колеса, вы можете удалить --no-indexи добавить --retries 0. Вы увидите pip pause на некоторое время, пока он попытается проверить 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но в моем случае я хотел проверить контрольную сумму (никогда не бывает достаточно параноидальной) и потерпел неудачу при попытке использовать различные опции, которые предоставляет pip / #md5фрагмент.

Было удивительно неприятно делать что-то такое простое напрямую pip. Я просто хотел пройти контрольную сумму и pipубедиться, что почтовый индекс совпадает, прежде чем устанавливать его.

Я, вероятно, делал что-то очень глупое, но в конце концов я сдался и выбрал это. Я надеюсь, что это помогает другим, пытающимся сделать что-то подобное.

Альдо 'xoen' Джамбеллука
источник