Pythonパッケージング 101#

初心者にやさしいチュートリアル

pyOpenSci Pythonパッケージングチュートリアルシリーズへようこそ。 これからのページのレッスンは、Pythonパッケージを作成するために必要なコアステップを説明します。

パッケージングチュートリアルのレッスンを示す図。Pythonパッケージとは何か、コードをpipでインストール可能にする、パッケージをPyPIに公開する、READMEとLICENSEファイルを追加する、PyPI用のメタデータを追加する、最後にconda forgeに公開する、の6つです。

このレッスンは、Pythonのパッケージングを始めるのに役立つ一連のレッスンの最初のものです。#

このチュートリアルは誰のためのものですか?#

このチュートリアルシリーズの内容は初心者に優しく、Pythonパッケージを作成したことがないことを前提としています。 しかし、Pythonパッケージの作成に関わるステップをよりよく理解することに興味があるのであれば、このコンテンツはまだ価値があるでしょう。

  • このシリーズでは、 Python Package Index (PyPI) にパッケージを公開するために必要なコアな要素について学びます。

  • 第2シリーズでは、パッケージのメンテナンスをサポートするために必要なインフラとドキュメントについて学びます。

学習目標

このレッスンでは Python パッケージの基本的な構成要素を紹介します。 このレッスンを読めば、次のことがわかります:

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

  • Pythonパッケージの5つのコアコンポーネントを列挙できます

  • 一般化可能なコードと特定の科学的アプリケーションをサポートするコードの違いを説明できます。

Pythonパッケージとは何ですか?#

高レベルでは、Pythonパッケージは、様々なタスクを実行するために使用できるツールボックスと考えることができます。

Pythonパッケージは基本的に特定のファイル構造を持つディレクトリです。 パッケージのディレクトリ構造の中に、.py で終わるファイル(Pythonスクリプトで見られるのと同じ拡張子)のモジュールがあります。これらのモジュールによって、Pythonコードをグループ化し、構造化することができます。各モジュールには関数とクラスが含まれており、それらはあなたの道具箱の中の道具だと考えることができます。

ハンマーやノコギリなど、さまざまな工具が入った工具箱のスケッチを示す図。

パッケージとは、コーディングツールが詰まった道具箱のようなものだと考えることができます。 ツールは関数かもしれないし、クラスかもしれません。 それぞれのツールは特定のことをよくします。#

Pythonパッケージはインストール可能#

パッケージはインストール可能で、パッケージのコード内の機能をどのPython環境にも追加でき、NumPyやMatplotlibのような科学的なPythonのコアパッケージをインポートするように、その機能をインポートできます。

import numpy

パッケージを環境にインストールすることで、異なるプロジェクト間でのコードの管理と再利用が容易になる。あなたのコードをパッケージとして構造化することは、あなたが作成したツールボックスのツールを共有し、他の人がそれを使って構築できるようにするために必要な最初のステップです。

なぜPythonパッケージを作るのか?#

Pythonパッケージを作りたいから作るかもしれません:

  • 異なるプロジェクト間でコードを使用する: 最も基本的なレベルでは、パッケージを作成することで、あなたのコードをPython環境にインストールすることができます。 これにより、ローカルとクラウドの両方のワークフローに関数やクラスをインポートすることができます。

  • Share your code: PyPIやcondaのような公開リポジトリでパッケージを公開する場合、 あなたのパッケージは、pipやcondaを使ってどのマシンにもコマンドひとつでインストールできます。

  • コードの周りにコミュニティを構築する: パッケージは、 (特にGitHubで公開されている場合) 複数の人が同じプロジェクトで作業することを容易にします。 git (GitHubで使われているシステム) のようなバージョン管理システムを使えば、コードベースへの長期的な変更を追跡するのがさらに簡単になる。 issueやプルリクエストのようなツールは、外部のユーザーがバグ修正に貢献したり、コードベースへの変更を受け入れるためのレビュープロセスを確立したりすることを容易にします。

  • コードを整理する: パッケージは、大規模なコード・プロジェクトを整理し、より小さく管理しやすいコンポーネントに分割するために使用できます。 この構造は、コードベースを維持する上でも、理解しやすくする上でも役立ちます。

パッケージを作成する前に考慮すべきこと#

他の人が使うPythonパッケージを作るには、かなりの時間と労力がかかります。 始める前に、以下のような目標について考えてください:

  • あなたのパッケージを利用すると思われる人

  • 人々があなたのパッケージをどのように使うか、またどのようなデータについて使うか(データが関連する場合)

  • ドキュメントやテストなどを追加する時間があるかどうか

  • メンテナンスできる可能性のある期間: いったん人々があなたのパッケージを使い始めると、彼らはそれを更新し、バグを修正し、質問に答えるために、あなたのメンテナチームに依存することになることを忘れないでください。

ユーザー向けのパッケージを作成する前に、上記のすべてを考慮することが重要です。

Pythonパッケージの要素#

図......これが残ればもっとここに。

Pythonパッケージの要素には、コード、ドキュメント、テスト、OSIが承認したライセンス、インフラが含まれます。 メインテナーは、バグを修正し、ユーザーの懸念に対処しながら、すべてが機能し、最新であることを確認する中核を担っています。#

Pythonパッケージの核となる要素は以下の通りです:

  • コード: パッケージのユーザーに機能を提供する関数とクラス

  • ドキュメンテーション: インストール手順、チュートリアル、サンプルは、ユーザがあなたのパッケージを使い始めるのを助け、貢献者やメンテナがバグを修正し、パッケージを保守するのを助けます。

    • CONTRIBUTING.md ファイル形式の貢献者ドキュメンテーションは、人々があなたのパッケージに貢献するのを助けるのに便利です。

    • Development Documentation は、メンテナと貢献者の両方が、パッケージのインフラストラクチャをどのように保守するかを理解するのに役立ちます。

  • テスト: これは、あなたのコードが本来の機能を発揮し、あなたや他の人が貢献しやすくなるようにするものです、 将来的にコードを修正更新します

  • ライセンス: オープンソースライセンス、あるいは OSI認可 ライセンスとは、他の人があなたのパッケージを使うことを許可するライセンスのことです。また、パッケージの要素をどのように再利用できるか、また再利用できないかに関する法的な方向性も示しています。

  • インフラ 更新、公開ワークフロー、テストスイートの実行を自動化します。 インフラストラクチャーには、GitHubやGitLabのようなプラットフォーム、noxやtoxのようなローカルでテストやツールを実行するツール、パッケージメンテナンスのステップを自動化する継続的インテグレーションなど、一連のものが含まれます。

pyOpenSciがパッケージで探すもの

pyOpenSciは、査読のために提出されたパッケージに対して、 最初のエディタチェック を行います。 これらのチェックは、パッケージを作成する際に、パッケージが持つべきものの基準として役に立つかもしれません。

パッケージは単なるコードではありません - インフラストラクチャー#

どの言語でも、パッケージは単なるコードではありません。 自分以外の人があなたのパッケージを使うことを期待するのであれば、高品質のコードを書くだけでなく、パッケージが有用なコミュニティリソースとなるための様々な要素も考慮すべきです。

GitHubまたはGitLabでのバージョン管理とパッケージの保存#

ほとんどのPythonパッケージは、GitHubやGitLabのようなオンラインバージョン管理プラットフォームにあります。 GitHubとGitLabはどちらもバージョン管理のために git を実行しています。 ソフトウェアをバージョン管理下に置くことは、時間の経過に伴う変更を追跡する一方で、コードベースへの変更が予期せず何かを壊してしまった場合に、履歴をさかのぼって変更を取り消すことができるからです。

あなたのパッケージをGitHubやGitLabで公開することで、あなたはコードを公開することになります。 これは、他の人があなたのコードを見ることができ、プルリクエスト(GitHub)/マージリクエスト(GitLab)/コードレビューワークフローを使って貢献することもできることを意味します。

GitHub & GitLab vs. Git

GitHubとGitLabは、バックエンドで git (バージョン管理ソフトウェア) を実行するオンライン (クラウド) プラットフォームです。 コンピュータ上でローカルに git を実行すると、GitHub や GitLab にファイルをアップロード (git push) したりダウンロード (git pull) したりすることができます。

issue かチケットトラッカー#

GitHubとGitLabは、どちらもissueのようなコミュニティ機能を提供しています:

  • メンテナや貢献者コミュニティとのコミュニケーション

  • ユーザーによるバグ報告、質問、新機能のリクエスト

  • あなたのパッケージのために取り組みたい機能強化や機能を公的に追跡することができます。

継続的インテグレーションと継続的デプロイメント#

GitHubとGitLabは、継続的インテグレーションと継続的デプロイメント (CI/CD) も提供しています。継続的インテグレーション (CI) とは、特定のイベントが発生したときに特定のジョブを自動的に実行するプラットフォームのことを指し、継続的デプロイメント (CD)とは、実行や構築だけでなく、最終的なアウトプットをどこかに公開することを指すCIの拡張です。

継続的インテグレーションの例:

  • 誰かがあなたのコードに変更を加えた場合、あなたのテストは異なるオペレーティングシステム上で実行され、コードはフォーマットの問題がないかチェックされます。

継続的デプロイの例:

  • PyPIにパッケージをリリースする準備ができたら、リリース時に継続的デプロイ操作をトリガーしてパッケージをPyPIに公開することがあります。

統合されたCI/CDは、コードの変更が予期せぬ事態を引き起こさないよう、ソフトウェアの保守を支援します。 また、コードに新しい変更が加えられるたびに、コードのスタイルや書式の一貫性を維持するのにも役立ちます。

図......これが残ればもっとここに。

科学的Pythonパッケージのライフサイクル。#

あなたのコードをPythonパッケージにするタイミングは?#

どのようなコードをPythonのパッケージにして、GitHubに置き、PyPIやconda-forgeに公開すればいいのか、疑問に思うかもしれません。

考慮すべき使用例がいくつかあります:

  1. 自分用の基本パッケージを作ります: 個人的に使用するためにパッケージを作成したいこともあるでしょう。 これは、コードをローカルにpipでインストールできるようにすることを意味するかもしれませんし、GitHubに公開したいと思うかもしれません。その場合、他の人があなたのコードを使うことを期待していないので、パッケージを更新する必要がある場合に、あなた自身と将来の自分のためのドキュメントしか用意できないかもしれません。

この種のパッケージの例としては、いくつかのプロジェクトにまたがって有用な関数のセットを書くことができます。 これらの機能をすべてのプロジェクトで利用できれば便利でしょう。

  1. コミュニティ向けパッケージの作成: また、自分だけでなく他の人にとっても有用なコードを作成することもあるでしょう。 その場合は、パッケージを作成してGitHubで公開し、他のユーザーもそれを使うかもしれないので、CI/CDパイプラインや課題トラッカーなどのGitHubのインフラを利用することも検討できるでしょう。あなたのパッケージを他の人たちにも使ってもらいたいので、LICENSE情報、ユーザーや貢献者のための文書、テストも含めておきたいです。 このタイプのパッケージはPyPIに公開されることが多いです。

例えば、すべての pyOpenSciパッケージ は、メンテナ以外の読者を想定して公開されています。

他の人が使用することを想定しているパッケージは、十分なスコープを持つべきです。#

Pythonパッケージのコードは、特定のテーマやユースケースにフォーカスしているのが理想的です。 このテーマは、パッケージの内容に幅を持たせる方法として重要です。

自分のコードが、いつ他の人に広く役立つものになるかを決めるのは、難しいことです。 しかし、自分自身に問いかけることができる質問が一つあります。それは、あなたのコードは特定の研究プロジェクトのために書かれたものですか?あるいは、あなたのドメインにおける複数のプロジェクトにまたがるより広範な応用が可能でしょうか?

研究プロジェクトのコードとの関連は?

Research Compendium とは、特定の研究プロジェクトをサポートするコード、データ、文書を整理したものです。 研究で使用された方法、データ、分析の包括的な記録を提供することで、研究の再現性と透明性を高めることを目的としています。

Pythonパッケージは、特定のタスクを実行するために使用できるモジュールのコレクションです。 これらのタスクは、数多くのワークフローに適用できるはずです。 そのため、Pythonパッケージは、特定のプロジェクトをサポートするResearch Compendiumよりも汎用性が高いです。

以下はよくスコープされたpyOpenSciパッケージの例です:

  • Crowsetta: は、動物の発声や生物音響データの注釈付けを行うために設計されたパッケージです。このパッケージは、ユーザー固有の研究ワークフローに関連する特定の個々の研究アプリケーションに焦点を当てるのではなく、科学者がさまざまなタイプの生体音響データを処理するのを支援します。

  • Pandera もまた、より広く使われているPythonパッケージです。 Panderaはデータの検査をサポートしているため、広範な研究用途にも使用できます。

例としてのMatplotlib

大規模なユーザーでは、Matplotlibが良い例です。 Matplotlibは一つのことをとてもよくやってくれます:

データの視覚的なプロットを作成します。

Matplotlibは、何千人もの人々が、様々な種類のデータを使った様々なプロットアプリケーションに利用しています。 Matplotlibのような広範なアプリケーションと大規模なユーザーベースを持つ科学パッケージはほとんどないでしょうが、自分のパッケージが何をするのかを調べるという考え方は依然として重要です。

コードはまた、クリーンで読みやすく、文書化されていなければなりません。#

パッケージ内のコードもまた、クリーンで読みやすく、十分に文書化されていなければなりません。

クリーンコード: クリーンなコードとは、表現力豊かな変数名を使い、簡潔で、繰り返しのないコードを指す。きれいなコードのためのベストプラクティスについては、今後のpyOpenSciチュートリアルで学ぶことができます。

読みやすいコード: 読みやすいコードとは、一貫したスタイルで書かれたコードのことです。blackやflake8などのリンターやコードフォーマッターを使用することで、パッケージ全体の一貫性を確保することができます。 コードフォーマッタの詳細はこちらです。

文書化されたコード: ドキュメント化されたコードは、ユーザーがコード内の関数やメソッドが何をするのか、また各関数の入出力要素が何なのかを理解するのに役立つdocstringを使って記述されます。 docstringsについては、こちらのガイドで詳しく説明しています。

パッケージをインストール可能にします - PyPIとconda-forgeに公開します#

Pythonのパッケージと環境#

NumPyやPandasをインストールするのと同じように、PythonパッケージをPython環境にインストールすることができます。 パッケージを環境にインストールすることで、特定のPython環境を有効にして実行したコードからそのパッケージにアクセスできるようになります。

パッケージを作成し、それをインストールする手順を示す図です。 最初の矢印はあなたのパッケージ、2番目はpip install packageと書かれています。2つ目の矢印は、PandasやNumPyなどのいくつかのパッケージがすでにインストールされているPython環境を表すボックスにつながります。あなたのパッケージも、pip installしたときに同じ環境にインストールされます。

あなたのコードをインストール可能にするためにPyPIに公開する必要はありません。 正しいファイル構造とプロジェクトのメタデータがあれば、PyPIに公開することなく、コードをローカルにインストールし、作業中のプロジェクトに使用することができます。 PyPIへの公開は、自分のコードを公開し、他の人と共有したいときに便利です。#

PyPI / Conda-Forgeへのパッケージの公開#

コードをローカルにダウンロードすることなく、パッケージを直接インストールできるようにしたい場合は、 PyPIconda-forge のようなリポジトリで公開する必要があります。

このチュートリアルでは、パッケージをPyPIに公開する方法 を学びます。

その後、 Grayskull ツールを使ってconda-forgeレシピを作成することができます。 このレシピをconda-forgeに投稿することができます。

conda-forgeの公開プロセスについてはこちらをご覧ください。

Graphic showing the high level packaging workflow. On the left you see a graphic with code, metadata and tests in it. Those items all go into your package. Documentation and data are below that box because they aren't normally published in your packaging wheel distribution. An arrow to the right takes you to a build distribution files box. That box leads you to either publishing to TestPyPI or the real PyPI. From PyPI you can then connect to conda-forge for an automated build that sends distributions from PyPI to conda-forge.

上の画像では、PyPIとconda-forgeでパッケージを公開する手順を見ることができます。 PyPIが要求する配布ファイルは sdistwheel ファイルであることに注意してください。コードを一般にインストール可能にする準備ができたら、PyPIで公開できます。いったんコードをPyPIにアップしたら、conda-forgeに公開するのは簡単です。 Grayskullパッケージを使ってレシピを作成し、conda-forgeレシピリポジトリでprを開きます。このプロセスについては、 conda-forgeのレッスン で詳しく学びます。#

やった、あなたのパッケージにはユーザーがいます! さて、どうしますか?#

あなたのパッケージを使うコミュニティが大きくなるにつれて、あなたはユーザーや貢献者、その他あなたのパッケージと交流したい人たちを管理することになるかもしれません。開発に飛び込む前に、これらすべてを考慮することが重要です。 コミュニティーの中にユーザーベースができれば、人々はあなたのコードに依存するようになり、その使い方の指示を必要とするようになります。

コミュニティをサポートするために、以下のようなものを追加したいです:

コントリビューターとメンテナーのサポート

他の人があなたのコードを使用し、貢献することを意図しているのであれば、誰がそれを長期にわたって保守するかを検討しましょう。あなたは、新しい貢献者候補があなたのパッケージへの貢献を始められるようにするための 貢献と開発 ガイドと、コミュニティの交流があなたにとっても貢献者やメンテナチームにとっても健全であり続けるようにするための 行動規範 が欲しいでしょう。

上記の要素は、今後のパッケージのメンテナンスにおいても重要です。 メンテナンスができなくなった場合、あるいは単に追加的な助けが欲しい場合、開発、そしてドキュメントの貢献は、新しいメンテナへの参加を支援します。


次のレッスン#

今後のレッスンでは、公開された、メンテナンスが容易になり、他の人が貢献しやすくなり、他の科学者が使いやすくなるPythonパッケージのインフラについて学びます。しかし、まずはPythonパッケージを公開するという最初のゴールに到達してもらいたいと思います。

この次のレッスンでは、インストール可能な Python パッケージの基本的な作り方を学びます。コードをpipインストール可能にします