Pipenv: Hasilkan requirements.txt dari Pipfile.lock

Dibuat pada 31 Jan 2019  ·  25Komentar  ·  Sumber: pypa/pipenv

Bagaimana cara menghasilkan file requirements.txt dari Pipfile.lock yang ada tanpa mengunci?
Ketika saya menjalankan pipenv lock -r itu mengabaikan Pipfile.lock yang ada dan melakukan proses penguncian lagi.

Ada solusi untuk ini:

$ pipenv sync
$ pipenv run pip freeze

Dalam situasi khusus saya, saya sedang membangun gambar buruh pelabuhan dan menggunakan requirements.txt di Dockerfile . Saya ingin menghindari membuat lingkungan virtual pada mesin Host hanya untuk dapat membuat requirements.txt .

Komentar yang paling membantu

kamu bisa lari

pipenv run pip freeze > requirements.txt

Semua 25 komentar

Pipenv tidak menyediakan cara untuk ini, Anda dapat mencari pustaka utilitas pipfile lain seperti persyaratan pipfile

kamu bisa lari

pipenv run pip freeze > requirements.txt

kamu bisa lari

pipenv run pip freeze > requirements.txt

Itulah yang saya sebutkan sebagai solusi di posting pertama.

Tetapi ini hanya berfungsi jika Anda memiliki lingkungan pipenv yang disinkronkan (semua paket diinstal).
Mengekstrak dependensi langsung dari Pipfile.lock lebih nyaman bagi saya:

jq -r '.default
        | to_entries[]
        | .key + .value.version' \
    Pipfile.lock > requirements.txt

posting blog
alat jq

LOL, saya sudah menyebutkan perpustakaan itu.

Saya, secara pribadi, tidak suka memiliki perpustakaan khusus untuk itu. Juga, ada kemungkinan lebih tinggi bahwa anggota tim sudah menginstal jq atau beberapa alat tujuan umum lainnya.

kamu bahkan bisa lari

 pipenv lock --requirements > requirements.txt

Ini tidak akan berfungsi seperti yang Anda harapkan, karena, seperti yang saya tulis:

Ketika saya menjalankan pipenv lock -r itu mengabaikan Pipfile.lock yang ada dan melakukan proses penguncian lagi.

Dengan kata lain, ia melakukan pembaruan, yang berpotensi merusak distribusi. Bayangkan, Anda menghasilkan requirements.txt untuk menggunakannya di Dockerfile untuk membangun gambar buruh pelabuhan. Secara lokal aplikasi Anda berfungsi, tetapi ketika Anda menghasilkan requirements.txt menggunakan pipenv lock , persyaratan mungkin diperbarui ke versi yang tidak kompatibel atau hanya rusak (mudah-mudahan, ini adalah kasus yang jarang terjadi). Dan Anda tidak akan tahu ini sebelum menjalankan gambar. Jadi, Anda perlu menguji aplikasi lagi setelah menjalankan pipenv lock .

Jika Anda tidak ingin menggunakan jq , maka lebih baik gunakan pendekatan yang saya usulkan di posting pertama dengan pipenv sync (yang tidak melakukan pembaruan).

@Zebradil jq pendekatan oneliner Anda jauh lebih sederhana daripada paket pipfile-requirements milik @frostming sendiri (100+ baris kode python) karena saya sudah menginstal jq , tidak ada dependensi lain diperlukan, yang sangat bagus.

Namun, setelah beberapa git melakukan, saya melihat perbedaan antara apa yang pipenv lock --requirements output dan apa yang jq diperoleh melalui file Pipfile.lock dan mencetak:

  • jq output tidak memiliki -i https://pypi.org/simple sebagai baris pertama, berbeda dengan pipenv lock --r yang selalu disisipkan sebagai baris pertama.
  • jq output tidak menyertakan anotasi untuk paket. Misalnya: pipenv lock --r output memiliki baris ini appnope==0.1.0 ; sys_platform == 'darwin' , tetapi dalam jq output, itu appnope==0.1.0 . Contoh lain adalah pipenv lock -r menghasilkan pexpect==4.7.0 ; sys_platform != 'win32' sedangkan jq menghasilkan pexpect==4.7.0 , tidak yakin apakah ini penting atau tidak.
  • pemesanan paket file persyaratan berbeda antara dua output. jq yang mungkin mengambil urutan paket dalam file Pipfile.lock , yang selalu mengurutkan berdasarkan abjad dan panjang karakter, misalnya, flask di depan flask-sqlalchemy atau paket flask-XXXXX apa pun, sedangkan pipenv lock --r menghasilkan flask di belakang flask-sqlalchemy , yang berbeda dari urutan di Pipfile.lock . Ini adalah gangguan besar karena tidak menghasilkan git diff minimum. Saya akan menganggap ini adalah bug di pipenv .

Hai @ye , perbandingan metode yang bagus. Ini mungkin membantu orang memilih solusi yang tepat untuk situasi khusus mereka dan menghindari peringatan.

Ya, seperti yang Anda katakan, pendekatan yang diusulkan dengan jq memiliki fungsionalitas terbatas. Dimungkinkan untuk memperluasnya untuk menambahkan anotasi dan URL indeks paket, tetapi saya tidak membutuhkannya sekarang.

Untuk menghindari perbedaan dalam requirements.txt yang dihasilkan, seseorang harus mempertimbangkan untuk menggunakan pendekatan yang sama setiap saat. Dengan cara yang sama, menggunakan alat pemformatan kode yang berbeda dapat menyebabkan hasil yang tidak konsisten. Jadi, saya tidak melihat masalah di sini.

kamu bisa lari

pipenv run pip freeze > requirements.txt

Itulah yang saya sebutkan sebagai solusi di posting pertama.

Tetapi ini hanya berfungsi jika Anda memiliki lingkungan pipenv yang disinkronkan (semua paket diinstal).
Mengekstrak dependensi langsung dari Pipfile.lock lebih nyaman bagi saya:

jq -r '.default
        | to_entries[]
        | .key + .value.version' \
    Pipfile.lock > requirements.txt

posting blog
alat jq

Hai,

Terima kasih atas solusi Anda. Saya mengalami masalah yang sama tetapi saya juga memerlukan definisi sumber yang dibuat oleh pipenv lock -r , yaitu: -i, --extra-index-url. Ini karena saya bekerja dengan sumber pribadi.

@Zebradil Saya pikir Anda menyebutkan itu.

Jadi saya membuat skrip tanpa ketergantungan minimal lainnya dengan python yang menyertakan fungsionalitas itu. Itu juga memperluas env vars jika Anda memiliki sumber yang ditentukan seperti itu di Pipfile Anda.

Jika ada yang ingin melihatnya, saya akan meninggalkannya di sini: https://Gist.github.com/rcastill/dab85c234dd10fa7af56755116c75aee

Jika ini membantu orang lain, berikut cara memasukkan hash ke dalam hasil:

 jq --raw-output '.default | to_entries[] | .key + .value.version + (.value.hashes | map(" --hash=\(.)") | join(""))' Pipfile.lock

Ini membuat entri seperti

paramiko==2.6.0 --hash=sha256:99f0179bdc176281d21961a003ffdb2ec369daac1a1007241f53374e376576cf --hash=sha256:f4b2edfa0d226b70bd4ca31ea7e389325990283da23465d572ed

Yang membuat pip menegakkan hash.

Jika Anda ingin memasukkan hanya persyaratan yang ada di file persyaratan asli (asalkan sudah dikunci ke versi tertentu dengan == ):

 jq --raw-output '.default | to_entries[] | .key + .value.version + (.value.hashes | map(" --hash=\(.)") | join(""))' Pipfile.lock | grep --file=<(grep --only-matching --perl-regexp '^.*(?===)' requirements.txt | tr '[:upper:]' '[:lower:]') > new.txt && mv new.txt requirements.txt

tr diperlukan karena file requirements.txt mungkin berisi nama paket kasus campuran tetapi pipenv install -r requirements.txt menggunakan huruf kecil di Pipfile.

Berikut ini skrip python kecil jika Anda ingin mengubah Pipfile (bukan file kunci) menjadi file requirements.txt.

import configparser


def main():
    parser = configparser.ConfigParser()
    parser.read("Pipfile")

    packages = "packages"
    with open("requirements.txt", "w") as f:
        for key in parser[packages]:
            value = parser[packages][key]
            f.write(key + value.replace("\"", "") + "\n")


if __name__ == "__main__":
    main()

@frostming Hai, saya menemukan https://github.com/frostming/pipfile-requirements berguna tetapi mengapa itu tidak terintegrasi ke dalam pipenv?

@linusguan Alat ini ada untuk mereka yang tidak ingin menginstal perpustakaan pipenv besar, ketika Anda telah menginstal pipenv, Anda dapat menggunakan pipenv lock -r

@frostming Saya merasa cukup berguna untuk digunakan dengan alat lain yang tidak mendukung pipfile.lock.
Masalah dengan pipenv lock -r apakah itu memperbarui pipfile.lock jadi saya tidak dapat menggunakannya untuk menghasilkan build deterministik bersama dengan alat lain. Sesuatu seperti pipenv lock -r --ignore-pipfile akan ideal.

Berikut ini skrip python lain untuk menghasilkan requirements.txt dari file Pipfile.lock dengan hash:

import os
import json

__dir__ = os.path.dirname(os.path.realpath(__file__))


def read_json_file(path):
    with open(path) as f:
        return json.load(f)


def main():
    root = read_json_file(os.path.join(__dir__, 'Pipfile.lock'))

    for name, pkg in root["default"].items():
        version = pkg["version"]
        sep = lambda i: "" if i == len(pkg["hashes"]) - 1 else " \\"
        hashes = [f'--hash={t}{sep(i)}' for i, t in enumerate(pkg["hashes"])]
        tail = '' if len(hashes) == 0 else f' {hashes[0]}'
        print(f'{name} {version}{tail}')
        for h in hashes[1:]:
            print(f'    {h}')


if __name__ == "__main__":
    main()

@Zebradil Terima kasih! Solusi Anda benar-benar bekerja untuk saya.

  • Saya pertama kali menginstal alat jq menggunakan brew install jq
  • Kemudian gunakan skrip Anda untuk menghasilkan requirements.txt dari Pipfile.lock

Sepertinya ini dapat diselesaikan dengan flag --keep-outdated , atau apakah saya salah?

pipenv lock --keep-outdated -d -r > requirements.txt

PS itu adalah flag verbose yang mengganggu untuk menyelesaikan ini

Sayangnya @jacobisaliveandwell bendera --keep-outdated tampaknya memperbarui subdependensi: https://github.com/pypa/pipenv/issues/3975

@paytonrules Itu bug, tetapi semangat bendera masih menjadi jawaban untuk masalah ini.

PS Tidak perlu diacungi jempol untuk itu :-(

Hanya ingin menyebutkan bahwa dari solusi yang dinyatakan, ada perbedaan:
pipenv run pip freeze mengembalikan nama paket peka huruf besar/kecil (mis. PyYAML )
pipenv lock --requirements mengembalikan semua nama paket huruf kecil (mis. pyyaml )

@Darkless012 Anda harus membuka tiket lain yang menjelaskan itu, dan merujuk masalah ini sebagai terkait.

Bash murni, hanya paket, tidak ada yang lain, jika seseorang tidak dapat atau tidak ingin menginstal jq, untuk berjaga-jaga jika itu membantu seseorang,

cat Pipfile.lock \
  | grep -B1 '"hashes"\|"version": ' \
  | grep -v '"markers": \|"hashes": ' \
  | grep ": {\|version" \
  | sed -e 's/: {$//g' \
  | tr '\n' ',' | tr -s ' ' ' ' \
  | sed -e 's/, "version": "//g;s/", "/ /g;s/"//g;s/,//g' \
  | tr ' ' '\n' \
| grep -v "^$" > requirements.txt

Apakah ada sesuatu yang juga menyalin hash dari Pipfile ke requirements.txt (misalnya diberikan sesuatu seperti platform str) sehingga pip install --require-hashes berfungsi?

$ pip install --help
# ...
  --require-hashes            Require a hash to check each requirement against, for repeatable installs. This option is implied when any package in a
                              requirements file has a --hash option.

Anda dapat menggunakan micropipenv yang dapat mengonversi file Pipenv.lock (juga puisi.lock) ke requirements.txt (persyaratan mentah.txt atau kompatibel dengan pip-tools). Lihat https://github.com/thoth-station/micropipenv/#micropipenv -persyaratan--micropipenv-req

Apakah halaman ini membantu?
0 / 5 - 0 peringkat