ロックせずに既存のPipfile.lock
からrequirements.txt
ファイルを生成するにはどうすればよいですか?
pipenv lock -r
を実行すると、既存のPipfile.lock
が無視され、ロックプロセスが再度実行されます。
これには回避策があります。
$ pipenv sync
$ pipenv run pip freeze
私の特定の状況では、Dockerイメージを構築し、 Dockerfile
で$ requirements.txt
を使用しています。 requirements.txt
を作成できるようにするためだけに、ホストマシン上に仮想環境を作成することは避けたいと思います。
Pipenvはこれを行う方法を提供していません。pipfile-requirementsなどの他のpipfileユーティリティライブラリを探すことができます。
あなたが実行することができます
pipenv run pip freeze > requirements.txt
笑、私はすでにそのライブラリについて言及しました。
私は個人的に、そのための専用のライブラリを持っているのが嫌いです。 また、チームメンバーがすでにjq
またはその他の汎用ツールをインストールしている可能性が高くなります。
あなたも実行することができます
pipenv lock --requirements > requirements.txt
私が書いたように、それはあなたが期待するようには機能しません:
pipenv lock -r
を実行すると、既存のPipfile.lock
が無視され、ロックプロセスが再度実行されます。
つまり、更新を実行し、ディストリビューションを破壊する可能性があります。 requirements.txt
を生成してDockerfileで使用し、Dockerイメージを構築するとします。 アプリケーションはローカルで機能しますが、 pipenv lock
$を使用して$ requirements.txt
を生成すると、要件が互換性のないバージョンまたは壊れたバージョンに更新される場合があります(ただし、まれなケースです)。 そして、イメージを実行する前にこれを知ることはできません。 したがって、 pipenv lock
を実行した後、アプリを再度テストする必要があります。
jq
を使用したくない場合は、最初の投稿で提案したpipenv sync
のアプローチを使用することをお勧めします(これは更新されません)。
@Zebradil jq
ワンライナーアプローチは、 @frostming独自のpipfile-requirements
パッケージ(100行以上のPythonコード)よりもはるかに簡単です。これは、 jq
を既にインストールしているため、他の依存関係はありません。必要です、それは素晴らしいです。
しかし、数回のgitコミットの後、 pipenv lock --requirements
の出力とjq
がPipfile.lock
ファイルを介して出力するものの違いに気づきました。
jq
の出力には、 pipenv lock --r
が常に最初の行として挿入するものとは対照的に、最初の行として-i https://pypi.org/simple
がありません。jq
の出力には、パッケージの注釈は含まれていません。 例: pipenv lock --r
出力にはこの行appnope==0.1.0 ; sys_platform == 'darwin'
がありますが、 jq
出力ではappnope==0.1.0
です。 別の例は、 pipenv lock -r
がpexpect==4.7.0 ; sys_platform != 'win32'
$を生成するのに対し、 jq
はpexpect==4.7.0
$を生成しますが、これが重要かどうかはわかりません。jq
は、おそらくPipfile.lock
ファイルのパッケージ順序を取ります。これは、常にアルファベットと文字長の昇順で並べ替えられます。たとえば、 flask
はflask-sqlalchemy
の前にあります。 flask-XXXXX
パッケージに対して、 pipenv lock --r
はflask-sqlalchemy
$の後ろに$ flask
$を出力します。これは、 Pipfile.lock
の順序とは異なります。 最小のgitdiffが生成されないため、これは大きな問題です。 これはpipenv
のバグだと思います。こんにちは@ye 、メソッドの素晴らしい比較。 それは人々が彼らの特定の状況のために適切な解決策を選ぶのを助けて、警告を避けるのを助けるかもしれません。
はい、あなたが言ったように、 jq
で提案されたアプローチは機能が制限されています。 アノテーションやパッケージインデックスURLを追加するために拡張することは可能ですが、今のところこれは必要ありません。
生成されたrequirements.txtに違いが生じないようにするには、毎回同じアプローチを使用することを検討する必要があります。 同様に、異なるコードフォーマットツールを使用すると、一貫性のない結果が生じる可能性があります。 ですから、ここでは問題はありません。
あなたが実行することができます
pipenv run pip freeze > requirements.txt
これは、最初の投稿で回避策として述べたものです。
ただし、pipenv環境が同期されている(すべてのパッケージがインストールされている)場合にのみ機能します。
Pipfile.lock
から直接依存関係を抽出する方が便利です。jq -r '.default | to_entries[] | .key + .value.version' \ Pipfile.lock > requirements.txt
やあ、
あなたの解決策をありがとう。 同じ問題が発生しましたが、 pipenv lock -r
によって作成されたソースの定義も必要です。つまり、-i、-extra-index-urlです。 これは、私がプライベートソースを使用しているためです。
@Zebradilあなたがそう言ったと思います。
そこで、その機能を含む、Pythonでさらにもう1つの最小限の依存関係のないスクリプトを作成しました。 また、Pipfileでソースがそのように定義されている場合は、env変数を拡張します。
誰かが見てみたい場合は、ここに残しておきます: https ://gist.github.com/rcastill/dab85c234dd10fa7af56755116c75aee
それが他の誰かを助ける場合に備えて、結果にハッシュを含める方法は次のとおりです。
jq --raw-output '.default | to_entries[] | .key + .value.version + (.value.hashes | map(" --hash=\(.)") | join(""))' Pipfile.lock
これにより、次のようなエントリが作成されます
paramiko == 2.6.0 --hash = sha256:99f0179bdc176281d21961a003ffdb2ec369daac1a1007241f53374e376576cf --hash = sha256:f4b2edfa0d226b70bd4ca31ea7e389325990283da23465d572ed1f70a7583041
これにより、 pip
はハッシュを強制します。
元の要件ファイルに含まれていた要件のみを含める場合( ==
で特定のバージョンに既にロックされている場合):
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
が必要なのは、requirements.txtファイルに大文字と小文字が混在するパッケージ名が含まれている可能性があるためですが、Pipfileではpipenv install -r requirements.txt
それらを小文字にします。
Pipfile
(ロックファイルではない)をrequirements.txtファイルに変換する場合の小さなPythonスクリプトを次に示します。
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こんにちは、 https://github.com/frostming/pipfile-requirementsは便利ですが、なぜそれがpipenvに統合されなかったのですか?
@linusguanこのツールは、大きなpipenvライブラリをインストールしたくない人のために存在します。pipenvをインストールした場合は、 pipenv lock -r
を使用できます。
@frostmingpipfile.lockをサポートしていない他のツールで使用すると非常に便利だと思います。
pipenv lock -r
の問題は、pipfile.lockが更新されるため、他のツールと一緒に決定論的なビルドを作成するために使用できないことです。 pipenv lock -r --ignore-pipfile
のようなものが理想的です。
ハッシュを使用してPipfile.lockファイルからrequirements.txtを生成するさらに別のPythonスクリプトを次に示します。
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ありがとう! あなたの解決策は本当に私のために働いた。
brew install jq
を使用して$ jq
ツールをインストールしますPipfile.lock
requirements.txt
を生成しましたこれは--keep-outdated
フラグで解決できるようですが、それとも私は間違っていますか?
pipenv lock --keep-outdated -d -r > requirements.txt
これを解決するための厄介な冗長フラグであるPS
残念ながら、@ jacobisaliveandwell --keep-outdatedフラグは、サブ依存関係を更新しているようです: https ://github.com/pypa/pipenv/issues/3975
@paytonrulesこれはバグですが、フラグの精神がこの問題の答えです。
PSそのために親指を立てる必要はありません:-(
記載されている回避策から、違いがあることに言及したいだけです。
pipenv run pip freeze
は、大文字と小文字を区別するパッケージ名を返します(例: PyYAML
)
pipenv lock --requirements
は、すべて小文字のパッケージ名を返します(例: pyyaml
)
@ Darkless012それを説明する別のチケットを開き、この問題を関連するものとして参照する必要があります。
純粋なbash、パッケージのみ、他には何もありません。誰かがjqをインストールできない、またはインストールしたくない場合に備えて、誰かに役立つ場合に備えて、
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
pip install --require-hashes
が機能するように、ハッシュをPipfileからrequirements.txtにコピーするもの(たとえば、プラットフォームstrのようなものを指定)はありますか?
$ 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.
Pipenv.lock(またpoetry.lock)ファイルをrequirements.txt(rawrequirements.txtまたはpip-tools互換)に変換できるmicropipenvを使用できます。 https://github.com/thoth-station/micropipenv/#micropipenv-requirements--micropipenv-reqを参照してください
最も参考になるコメント
あなたが実行することができます