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
.
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
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 mengabaikanPipfile.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.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 dariPipfile.lock
lebih nyaman bagi saya:jq -r '.default | to_entries[] | .key + .value.version' \ Pipfile.lock > requirements.txt
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.
jq
menggunakan brew install jq
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
Komentar yang paling membantu
kamu bisa lari