PyPI ミラー

Python アプリケーションやサービスには依存関係があり、ほとんどの場合 pip を通じてインストールされます(Python パッケージレジストリである PyPI からプル)。Dockerfile の例:

RUN pip3 install onnx==1.14.0

信頼性の高い安定したビルドを目指す場合、これは問題になります。

  1. 依存関係リストを完全にピン留めすることは不可能です。上記で onnx 1.14.0 の正確なバージョンにピン留めしていても、onnx の依存関係は次のように指定されています:\

    numpy
    protobuf>=3.20.2
    typing-extensions>=3.6.2.1

    つまり onnx をインストールすると、任意のバージョンの numpy と、>=3.20.2 であれば任意のバージョンの protobuf が取得されます。これらのパッケージのいずれかに破壊的変更が入ると、アプリケーションが壊れます。また、取得されるバージョンはコンテナをビルドするタイミングに依存します。同じ Dockerfile を開発者マシンと本番環境で同時にビルドしても、ビルドキャッシュによっては大きく異なるパッケージリストになる場合があります。

  2. requirements.txt と並行してロックファイルを作成するパッケージマネージャー(Poetry など)があります(そしてそれらを使うべきです!)。それでも問題が発生する可能性があります:

    1. 後から新しい依存関係を追加する場合。ロックファイルは新しいプロジェクト開始時は正確でしたが、新しい依存関係を追加すると、パッケージマネージャーは依存関係グラフを再計算する必要があり、サブ依存関係の意図しないアップグレードが発生する可能性があります(poetry lock --no-update でも起こります)。

    2. 古いバージョンの依存関係を追加する場合。パッケージマネージャーは今日の Python パッケージレジストリ(依存関係が作成された時点ではなく)を使って依存関係ツリーを解決するため、サブ依存関係の新バージョン(例:上記の protobuf)が依存関係を壊す可能性に気づきません。

    3. 新しいプロジェクトではない場合、例えばインターネットで見つけた興味深いチュートリアルやサンプル(ほとんどの場合ロックファイルがない)を動かしたい場合。パッケージマネージャーは再び今日の Python パッケージレジストリを使用し、サブ依存関係の最新バージョンをインストールしますが、それらは古いアプリケーションとほぼ確実に動作しません。

  3. パッケージバージョンは Python パッケージレジストリから削除される可能性があります。依存関係とサブ依存関係の完全なリストをフリーズしていても、ビルドが壊れます。大企業でもこれを行っており、例えば Google は過去に jaxlib のバージョンを削除しています。

StableBuild は、完全な PyPI レジストリ(最も人気のある Python パッケージレジストリ)の日次コピーを作成することでこれらの問題をすべて解決します。パッケージリストを特定の日付にピン留めでき、上流でパッケージが更新または削除されても、常に同じパッケージが返されます。例:

pip3 install \
    -i https://your-domain.pypimirror.stablebuild.com/2023-11-18/ \
    onnx==1.14.0

これにより常に同じパッケージリストがインストールされます:

後から新しい依存関係を追加したい場合、同じピン留め日付を使用できます。依存関係ツリーはその日付のレジストリを使って解決され、サブ依存関係のバージョンがそのまま維持されます。

2023年9月21日からの PyPI レジストリインデックスの完全な日次コピーを保持しています。それ以前の日付にピン留めする場合、その日付のレジストリの状態を動的に計算します。ほとんどの場合は動作しますが、若干の差異が生じる可能性があります(例:削除されたパッケージは復元できません)。

以上です。Python パッケージリストが安定した信頼性の高いものになりました。🎉

古い Python サンプルを動作させる

StableBuild の PyPI ミラーの大きなメリットの一つは、正しい依存関係リストを手動で組み立てることなく、古い Python サンプルを簡単に復活させられることです。例えば、画像分類のために OlafenwaMoses/ImageAI revision e76f87212aarrow-up-right(2020年10月15日公開)を動かしたいとします。インストール手順はもう動作しません:

このサンプルは2020年10月15日の公開時には動作していたと考えられるため、その日付をピン留め日付として使用し、代わりに StableBuild で依存関係をインストールします。

(Ubuntu 20.04、Python 3.8、x86 でテスト済み。2020年10月時点では PyPI に TensorFlow の arm64 ホイールはまだありませんでした)

ヒントとコツ

Poetry で StableBuild を使用する

StableBuild は Poetry と併用できます。pyproject.toml に以下を追加してください:

これにより、すべてのパッケージが PyPI ではなく StableBuild 経由で取得されます。

すべてのパッケージをキャッシュしていますか?

いいえ。以下の場合にパッケージをキャッシュします:

  1. ファイルが初めてリクエストされたとき。以降のリクエストは StableBuild のキャッシュから提供されます。

  2. ファイル、バージョン、またはパッケージが PyPI から削除されたことを検出したとき。これらは PyPI の CDN からすぐには削除されないため、削除を検出したときにキャッシュできます。

毎日のインデックスの完全なコピー(レジストリに存在するパッケージとバージョンを保持)を持っています。削除されたファイルのキャッシュと組み合わせることで、キャッシュされたすべての日付にわたってすべてのパッケージの 100% カバレッジが実現されます。

日付でピン留めせずにパッケージをキャッシュしたい場合

特定の日付にピン留めしたくない場合(例:Poetry を使用しているため)でも、パッケージを自動的にキャッシュしたい場合(パッケージが削除された場合に備えて)、日付として live を使用できます。これにより、リクエストごとに現在の PyPI インデックスをクエリしますが、ファイルはキャッシュから提供されます(キャッシュにない場合は追加されます)。例えば、pyproject.toml ファイルで:

他のパッケージレジストリ

現在は PyPI のみをミラーリングしています。パッケージレジストリがパッケージのダウンロードに相対 URL を使用している限り、ファイルミラー を使用して代替パッケージレジストリをピン留めできます。

例えば、Nvidia パッケージレジストリ(https://pypi.ngc.nvidia.comarrow-up-right)をピン留めしたい場合。https://pypi.ngc.nvidia.com/onnx-graphsurgeonarrow-up-right のソースを見ると、パッケージに相対 URL を使用していることがわかります:

Nvidia からホイールをダウンロードするための相対 URL

Nvidia レジストリへのすべての呼び出しにファイルミラーのプレフィックスを付けるだけです。例:

実行後、onnx-graphsurgeon のパッケージインデックスとインストール済みバージョンの両方がキャッシュされます。これにより常に onnx-graphsurgeon 0.3.27 が返されます:

StableBuild のファイルミラーを使用した PyPI 互換レジストリのキャッシュ。pip の URL 処理により .whl URL は変形されますが、正常に動作します。

これはプライベートレジストリでも動作します。通常どおりに認証するだけで、最初のリクエスト時に認証情報が転送されます。ファイルミラー > 認証 / HTTP ヘッダーarrow-up-right を参照してください。

ミラーリングを希望する代替(公開)レジストリがあり、ファイルミラーが機能しない場合は、support@stablebuild.comenvelope までメールをお送りください。サポートの追加を検討します。

最終更新