Menginstal paket Python dari folder sistem file lokal ke virtualenv dengan pip

346

Apakah mungkin untuk menginstal paket menggunakan pip dari sistem file lokal?

Saya telah menjalankan python setup.py sdistuntuk paket saya, yang telah membuat file tar.gz yang sesuai. File ini disimpan di sistem saya di /srv/pkg/mypackage/mypackage-0.1.0.tar.gz.

Sekarang di lingkungan virtual saya ingin menginstal paket baik yang berasal dari pypi atau dari lokasi lokal tertentu /srv/pkg.

Apakah ini mungkin?

PS Saya tahu bahwa saya bisa menentukan pip install /srv/pkg/mypackage/mypackage-0.1.0.tar.gz. Itu akan berhasil, tetapi saya berbicara tentang menggunakan /srv/pkglokasi sebagai tempat lain untuk mencari pip jika saya mengetik pip install mypackage.

chadgh
sumber
Saya mencari untuk menginstal paket PyPi tanpa setup.py, dari roda WHL, dan itu terinstal setelah saya mengunduh versi yang benar untuk versi Python saya, dan berlari pip install <Path-to-WHL-file>.
Wiktor Stribiżew

Jawaban:

136

Saya cukup yakin apa yang Anda cari disebut --find-linksopsi.

Meskipun Anda mungkin perlu membuat dummy index.htmluntuk indeks paket lokal Anda yang mencantumkan tautan ke semua paket. Alat ini membantu:

https://github.com/wolever/pip2pi

Mikko Ohtamaa
sumber
100
pip install mypackage --no-index --find-links file:///srv/pkg/mypackageharus bekerja.
jfs
1
Itu memang membantu. Dan kita dapat menggunakan opsi -i dari pip untuk memperlakukannya sebagai PyPI lokal.
diabloneo
Perintah easy_install yang setara adalaheasy_install --allow-hosts=None --find-links file:///srv/pkg/mypackage mypackage
Wilfred Hughes
Saya harus membuat file distribusi sumber tidak hanya mengarahkannya ke proyek atau direktori paket sebelum itu berfungsi. Ini membuat saya tersandung. docs.python.org/3.6/distutils/sourcedist.html
Josh
3
Perhatikan bahwa --find-linksmasih akan memungkinkan pencarian di PyPI jika paket tidak ditemukan di lokasi yang ditentukan atau jika versi yang lebih baru tersedia. Di Windows, saya menemukan bahwa menggabungkan ini dengan --only-binary=packagename(atau --only-binary=:all:) sangat berguna. Ini mencegah pip dari mencoba mengunduh paket dengan dependensi asli yang hanya memiliki distribusi sumber pada PyPI (dan karenanya memerlukan kompilasi), yang merupakan alasan paling umum saya harus mencoba untuk menginstal dari direktori. Tidak seperti itu --no-index, saya masih dapat menginstal paket lain dari PyPI.
jpmc26
463

Bagaimana dengan::

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.

misalnya, pip install -e /srv/pkg

di mana / srv / pkg adalah direktori tingkat atas tempat 'setup.py' dapat ditemukan.

drpoo
sumber
49
Ini akan menginstal paket dalam mode pengembangan, artinya hanya akan menautkan kembali ke tempat sumbernya. Jika kebetulan sumbernya dipindahkan atau dihapus, mengimpor paket akan gagal.
Trasplazio Garzuglio
3
@MarcoDinacci Yang menarik tentang --editabletampaknya melihat ke direktori paket lokal dan mengatur sumber sebagai repo git jika ada satu - sedikit lebih fleksibel daripada hanya folder. Saya tidak dapat menemukan dokumentasi untuk ini.
NotSimon
3
Meskipun ini benar untuk menginstal paket tertentu, terutama yang sedang dalam pengembangan / intensif pada mesin lokal atau VCS url. Itu tidak menjawab pertanyaan tentang mencari direktori induk untuk semua sumber paket lokal sebagai lawan dari satu sumber paket tertentu . Jawaban yang diterima berfungsi ketika Anda memiliki direktori atau url dengan beberapa paket yang ingin Anda instal.
Gavin
@MarcoDinacci Namun, anggaplah pengguna mengunduh kode. Mereka meletakkannya di tempat yang mereka inginkan, jika mereka cerdas. Mengapa mereka ingin memindahkannya?
Zelphir Kaltstahl
1
@Simon apakah ada cara untuk memberitahu pip untuk tidak mencari repo git? Jika saya do pip install -ememeriksa kode dari remote git, saya ingin menginstal kode apa adanya (dengan perubahan yang belum ada di remote).
Pedru
39

Saya menginstal pyfuzzytetapi tidak dalam PyPI; ia mengembalikan pesan: No matching distribution found for pyfuzzy.

Saya mencoba jawaban yang diterima

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

Tapi itu tidak berhasil dan mengembalikan kesalahan berikut:

Mengabaikan indeks: https://pypi.python.org/simple Mengumpulkan pyfuzzy Tidak dapat menemukan versi yang memenuhi persyaratan pyfuzzy (dari versi:) Tidak ditemukan distribusi yang cocok untuk pyfuzzy

Akhirnya, saya menemukan cara sederhana yang bagus di sana: 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

Jadi perintah berikut bekerja untuk saya:

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

Semoga ini bisa membantu Anda.

Victor Choy
sumber
4
Ini berhasil untuk saya. Saya mencoba pendekatan lain dan tersandung oleh Could not find a version that satisfieskesalahan. Terima kasih.
Rair
21

Ini adalah solusi yang akhirnya saya gunakan:

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

Saya mengumpulkan ini bersama-sama dari contoh instalasi pip dan juga dari jawaban Rikard pada pertanyaan lain . Argumen "--pre" memungkinkan Anda menginstal versi non-produksi. Argumen "--no-index" menghindari pencarian indeks PyPI. "--Find-links =." pencarian argumen di folder lokal (ini bisa relatif atau absolut). Saya menggunakan argumen "--log-file", "log.txt", dan "-vv" untuk debugging. Argumen "--upgrade" memungkinkan Anda menginstal versi yang lebih baru dari yang lebih lama.

Saya juga menemukan cara yang bagus untuk menghapus instalasi mereka. Ini berguna ketika Anda memiliki beberapa lingkungan Python yang berbeda. Ini format dasar yang sama, hanya menggunakan "uninstall" alih-alih "install", dengan langkah keamanan untuk mencegah pencopotan pemasangan yang tidak diinginkan:

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 lokal berisi file-file ini: install.py, uninstall.py, mypackagename-1.0.zip

Devan Williams
sumber
1
Terima kasih. "--Find-links =." dan "--tidak ada indeks", di mana kunci menempel bersama skrip python di dalam paket utilitas saya, yang pertama-tama menghapus paket versi lama dari paket situs lalu menginstal paket tar.gz'ed dari subdir folder utility-package-folder (tidak tahu tentang --find-links =.), kemudian membuat roda dan memasangnya. Semua otomatis melalui timah hitam dan klik. Jika seseorang menginginkannya, saya akan memposting tautan. Terpilih.
JackLeEmmerdeur
15

Opsi --find-links berfungsi dan bekerja dari requirements.txtfile!

Anda dapat meletakkan arsip paket di beberapa folder dan mengambil yang terbaru tanpa mengubah file persyaratan, misalnya 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

Sekarang requirements/base.txtdimasukkan:

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

Cara yang rapi untuk memperbarui paket eksklusif, cukup masukkan yang baru di folder

Dengan cara ini Anda dapat menginstal paket dari local folderDAN pypidengan satu panggilan yang sama:pip install -r requirements/production.txt

PS. Lihat garpu cookiecutter-djangopackage saya untuk melihat cara membagi persyaratan dan menggunakan organisasi persyaratan berbasis folder.

Janusz Skonieczny
sumber
Terima kasih, ini bahkan lebih baik daripada apa yang saya pikirkan lakukan!
FoundNil
11

Dari halaman install-paket Anda cukup menjalankan:

instal pip / srv / pkg / mypackage

di mana / srv / pkg / mypackage adalah direktori, berisi setup.py .


Selain itu 1 , Anda dapat menginstalnya dari file arsip:

pip instal ./mypackage-1.0.4.tar.gz

1 Meskipun disebutkan dalam pertanyaan, karena popularitasnya, itu juga termasuk.

dim8
sumber
2
Ini harus menjadi jawaban default. Tidak perlu membuat pip berburu dengan --find-links jika Anda tahu persis di mana paket Anda berada di mesin lokal.
Robert
6

Dengan asumsi Anda memiliki virtualenv dan requirements.txtfile, maka Anda dapat menentukan di dalam file ini di mana mendapatkan paket:

# 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
sumber
5

Memiliki persyaratan dalam requirements.txtdan egg_dirsebagai direktori

Anda dapat membangun cache lokal Anda:

$ pip download -r requirements.txt -d eggs_dir

kemudian, menggunakan "cache" itu sederhana seperti:

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

Sławomir Lenart
sumber
1

Untuk menginstal hanya dari lokal Anda memerlukan 2 opsi:

  • --find-links: tempat mencari dependensi. Tidak perlu file://awalan yang disebutkan oleh orang lain.
  • --no-index: jangan lihat di indeks pypi untuk dependensi yang hilang (dependensi tidak diinstal dan tidak di --find-linksjalur).

Jadi Anda bisa lari dari folder apa saja berikut ini:

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

Jika mypackage Anda telah diatur dengan benar, ia akan mencantumkan semua dependensinya, dan jika Anda menggunakan unduhan pip untuk mengunduh kaskade dependensi (mis. Dependensi depency, dll.), Semuanya akan berfungsi.

Jika Anda ingin menggunakan indeks pypi jika dapat diakses, tetapi mundur ke roda lokal jika tidak, Anda dapat menghapus --no-indexdan menambahkan --retries 0. Anda akan melihat pip pause sebentar ketika sedang mencoba memeriksa pypi untuk dependensi yang hilang (satu tidak terinstal) dan ketika ternyata tidak dapat mencapainya, akan kembali ke lokal. Sepertinya tidak ada cara untuk memberitahu pip untuk "mencari yang lokal dulu, lalu indeks".

Oliver
sumber
-1

Saya sudah berusaha untuk mencapai sesuatu yang sangat sederhana dan gagal total, mungkin saya bodoh.

Lagi pula, jika Anda memiliki skrip / Dockerfileyang mengunduh file zip paket python (mis. Dari GitHub) dan Anda ingin menginstalnya, Anda dapat menggunakan file:///awalan untuk menginstalnya seperti yang ditunjukkan dalam contoh berikut :

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

CATATAN : Saya tahu Anda dapat menginstal paket langsung menggunakan pip install https://example.com/mypackage.ziptetapi dalam kasus saya saya ingin memverifikasi checksum (tidak pernah cukup paranoid) dan saya gagal total ketika mencoba menggunakan berbagai opsi yang disediakan pip / #md5fragmen.

Mengejutkan karena melakukan sesuatu yang begitu sederhana secara langsung membuat frustrasi pip. Saya hanya ingin melewati sebuah checksum dan pipmemverifikasi bahwa zip sudah cocok sebelum menginstalnya.

Saya mungkin melakukan sesuatu yang sangat bodoh tetapi pada akhirnya saya menyerah dan memilih untuk ini. Saya harap ini membantu orang lain mencoba melakukan sesuatu yang serupa.

Aldo 'xoen' Giambelluca
sumber