自分の作ったパッケージをconda installできるようにする
以前から自分で作成したPythonパッケージをPyPIにリリースしていた。
https://note.yu9824.com/howto/pypi-package-release/
したがって、pip install <package-name>
とすることでインストールできた。しかし、この度conda install -c conda-forge <package-name>
でインストールしたいという要望をいただいたのでanaconda cloudにパッケージをアップロードする方法を学んだ。
https://github.com/yu9824/kennard_stone/issues/5
このときの手順をメモした。
環境
M1チップ搭載のMacbook Air 2020を使用。
% sw_vers
ProductName: macOS
ProductVersion: 12.3.1
BuildVersion: 21E258
経緯
PyPIにパッケージをリリースしていれば比較的簡単にアップロードできるようになっている。
このやり方に関して公式が説明してくれているサイト(英語)がある。
日本語では、この記事でパッケージをリリースする方法が書かれている。しかしこれはWindowsであり、少し状況が異なる。
したがって、自分で試行錯誤した結果をメモする。
ちなみに、Anacona cloudにアップロードするとき、自分自身のチャンネルにアップロードする場合とconda-forgeチャンネルにアップロードする方法とがある。
途中まで共通のため、まず自分用チャンネルにアップロードする方法から示す。
自分用チャンネルにアップロードする手順
やり方の概略は以下。
- ターミナル上で
conda activate base
などを実行し、base (環境によってはroot) 環境に入る conda install conda-build
をして、conda-buildパッケージをインストールするconda skeleton pypi <package-name>
を実行し、レシピを作成する- レシピをもとにパッケージを作成し、Anaconda cloudにアップロードする
パッケージの作成も正しいレシピが作成できていれば簡単なので肝はレシピの生成段階であると個人的には考えている。
なお、<package-name>
と書いた部分はご自身の行いたいパッケージの名前に変えて実行していただきたい。
1. base環境に入る
(base)....@...
となっていれば問題ない。インストールして、特に設定をいじっていなければ自動で入る設定になっている。
なお、base環境に勝手に入らないようにする設定もある。詳しくは以下。
https://note.yu9824.com/howto/migration-my-setup-macbook/#miniforge
2. conda-buildパッケージをインストールする
以下のコマンドをターミナルで実行し、インストール。
conda install conda-build
このパッケージはbase (root) 環境でないとインストールできない(らしい)。
3. レシピ (meta.yaml) を生成
正式なやり方(個人的に非推奨)
conda skeleton pypi <package-name>
このコマンドにより、パッケージ生成のためのレシピが生成される。
注意点
<package-name>
のディレクトリがカレントディレクトリの直下に生成されるので、同じ名前のディレクトリがないことを確認したのちに実行する必要がある。
そうでないとエラーを生じる。
特に重要なのはmeta.yaml
。必要であればここを書き換える必要がある。
自分は生成されたレシピを以下のように書き換えた。
https://github.com/conda-forge/kennard-stone-feedstock/blob/main/recipe/meta.yaml
個人的に非推奨にしている理由
私の確認した限り、特定の環境では失敗してしまう。
これについて以下の記事で検討した。
https://note.yu9824.com/error/conda-skeleton-error/
端的に言えば、Python 3.7以上もしくは、ARMチップである場合に正常に動作しない。さらにパッケージ名に”-“(ハイフン)が入っている場合も問題が生じる場合がある。
これを解決するためにdockerコンテナ上にPython3.6、AMDプロセッサ環境を構築し、かつ”-“を処理するシェルスクリプトを書いて対応した…
が、このような面倒な作業などする必要がなく、grayskullパッケージを使用することで解決できる。
個人的に推奨する方法
grayskullはconda-forgeチャンネルから簡単にダウンロードできる。
conda install -c conda-forge grayskull
あとは、以下の通りgrayskullコマンドを実行すれば自動的にmeta.yamlファイルを生成してくれる。
grayskull pypi <package-name>
これはあとから気づいたのだが--strict-conda-forge
というオプションをつけて実行するとconda-forge向けのより良いmeta.yamlが生成できるよう。
注意点
このときも<package-name>
のディレクトリがカレントディレクトリの直下に生成されるので、同じ名前のディレクトリがないことを確認したのちに実行する必要がある。
4. レシピをもとにパッケージを作成 + Anaconda cloudへのアップロード(自分用のチャンネル)
conda-forgeチャンネルの場合はこちら。
これ以降の工程に関しては、自分のチャンネルでインストールできるようにしたいか、conda-forgeチャンネルでインストールできるようにしたいかでやり方が異なる。
レシピをもとにパッケージを作成
以下のコマンドでアップロードするためのパッケージファイルを作成する。
conda build <package-name>
依存するパッケージをconda-forge
チャンネル経由でインストールする必要がある場合は、以下のようにチャンネルを指定しても良い。
conda build -c conda-forge <package-name>
作成の成功可否を確認する方法
作成したパッケージファイルが、正しく作成できたかを確認するためには、適当な仮想環境を新しく作成して--use-local
オプションつきでconda install
を実行することで確認できる。正しく作成が行うことができていれば、インストールすることができる。
たとえば、以下のように行う。
conda create -n test # testという名前の仮想環境を作成。名前はなんでも良い。
conda activate test # 先ほど作成した仮想環境に入る。
conda install --use-local -c conda-forge <package-name> # ローカルのレシピを使用してパッケージをインストールする。チャンネルはconda buildを実行したときに使用したチャンネルを指定すると良い。
正しく作成できていることが確認できた場合は以下のコマンドでbase環境に戻っておく。
conda deactivate
conda activate base
Anaconda cloudへのアップロード
事前にAnaconda cloudでアカウントを登録しておく必要がある。
現在base環境にきちんといることを確認して以下のコマンドを実行し、anaconda-clientパッケージをインストールする。
conda install anaconda-client
インストール完了後、以下のコマンドを実行してターミナル上で先ほど登録したAnaconda cloudアカウントにログインする。
anaconda login
求められる通りにユーザー名とパスワードを入力する。
その後、conda buildしたときに生成したXXX.tar.bz2
を探し、それを以下のコマンドでアップロードする。
anaconda upload /path/to/<package-name>-<version>-XXXX.tar.bz2
私の環境ではconda-bld
ディレクトリの下にアーキテクチャごと(もしくはnoarch)に生成されていた。そのファイルのパスを指定してuploadすることで完了する。
アップロードできたかはhttps://anaconda.org/<Username>/<package-name>
にアクセスして確認する。
conda-forgeチャンネルの場合
— ここまで共通 —
- 4. レシピをもとにパッケージを作成 + Anaconda cloudへのアップロード(conda-forgeチャンネル)
- conda-forge/staged-recipesをfork&clone
- ブランチを切って、レシピを移動し、commit
- pushしてpull requestを送る
- チェックリストやレビュー、テストの結果を元に修正を加える
4. レシピをもとにパッケージを作成 + Anaconda cloudへのアップロード(conda-forgeチャンネル)
conda-forgeチャンネルの場合は、conda-forgeが作成したGithub Actionsを使用してパッケージの作成およびアップロードがなされる。
それらを実行する手順について以下に示す。
conda-forge/staged-recipesをfork&clone
以下のレポジトリをforkする。
https://github.com/conda-forge/staged-recipes
これをcloneする。
git clone [email protected]:<your-github-id>/staged-recipes.git
ブランチを切って、レシピを移動し、commit
先ほどcloneしたリポジトリに移動する。
cd /path/to/staged-recipes
次に、以下のコマンドなどを利用して新しいブランチを作成した上で、そのブランチに移動する。
git checkout -b <package-name>
その後、レシピ(meta.yaml)をリポジトリ内の/recipes/<package-name>/meta.yaml
に移動させる。Finderを使ってもmkdir
でディレクトリを作成したあとにmv
コマンドやcp
コマンドを使用してもOK。
これをaddしてcommitする。
git add .
git commit -m "Add recipe of my <package-name> package."
pushしてpull requestを送る
git push origin <package-name> # originの後ろは、新しく作成したブランチ名
そうするとgithub上にpull request(以下PR)を送るボタンが出てくるので、送る。わからない場合は、公式サイトのドキュメントが詳しい。
チェックリストやレビュー、テストの結果を元に修正を加える
PRを送ると勝手にテストをしてくれ、かつチェックリストが作成される。チェックリストに準拠するようにPRのタイトルやmeta.yamlを修正する。テストを通過し、チェックリストすべてを確認してチェックをいれると、reviewerに診てもらえる。
修正した場合、pushすれば勝手にPRに反映され、テストがスタートする。
@conda-forge/help-python
to let them know that your recipe is ready for review.
とあるが、自分は使わなかった。これをせずとも診てもらえた。
mergeされればめでたくpublishとなる。
参考のため、自分が実際に送ったPRを以下に示す。
https://github.com/conda-forge/staged-recipes/pull/18779
パッケージの更新方法
めでたくpublishされると、<package-name>-feedstock
という名前のrepositoryが作成される。
自分の例だと以下。
https://github.com/conda-forge/kennard-stone-feedstock
パッケージの更新はこれに対してPRを送ることで行える。
手順は以下。
- feedstock repositoryをfork&clone
- ブランチを切る
- meta.yamlを新しいものに置き換える(生成方法は3. レシピ (meta.yaml) を生成と同様)
- 変更をcommit&push
- fork元リポジトリへPull Requestして指示に従う
肝はmeta.yamlを再度コマンドで生成し直すこと。手でファイルの一部を変更するだけでは基本的に成功しない。
もっと簡単にできるかも?
上記の手順を踏んだ後に気づいたのだが@conda-forge-admin, please add bot automerge
とタイトルにつけて<package-name>-feedstock
にてissueを立てればbotが自動的にPRを作成してくれるらしい。
参考
次更新する際は試してみたい。
参考
- Building conda packages with conda skeleton - conda-build
- 公式ドキュメント。自分のチャンネルからアップロードする方法。
- Anaconda Cloudへのアップロード - Pythonパッケージの作り方
- 自分のチェンネルからアップロードする方法。日本語。Windows。baseではなくrootなので環境がかなり違うのかも?と思っているが流れを把握するのに役立った。
- Publishing Your Python Package on conda and conda-forge
- conda-forgeチェンネルからアップロードする方法。
- How to publish a Python package on conda-forge
- 自作パッケージをconda-forgeに登録してみた - Zenn