PyPICloudを使って、Pythonの野良パッケージを公開する

あまり他の人が使わなそうな自作PythonパッケージをプライベートPyPIを使って公開してみています。

Pythonコードの共通化とパッケージング

Pythonのコードを書いたりしていると、同じような処理が出て来ることがちょくちょくあります。

もちろん普通にコピペで使いまわしても全く問題ないのですが、 GitHubなどに公開しておいたりすると、困ってそうな人の眼に止まってたりするので良いですね。

この時に「他の人も使う」ということをイメージすると、パッケージの体裁を整えるのは、 様々な方面で有効になっています。

パッケージをどう公開するか問題

Pythonパッケージ管理には、 pip コマンドを使います。 このコマンドで指定するパッケージは、いくつかのフォーマットに対応しています。 以下のような公開アプローチを取ることが出来ます。

PyPI

pipがデフォルトで参照先にしているパッケージ管理サービスです。 pip install package-namepackage-name 部分がURLの類でない場合は、 基本的にここを参照します。

別に気にせずここにアップロードしてしまえば良いのですが、 名前空間の概念は無いため「原則として使い始めたパッケージ名は責任を持つ」 ということになり、ちょっと躊躇してしまいます。

(とはいえ、普通に他人が使いそうな気がしたら、なるべく使うようにしているのですが)

GitHubなどのリモートリポジトリ

pip install git+https://github.com/xxxxx/xxxxx などのように、 パッケージ名の部分に種別+プロトコルを明示したリポジトリURLを指定すると、 リポジトリのフェッチをした上でインストール処理をしてくれます。

パッケージ済みファイルの容易をせずに済むので、提供側としては楽なのですが、 インストールする側でgitクライアントを用意しないといけないのがちょっとつらいところです。

(この手の話は、Dockerイメージ上でのインストールだと起こったりします)

アーカイブファイル提供

pip install https://example.com/python-package.whl などのように、 パッケージ名の部分にパッケージがまとまっているファイルURLを指定すると、 ファイルのダウンロードをした上でインストール処理をしてくれます。

パッケージをファイルとして用意する手間がややかかりますが、 wheelパッケージの提供を出来るのであればインストール側はかなり楽です。

独自PyPI

今回の主役

特定個人だけがアップロード出来るPyPI環境を用意して外部公開することで、 通常のPyPIと合わせてキレイに自作パッケージを利用できるようになります。

pip intall package-name --extra-index-url https://pypi.attakei.net/simple/ という形式で追加の独自PyPIを追加することで、 「通常のPyPIと独自PyPIのどちらかもパッケージを探してインストールする」という振る舞いをしてくれます。

というわけで、自分用に独自PyPIを用意して、 「公開したいけど本家PyPIに置くのはちょととためらわれる」パッケージは ここで管理してみようと試みました。

PyPICloud

PyPICloudはプライベートでPyPIサーバーを動作させるための実装の一つです。

バックエンドにある次の2要素を扱い、 管理下にあるパッケージ情報を本家PyPIと同じAPIで提供できるようになっています。

  • パッケージ本体を管理するストレージ

  • メタデータをキャッシュするデータベース

blockdiag Storage Cache PyPICloud

PyPICloudの基本構造

名前の通りクラウドサービス環境下で動くことを想定しており、 例えばストレージはGSCやS3用のアクセスをする仕組みがあらかじめ提供されています。

ストレージやキャッシュの部分は、インターフェースも用意されているので、 「ストレージ/キャッシュに○○○を使いたい」といったケースでも、 自分で実装することで対応が可能です。

用意したPyPICloud環境

https://pypi.attakie.net/

構成

blockdiag GCS for Storage Firestore for Cache Cloud Run for PyPICloud Firebase Hosting

自分用PyPICloudの基本構造

GCP上に構築して、ストレージにGCSを、メタデータのDBにはCloudSQLではなくFirestoreを据えています。 WebサーバーはCloud Runで動作させて最終的にFirebase Hostingでラップする、 安定の従量課金構成です。

そうそう内容が変わらないパッケージ本体やサイトの静的ファイルは長めのCache-Controlを設定しています。

そして、 キャッシュにFirestoreを使うライブラリが無いので、作りました。 需要がわからなすぎたので、今回PyPICloud環境上でホスティングしています。

所感

自分がライブラリ/基盤指向の強いタイプのためか、結構楽しんで環境用意できました。

こうやってプライベート空間に閉じさせられる環境を持つのは、 ミニマムながら一定の需要はあると思いたいです。

なお、PyPI本体にアップロードするより気楽なので、ミニマムなピンポイント需要を持つライブラリも、 パッケージとして扱えるようにこまごまパッケージングしていければと考えてます。