PyPIにあるPythonパッケージをconda-forgeに公開する#

前回のレッスンであなたは以下のことを学びました:

  1. Pythonパッケージの最も基本的なバージョンの作り方 。 これは、あなたのコードをインストール可能にすることが必要でした。

  2. PythonパッケージをPyPIに公開する方法

  3. パッケージに READMELICENSE ファイルを追加する方法

  4. どのように pyproject.toml ファイルに PyPI が要求するすべてのメタデータと、ユーザがあなたのパッケージを見つけるのに役立つメタデータをセットアップするかです。

上記のレッスンをすべて終えたなら、conda-forgeでパッケージを公開する準備が整いました。

重要: パッケージをconda-forgeに公開する練習はしないでください。 conda-forgeに公開するのは、pypi.orgにメンテナンスする予定のパッケージがあるときだけにしてください。

学習目標

このレッスンで学ぶこと:

  • Grayskullを使用してパッケージのconda-forge yamlレシピを作成します。

  • レシピ(yamlファイル)をconda-forge staged recipesリポジトリにプルリクエストとして提出します。

  • PyPIでパッケージの新しいリリースを作成することで、conda-forgeパッケージを維持します。

パッケージがPyPIに登録されたら、 grayskull ツールを使って簡単にconda-forgeに公開することができます。conda専用のパッケージをビルドする必要はない、conda-forgeはPyPIのソース配布ファイル (sdist) からビルドします。

Pythonパッケージの作成、ビルド、そしてPyPIとconda-forgeへの公開の流れを示す画像です。あなたのコードをPyPIが受け付ける配布ファイル(sdistとwheel)に変換します。そして、両方のディストリビューションを公開しているPyPIリポジトリへの矢印があります。PyPIからconda-forgeのレシピを作成し、conda-forgeに公開することができます。

両方のパッケージ配布(ソース配布とホイール)をPyPIに公開したら、次にconda-forgeに公開します。conda-forgeでパッケージをビルドするには、PyPIでのソース配布が必要です。conda-forgeに公開するためにパッケージをリビルドする必要はありません。#

conda-forgeとは何ですか?#

conda はオープンソースのパッケージと環境管理ツールで、Anaconda.org のさまざまなチャンネルからツールをインストールするために使用できます。

チャンネルとは、パッケージ群が保存され、 conda install packagename のようなコマンドでインストールできる特定の場所と考えることができます。 conda チャンネルの場合、defaults チャンネルなど、いくつかのチャンネルは Anaconda (社) によって管理されています。 どのパッケージが defaults チャンネルで利用可能かを決定できるのは Anaconda だけです。しかし、conda-forge (とbioconda) チャンネルはコミュニティが管理するチャンネルです。 誰でもこれらのチャンネルにパッケージを投稿できますが、公開するには staged-recipesのGitHubリポジトリ での技術レビューに合格しなければなりません。

condaチャンネルについて詳しくはこちら。

Python package repositoriesというタイトルのグラフィック。 PyPI でホストされているものは pip install でインストールできます。 condaチャンネルでホストされているパッケージはconda installを使ってインストールできます。 その下に2つの行があり、一番上の行には conda channels と書かれています。その隣には3つのボックスがあり、1つは conda-forge、コミュニティによって管理されているもの、bioconda、そして default - anaconda チームによって管理されているものです。 その下にPyPIサーバーという行があります。 PyPI - 誰でもPyPIに公開することができます、と test PyPI (PyPIをテストするためのテストベッドサーバ)。

Condaチャンネルは、パッケージをインストールできる様々なリポジトリです。 conda-forge はコミュニティによって管理されているため、誰でもレシピを投稿することができます。 PyPIもコミュニティによって管理されているリポジトリです。 誰でもPyPIにパッケージを投稿し、PyPIをテストすることができます。 conda-forge とは異なり、PyPI に投稿されたパッケージを手動でチェックすることはありません。#

conda-forgeに公開する理由#

特に科学的なPythonのエコシステムでは、condaを主要なパッケージマネージャ / 環境ツールとして使っているユーザーがたくさんいます。 したがって、conda-forgeチャンネルでこれらのユーザーがパッケージを利用できるようにすることは有用です。 場合によっては、conda-forge上のパッケージは、pipとcondaを混ぜてインストールする際に起こりうる依存関係の衝突を最小限に抑えることができます。これは空間生態系にとって特に重要です。

conda-forgeへの公開の仕組み#

パッケージをビルドしてPyPIに公開したら、conda-forgeに公開するために必要なものはすべて揃っています。 conda-forgeに公開するための追加のビルドステップは必要ありません。

Conda-forgeは、 前のレッスンでPyPIに公開した ソースディストリビューションから、以下で作成するレシピを使ってパッケージをビルドします。

Conda-forgeの公開手順#

conda-forgeへの公開に関連する手順を示す画像です。 詳しい説明は以下のキャプションをご覧ください。

conda-forgeに公開する手順は、PythonパッケージをPyPIに公開することから始まります。 PyPIに公開したら、yamlファイルのレシピを作成し、conda-forge staged recipesリポジトリに投稿してレビューを受けることができます。 レシピが承認されると、あなたのパッケージはconda-forge上のリポジトリ(フィードストックと呼ばれます)に登録されます。#

conda-forgeに公開する手順は以下の通りです:

  1. Pythonパッケージの配布ファイル (sdistとwheel) をPyPIに公開する

  2. これは、 grayskull[1] パッケージを使用して、conda-forge上でパッケージをビルドする方法を説明したyamlファイルです。

  3. レシピ (yamlファイル) をconda-forge staged recipesリポジトリにプルリクエストとして提出し、レビューを受けてください。 pyOpenSciからの投稿例はこちらをクリックしてください

  4. conda-forgeチームの誰かがあなたのプルリクエストをレビューしたら、いくつかの変更が必要になるかもしれません。最終的にプルリクエストは承認され、マージされます。

あなたのレシピがconda-forgeで承認され、マージされると、ユーザーはあなたのパッケージをインストールできます:

conda install -c conda-forge your-package

レシピを作成するのは一度だけです。 レシピが受け入れられマージされたら、リポジトリを管理するだけです。

conda-forge パッケージのメンテナンス#

あなたのパッケージがconda-forgeに登録されると、リポジトリはそのパッケージのPyPIリポジトリのリリースアクティビティを追跡します。 新しいソースディストリビューションで新しい PyPI リリースを作成すると、conda-forge はあなたの conda-forge リポジトリ(フィードストックとも呼ばれます)をビルドして更新します。

アップデートが処理されると、フレンドリーなconda-forgeボットがフィードストックの配布レシピを更新した新しいプルリクエストを作成します。

そのプルリクエストをレビューし、継続的インテグレーションのテストがすべてパスしたら、それをマージすることができます。

conda-forgeでパッケージを公開する方法#

あなたのパッケージをconda-forgeチャンネルに追加しましょう。 以下の手順が動作する前に、あなたのパッケージがPyPI上にある必要があることを覚えておいてください。また、conda-forgeを管理しているチームはすべてボランティアであることを忘れないでください。

  • conda-forgeに公開する前に、あなたのパッケージが(test.pypi.orgではなく)PyPI.orgにあることを確認してください。

重要

パッケージをconda-forgeに投稿するのは、長期的にメンテナンスするつもりである場合だけにしてください。

ノート - このチュートリアルは、あなたのパッケージをconda-forgeに載せる手助けをすることを目的としています。この処理に関するcondaの公式ドキュメントは こちら

ステップ1: grayskullをインストールする#

まず、 grayskullをインストールします 。 pip を使用してインストールできます:

> python -m pip install grayskull

それともconda

> conda install -c conda-forge grayskull

このコマンドを実行するには、前のチュートリアルでhatchコマンドを実行するのに使ったのと同じシェル/ターミナルを使います。

注釈

pipx[2] を使用してgrayskullをインストールすることもできます。 pipxは、作成したPython環境すべてにパッケージをインストールするのではなく、複数のPython環境で利用できるようにしたい、よく使われるツールをインストールできるツールです。

ステップ 2: conda-forge staged-recipes リポジトリをフォークしてクローンします。#

  • 次に、シェルを開き、 conda-forge/staged-recipes リポジトリをクローンしたい場所に cd します。

  • conda-forge/staged-recipes GitHubリポジトリ をフォークしてクローンしてください。

  • フォークのメインブランチから投稿するのではなく、フォークに新しいブランチを作成してください。ブランチにパッケージ名をつけることをお勧めします。

git checkout -b your-package-name

  • bashで cdstaged-recipes/recipes フォルダに入れる。

staged-recipes/recipes ( pyospackage)
# Clone the repository git clone git@github.com:conda-forge/staged-recipes.git

次に、クローンした conda-forge/staged-recipes リポジトリに新しいブランチを作成します。 そのブランチを、あなたのパッケージと同じ名前にしたいかもしれません。

# Create a new branch called pyospackage git checkout -b pyospackage
➜ cd staged-recipes/recipes
➜ git branch
  main
* pyospackage

ステップ3: conda-forgeレシピの作成#

  • 次に、レシピディレクトリに移動します。

ここで ls を実行すると、レシピ例のあるexampleディレクトリがあることに気づくでしょう。

staged-recipes ( pyospackage) via 🐍 pyenv
➜ cd recipes

staged-recipes/recipes ( pyospackage) ls
example
  • 次に、 grayskull pypi your-package-name を実行してレシピを生成します。

 grayskull pypi pyospackage

#### Initializing recipe for pyospackage (pypi) ####

Recovering metadata from pypi...
Starting the download of the sdist package pyospackage
pyospackage 100% Time:  0:00:00   1.2 MiB/s|###########################|
Checking for pyproject.toml
pyproject.toml found in /var/folders/r8/3vljpqb55psbgb1ghc2qsn700000gn/T/grayskull-pyospackage-du0sf_a4/pyospackage-0.0.1/pyproject.toml
Recovering information from setup.py
Executing injected distutils...
Checking >> -- 100% |#                          |[Elapsed Time: 0:00:00]
Matching license file with database from Grayskull...
Match percentage of the license is 97%. Low match percentage could mean that the license was modified.
License type: MIT
License file: ['LICENSE']
Build requirements:
  <none>
Host requirements:
  - python
  - hatchling
  - pip
Run requirements:
  - python

RED: Missing packages
GREEN: Packages available on conda-forge

Maintainers:
   - lwasser

#### Recipe generated on /your/file/package/here/pyosPackage for pyospackage ####

# You should see a new directory created by grayskull after this run is completed.
staged-recipes/recipes ( pyospackage) ls
example         pyospackage

Tip

  • Grayskull はあなたのパッケージのメタデータを PyPI から取得します。ローカルにインストールしたパッケージは使用しません。

  • grayskull pypi your-package-name のステップを実行するにはインターネット接続が必要です。

grayskullを実行すると、PyPIからあなたのパッケージの最新のディストリビューションを取得し、それを使って新しいレシピを作成します。

レシピは、コマンドを実行した場所の、あなたのパッケージ名にちなんだ名前のディレクトリに保存されます。

recipes/packagename/meta.yaml

grayskull 出力の一番下にある、レシピファイルの保存場所も教えてくれます。

meta.yaml ファイルを開きます。 grayskullが作成する完成した meta.yaml ファイルは、以下の例のようになるはずです:

{% set name = "pyospackage" %}
{% set version = "0.1.8" %}

package:
  name: {{ name|lower }}
  version: {{ version }}

source:
  url: https://pypi.org/packages/source/{{ name[0] }}/{{ name }}/{{ name.replace('-', '_') }}-{{ version }}.tar.gz
  sha256: 43ec82da3a10752a5dbf2f0ef742e357803a3ddb400005f87e86534685bfb8a7

build:
  noarch: python
  script: {{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation
  number: 0

requirements:
  host:
    - python
    - hatchling
    - pip
  run:
    - python

test:
  imports:
    - pyospackage
  commands:
    - pip check
  requires:
    - pip

about:
  summary: A package that adds numbers together
  dev_url: https://github.com/pyopensci/pyospackage
  license: BSD-3-Clause
  license_file: LICENSE

extra:
  recipe-maintainers:
    - lwasser

ステップ 3b: バグフィクス - about:セクションにホームURLを追加します#

現在Grayskullには、レシピの home: 要素が入力されないという小さなバグがあります。これを入れないと、フレンドリーな conda-forge linter bot から エラーメッセージが表示されます

Hi! This is the friendly automated conda-forge-linting service.

I wanted to let you know that I linted all conda-recipes in your PR (recipes/pyospackage) and found some lint.

Here's what I've got...

For recipes/pyospackage:

The home item is expected in the about section.
  • これを修正するには、meta.yamlファイルをお好みのテキストエディタで開いてください。

  • そして、aboutセクションに home: 要素を追加します

レシピを作成すると、aboutセクションはこのようになります。

about:
  summary: A package that adds numbers together
  dev_url: https://github.com/pyopensci/pyospackage
  license: BSD-3-Clause
  license_file: LICENSE

以下で home: element を追加します。プロジェクトのホームページやウェブサイトがあれば、そのURLを使うことができます。そうでなければ、PyPIのランディングページを使うこともできます。

about:
  home: https://pypi.org/project/pyospackage/
  summary: A package that adds numbers together
  dev_url: https://github.com/pyopensci/pyospackage
  license: BSD-3-Clause
  license_file: LICENSE

ステップ 4: conda-forgeのテスト#

次に、 meta.yaml ファイルのtestsセクションを見てください。 最低限、自分のパッケージか、そのパッケージに関連する主要なモジュールをインポートして pip check を実行する必要があります。

pip check は、あなたのパッケージが適切な依存関係をすべて持って正しくインストールされることを保証します。

test:
  imports:
    - pyospackage # Test importing the package into a python environment
  commands:
    - pip check # check the package
  requires:
    - pip

さらに高度なテストを実施したい場合は、ここに追加することができます。 しかし、テストセクションをそのままにしておくこともできます。

ステップ 4: staged-recipesリポジトリにプルリクエストを提出します#

上記がすべて完了したら、 conda-forge/staged-recipes repository でプルリクエストを開く準備ができました。

  1. staged-recipesリポジトリのフォーク/ブランチからプルリクエストを提出してください。

  2. conda-forgeのメンテナはボランティアであることを忘れないでください。相手の反応があるまで辛抱し、相手とのコミュニケーションをサポートしてください。

Conda-forgeチェックリストヘルプ

Conda-forge Staged-recipes プルリクエストチェックリスト

conda-forgeにパッケージを投稿する際、プルリクエストテンプレートには、あなたが確実にカバーしたいチェックリストが含まれています。

以下では、そのリストの各要素を分解します。

プルリクエストテンプレートのチェックリストのヒント

-[x] このPRのタイトルは意味があります: 例 "updated meta.yaml" ではなく "Adding my_nifty_package" 。

翻訳: プルリクエストのタイトルが具体的であることを確認してください。 我々は次のようなものを提案します: <your package name> のレシピを追加

-[x] ライセンスファイルは例としてパッケージされています([ここ](https://github.com/conda-forge/staged-recipes/blob/5eddbd7fc9d1502169089da06c3688d9759be978/recipes/example/meta.yaml#L64-L73 を参照)) 。

翻訳: パッケージのソース配布物にLICENSEファイルを含める必要があります。 pyOpenSciチュートリアルに従ったのであれば、すでにLICENSEファイルがあり、MITライセンスを使っていると思われます。 hatch build を実行すると、conda-forge がパッケージのビルドに使用する出力 ソースディストリビューションファイル(tar.gz ファイル) にそのファイルがバンドルされます。

  • [x] ソースは公式ソースより。

翻訳: Pythonパッケージの公開に関する前回のレッスン で学んだように、あなたのパッケージがPyPI上にあるのであれば、問題はありません。 conda-forgeはディストリビューションを既知のリポジトリに公開することを推奨します。

-[x] パッケージは他のパッケージをベンダリングしません。 (あるパッケージが他のパッケージのソースを使用している場合、これらは別々のパッケージにするか、すべてのパッケージのライセンスをパッケージ化する必要があります)。

翻訳: あなたのパッケージのコードベースがあなた自身のものであり、それがすべて同じライセンスを共有しているのであれば、問題はありません。他のパッケージから取得したコードがある場合は、そのコードを宣言し、異なる場合はそのライセンスも含める必要があるかもしれません。これらのチュートリアルに従ったのであれば、あなたはベンダーのコードを持っていません。

-[x] スタティックライブラリーがリンクされている場合、スタティックライブラリーのライセンスがパッケージされます。

-[x] パッケージには静的ライブラリは同梱されていません。静的ライブラリーが必要な場合、 CFEP-18 に従います.

翻訳: スタティックライブラリーは、パッケージに組み込まれたパッケージのコピーを指します。もしあなたのパッケージが純粋なPythonパッケージであれば、スタティックライブラリが同梱されていないことを確認してください。

pyOpenSciチュートリアルはすべて純粋なPythonであり、リンクされた、あるいは出荷された(パッケージ配布に含まれる)形式の静的ライブラリは使用しません。

あなたのパッケージが、C++のような他の言語で書かれた拡張機能へのリンクを含む、より複雑なビルドを持つ場合は、メタデータにそれらの拡張機能の適切なライセンスを含めるようにしてください。

注釈

静的ライブラリについてもっと知りたいなら、 この概要 が役に立つかもしれません。

-[ ] ビルド番号は0。

翻訳: レシピのビルド番号は、パッケージのソース配布場所のすぐ下にあります。 number: 0 は、レシピのそのセクションに表示されるべきものです。

source:
 url: https://pypi.org/packages/source/{{ name[0] }}/{{ name }}/{{ name.replace('-', '_') }}-{{ version }}.tar.gz
 sha256: 01e31f5521973710d0d91b15a94491d4f8f8f54566322110098c0f2381dd09ab

build:
 noarch: python
 script: {{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation
 number: 0
  • [x] レシピでは、リポジトリ (例 git_url ) ではなく、tarball (url) を使用します。 (詳細は こちら)。

翻訳: ここでcondaは、あなたのGitHubリポジトリ配布へのリンクではなく、PyPI上のソース配布へのリンクを提供することを望んでいます。レシピのSourceセクションに url: セクションがあり、tar.gzで終わるPyPIのURLを提供していることに注意してください。これは、conda-forgeが使用するソースディストリビューションへのリンクです。

url: https://pypi.org/packages/source/{{ name[0] }}/{{ name }}/{{ name.replace('-', '_') }}-{{ version }}.tar.gz
  • [x] GitHubのメンテナセクションに掲載されているユーザーは、掲載の意思を確認するコメントを投稿しています。

Translation レシピを提出したら、レシピに記載されているすべてのメンテナが、あなたのパッケージの conda-forge バージョンのメンテナとして記載されても構わないという返事をすることを確認してください。

翻訳 コンダチームはボランティアで、私たちのコミュニティをサポートするために時間を費やしています。 彼らに助けを求める前に、まずは自分でトラブルシューティングを試みてください。

これが、練習としてconda-forgeに公開することをお勧めしない理由でもあります。

プルリクエストを作成すると、一連のCIアクションがビルドを実行し、パッケージのビルドをテストします。 conda-forgeのメンテナーは、あなたのレシピを良い状態にしてマージするためにあなたと協力します。

プルリクエストを作成した後、GitHubのインターフェイスであなたのパッケージに対して実行される5つのCIタスクを示す画像。

プルリクエストのCIステップがすべて実行されるまで待ちます。 この時点で、あなたのプルリクエストはconda-forgeのメンテナによるレビューの準備が整いました。#

場合によっては、CIですべてのチェックを成功させるには、少し手間がかかるかもしれません。 レシピがうまくビルドできない場合は、conda-forge メンテナチームに助けを求めてください。

辛抱強く返答を待ってください。

conda-forgeのステージレシピとCIの失敗

もしあなたのパッケージが純粋なPythonパッケージで、どのタイプのコンピュータ (Windows、mac、linux) にもインストールでき、アーキテクチャの要求がない場合 (noarch: Pythonまたはアーキテクチャの要求がないパッケージとして知られています) 、conda-forgeチームはLinux CI用のテストのみがパスすることを要求します。

そのため、WindowsとMAC OSのテストが失敗したとしても、それは予想されることです。 この場合、テストの失敗を心配する必要はありません。メンテナチームが、あなたのパッケージが公開されるよう手助けしてくれます。

レシピを提出したら、CIビルドが通過するのを待つことができます。 もしそれが通らず、その理由がわからない場合は、conda-forgeのメンテナーが解決してくれるでしょう。

あなたのレシピがビルドされマージされると、condaチームはあなたのために GemGISパッケージ用のリポジトリ と同じような新しいパッケージリポジトリを作成します。

おめでとう - パッケージをconda-forgeに追加しました。#

このプロセスの最後の部分は、リポジトリの管理です。次はそれを取り上げます。

conda-forgeフィードストックのメンテナンス#

PyPIで新しいリリースを作成するたびに、conda-forgeボットはそのリリースを認識し、新しくリリースされたバージョンのパッケージをリビルドします。このプロセスには1-2日かかることがありますので、気長にお待ちください。

conda-forgeのビルドが完了すると、 conda-forge feedstock の全メンテナにGitHubで新しいプルリクエストが開かれたことが通知されます。

プルリクエストを確認します。すべてのテストがパスすれば、マージできます。あなたのプルリクエストをマージした直後に、conda-forge リリースが利用可能になり、ユーザーはインストールできるようになります:

conda install -c conda-forge yourpackage

まとめ#

このチュートリアルシリーズを一通りご覧になった方なら、もうお分かりでしょう:

  1. Pythonパッケージとは何か を理解する

  2. コードをPython環境にインストール可能にする方法 を知る

  3. pyproject.toml ファイル、 README ファイル、 LICENSE と行動規範の作成方法を知っている。

  4. パッケージをPyPIに公開する 方法と

  5. パッケージをconda-forgeに公開する方法を知ります

以上が、Pythonパッケージを作成して公開するために必要な基本的な手順です。 今後のチュートリアルシリーズでは、パッケージのメンテナンスの基本について取り上げます。

脚注#