Instalowanie pakietów Pythona z folderu lokalnego systemu plików do virtualenv za pomocą pip

346

Czy jest możliwe instalowanie pakietów za pomocą pip z lokalnego systemu plików?

Uruchomiłem python setup.py sdistpakiet, który utworzył odpowiedni plik tar.gz. Ten plik jest przechowywany w moim systemie pod adresem /srv/pkg/mypackage/mypackage-0.1.0.tar.gz.

Teraz w środowisku wirtualnym chciałbym zainstalować pakiety pochodzące z pypi lub z określonej lokalizacji lokalnej /srv/pkg.

czy to możliwe?

PS Wiem, że mogę to określić pip install /srv/pkg/mypackage/mypackage-0.1.0.tar.gz. To zadziała, ale mówię o używaniu /srv/pkglokalizacji jako innego miejsca, w którym pip mógłby wyszukiwać, jeśli wpisałem pip install mypackage.

Czadgh
źródło
Chciałem zainstalować pakiet PyPi bez setup.py, z koła WHL, i został on zainstalowany po pobraniu poprawnej wersji dla mojej wersji Python i uruchomieniu pip install <Path-to-WHL-file>.
Wiktor Stribiżew

Odpowiedzi:

136

Jestem pewien, że to, czego szukasz, nazywa się --find-links opcją.

Chociaż może być konieczne wygenerowanie manekina index.html dla lokalnego indeksu pakietów, który zawiera listę łączy do wszystkich pakietów. To narzędzie pomaga:

https://github.com/wolever/pip2pi

Mikko Ohtamaa
źródło
100
pip install mypackage --no-index --find-links file:///srv/pkg/mypackagepowinno działać.
jfs
1
To pomaga. I możemy użyć opcji -i pip, aby potraktować go jako lokalny PyPI.
diabloneo
Odpowiednikiem polecenia easy_install jesteasy_install --allow-hosts=None --find-links file:///srv/pkg/mypackage mypackage
Wilfred Hughes,
Musiałem utworzyć źródłowy plik dystrybucyjny, a nie tylko skierować go do katalogu projektu lub pakietu, zanim zadziała. To mnie potknęło. docs.python.org/3.6/distutils/sourcedist.html
Josh
3
Zauważ, że --find-linksnadal pozwoli na wyszukiwanie w PyPI, jeśli pakiet nie zostanie znaleziony w określonej lokalizacji lub jeśli dostępna jest nowsza wersja. W systemie Windows uważam, że połączenie tego z --only-binary=packagename(lub --only-binary=:all:) jest niezwykle przydatne. Zapobiega to próbom pobrania przez pip wszelkich pakietów z rodzimymi zależnościami, które mają tylko dystrybucje źródłowe na PyPI (a zatem wymagają kompilacji), co jest najczęstszym powodem, dla którego muszę próbować zainstalować z katalogu. W przeciwieństwie do --no-indextego nadal mogę instalować inne pakiety z PyPI.
jpmc26,
463

Co powiesz na::

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.

na przykład, pip install -e /srv/pkg

gdzie / srv / pkg to katalog najwyższego poziomu, w którym można znaleźć plik „setup.py”.

drpoo
źródło
49
Spowoduje to zainstalowanie pakietu w trybie programowania, co oznacza, że ​​po prostu odsyła do źródła. Jeśli przypadkiem źródła zostaną przeniesione lub usunięte, import pakietu nie powiedzie się.
Trasplazio Garzuglio
3
@MarcoDinacci Interesujące --editablejest to, że wygląda na to, że zagląda do katalogu lokalnego pakietu i ustawia źródło jako repozytorium git, jeśli takie istnieje - nieco bardziej elastyczne niż tylko folder. Nie mogę jednak znaleźć na to dokumentacji.
NotSimon,
3
Chociaż jest to poprawne w przypadku instalowania konkretnego pakietu, zwłaszcza tego w bieżącym / intensywnym rozwoju na komputerze lokalnym lub adresie URL VCS. Nie odpowiada na pytanie dotyczące przeszukiwania katalogu nadrzędnego dla wszystkich lokalnych źródeł pakietów w przeciwieństwie do jednego konkretnego źródła pakietu . Akceptowana odpowiedź działa, gdy masz katalog lub adres URL z wieloma pakietami, z których chcesz zainstalować pip.
Gavin
@MarcoDinacci Załóżmy jednak, że użytkownik pobiera kod. Umieszczają go tam, gdzie chcą, aby program był, jeśli są tak inteligentni. Dlaczego mieliby to przenieść?
Zelphir Kaltstahl
1
@ Simon jest sposób, aby powiedzieć pipowi, aby nie szukał repozytorium git? Jeśli do pip install -esprawdzę kod ze zdalnego git, chciałbym zainstalować kod w obecnej postaci (ze zmianami jeszcze nie w zdalnym).
Pedru
39

Instaluję, pyfuzzyale nie ma go w PyPI; zwraca komunikat: No matching distribution found for pyfuzzy.

Próbowałem zaakceptować odpowiedź

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

Ale to też nie działa i zwraca następujący błąd:

Ignorowanie indeksów: https://pypi.python.org/simple Zbieranie pyfuzzy Nie można znaleźć wersji spełniającej wymaganie pyfuzzy (z wersji:) Nie znaleziono pasującej dystrybucji dla pyfuzzy

W końcu znalazłem prosty sposób: 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

Więc następujące polecenie działało dla mnie:

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

Mam nadzieję, że może ci to pomóc.

Victor Choy
źródło
4
To zadziałało dla mnie. Próbowałem innych podejść i natknąłem się na Could not find a version that satisfiesbłąd. Dzięki.
Rair,
21

Oto rozwiązanie, które wykorzystałem:

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

Złożyłem to razem z przykładami instalacji pip, a także z odpowiedzi Rikarda na inne pytanie . Argument „--pre” pozwala instalować wersje nieprodukcyjne. Argument „--no-index” unika przeszukiwania indeksów PyPI. „--Find-links =.” wyszukiwanie argumentów w folderze lokalnym (może być względne lub bezwzględne). Użyłem argumentów „--log-file”, „log.txt” i „-vv” do debugowania. Argument „--upgrade” pozwala instalować nowsze wersje na starszych.

Znalazłem również dobry sposób na ich odinstalowanie. Jest to przydatne, gdy masz kilka różnych środowisk Python. Jest to ten sam podstawowy format, wystarczy użyć „odinstaluj” zamiast „zainstaluj”, ze środkiem bezpieczeństwa, aby zapobiec niezamierzonym odinstalowaniom:

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

Folder lokalny zawiera następujące pliki: install.py, uninstall.py, mypackagename-1.0.zip

Devan Williams
źródło
1
Dzięki. „--Find-links =.” i „--no-index”, gdzie klucz do sklejenia ze sobą skryptu python w moim pakiecie narzędziowym, który najpierw usuwa pakiet starej wersji z pakietów witryn, a następnie instaluje pakiet tar.gz z podkatalogu folderu Utility-package-folder (nie wiedziałem o --find-links =.), a następnie tworzy koło i instaluje je. Wszystko zautomatyzowane za pomocą pionu i kliknij. Jeśli ktoś tego chce, opublikuję link. Pozytywne.
JackLeEmmerdeur
15

Opcja --find-links wykonuje zadanie i działa z requirements.txtpliku!

Możesz umieścić archiwa pakietów w jakimś folderze i pobrać najnowszą bez zmiany pliku wymagań, na przykład 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

Teraz w requirements/base.txtzestawie:

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

Świetny sposób na aktualizację zastrzeżonych pakietów, po prostu upuść nowy w folderze

W ten sposób możesz zainstalować pakiety z local folderAND pypiz tym samym pojedynczym wywołaniem:pip install -r requirements/production.txt

PS. Zobacz mój widelec cookiecutter-djangopackage, aby zobaczyć, jak podzielić wymagania i korzystać z organizacji wymagań opartej na folderach.

Janusz Skonieczny
źródło
Dzięki, to jest nawet lepsze niż to, o czym myślałem!
FoundNil
12

Na stronie pakietów instalacyjnych możesz po prostu uruchomić:

pip install / srv / pkg / mypackage

gdzie / srv / pkg / mypackage to katalog zawierający plik setup.py .


Dodatkowo 1 możesz zainstalować go z pliku archiwum:

pip install ./mypackage-1.0.4.tar.gz

1 Chociaż zaznaczono to w pytaniu, ze względu na jego popularność, zostało również uwzględnione.

dim8
źródło
2
To powinna być domyślna odpowiedź. Nie musisz zmuszać Pipa do szukania za pomocą opcji --find-links, jeśli dokładnie wiesz, gdzie jest twój pakiet na komputerze lokalnym.
Robert
6

Zakładając, że masz virtualenv i requirements.txtplik, możesz określić w tym pliku, skąd pobrać pakiety:

# 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
markiz
źródło
5

Uwzględniając wymagania requirements.txti egg_dirjako katalog

możesz zbudować lokalną pamięć podręczną:

$ pip download -r requirements.txt -d eggs_dir

następnie użycie tej „pamięci podręcznej” jest proste:

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

Sławomir Lenart
źródło
1

Aby zainstalować tylko lokalnie, potrzebujesz 2 opcji:

  • --find-links: gdzie szukać zależności. file://Przedrostek wymieniony przez innych nie jest potrzebny .
  • --no-index: nie szukaj w indeksach pypi brakujących zależności (zależności nie zostały zainstalowane i nie znajdują się na --find-linksścieżce).

Abyś mógł uruchomić z dowolnego folderu:

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

Jeśli twój mypackage jest poprawnie skonfigurowany, wyświetli listę wszystkich swoich zależności, a jeśli użyłeś pip download, aby pobrać kaskadę zależności (tj. Zależności zależności itp.), Wszystko będzie działać.

Jeśli chcesz użyć indeksu pypi, jeśli jest on dostępny, ale jeśli nie, możesz wrócić do lokalnych kół, możesz go usunąć --no-indexi dodać --retries 0. Zobaczysz pauzę pauzy na chwilę, gdy próbuje sprawdzić pypi pod kątem brakującej zależności (jedna niezainstalowana), a gdy stwierdzi, że nie może do niej dotrzeć, wróci do lokalnego. Wydaje się, że nie ma sposobu, aby powiedzieć pipowi, aby „najpierw szukał lokalnych, a potem indeksu”.

Oliver
źródło
-1

Próbowałem osiągnąć coś naprawdę prostego i nieszczęśliwie poniosłem porażkę, prawdopodobnie jestem głupi.

W każdym razie, jeśli masz skrypt / Dockerfilektóry pobiera plik zip pakietu python (np. Z GitHub), a następnie chcesz go zainstalować, możesz użyć file:///prefiksu, aby go zainstalować, jak pokazano w poniższym przykładzie :

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

UWAGA : Wiem, że możesz od razu zainstalować pakiet, pip install https://example.com/mypackage.zipale w moim przypadku chciałem zweryfikować sumę kontrolną (nigdy wystarczająco paranoiczną) i nie udało mi się, próbując użyć różnych opcji, które zapewnia pip /#md5 fragment .

Zaskakująco frustrujące było robienie czegoś tak prostego bezpośrednio pip. Chciałem tylko przekazać sumę kontrolną i pipsprawdzić, czy zip był wcześniej zgodny instalacją.

Prawdopodobnie robiłem coś bardzo głupiego, ale ostatecznie zrezygnowałem i zdecydowałem się na to. Mam nadzieję, że pomoże to innym próbować zrobić coś podobnego.

Aldo „xoen” Giambelluca
źródło