Python による非常に優れたオープンソースのアプリケーションは、パッケージ化に関しても優れています。この記事では、パッケージ化についての概要と、パッケージ化の基本的な方法について説明します。また、さらに一歩進め、パッケージ化に関連して、パッケージのバージョン管理と配布についても説明します。

Patrick T. Altman, VP of Engineering, Eldarion

Photo of Patrick AltmanPatrick Altman は Pinax の中核的な開発者であり、他にも多くのオープンソース・プロジェクトを作成し、それらに貢献しています。彼は現在、Eldarionの VP of Engineering です。それ以前には、後に AOL に買収された StudioNow の Principal Software Engineer でした。彼は現在テネシー州ナッシュビルに住んでおり、妻と 3 人の子供がいます。



2011年 11月 18日

オープンソース・プロジェクトを成功させる上で中心となるのは、パッケージ化です。そして適切なパッケージ化をするための重要な要素はバージョン管理にあります。プロジェクトはオープンソースであるため、パッケージを公開し、オープンソース・コミュニティーによる多くのメリットを実現したいものです。パッケージ化のメカニズムはプラットフォームや言語によって異なりますが、この記事では特に Python と Python のパッケージ化エコシステムに焦点を絞ります。この記事では、パッケージ化のメカニズムについて説明し、それを基礎として発展させられるようにします。また、即座に作業を始められるように実践的な例を示します。

なぜパッケージ化をするのか?

パッケージ化することは単に適切であるというだけではありません。ソフトウェアをパッケージ化する理由として、以下の 3 つの実用的な理由が挙げられます。

  • 使いやすさ
  • (バージョン管理による) 安定性
  • ディストリビューション

アプリケーションのインストールを可能な限り容易にすることは、ユーザーに対する配慮です。パッケージ化することにより、ソフトウェアが扱いやすくなり、インストールも容易になります。インストールが容易であれば、ユーザーはそのソフトウェアを容易に使い始めることができます。パッケージを PyPI (Python Package Index) に公開すると、pipeasy_install などのユーティリティーを利用してそのパッケージを容易に利用できるようになります (これらのツールについては「参考文献」のリンクを参照)。

また、ソフトウェアのパッケージをバージョン管理して提供することで、そのソフトウェアのユーザーが自らのプロジェクトにおいて依存関係を指定する際に、そのソフトウェアの特定のバージョンに対する依存関係として指定できるようになります。例えば Pinax のバージョンとして 0.9a2.dev1017 を指定するには以下のように表現します。

Pinax==0.9a2.dev1017

このように指定すると、そのプロジェクトで Pinax の 0.9a2.dev1017 リリースを使用するように強制することができます。

インターフェースが大幅に変わるような変更を後でリリースした場合にも、バージョン管理によって高い安定性を保証することができます。バージョン管理により、ユーザーは自分が入手しているものを正確に知ることができ、またリリース間の違いを容易に追跡することができます。さらに、プロジェクトの開発者は、どのバージョンを対象にコーディングを行っているのかを正確に知ることができます。

PyPI (または独自の配布サーバー) にパッケージを公開するための一般的な方法として、ソース・ディストリビューションを作成してアップロードする方法があります。ソース・ディストリビューションはプロジェクトのソースを配布可能な単位としてパッケージ化するための標準的な手段です。バイナリー・ディストリビューションを作成する方法もありますが、オープンソースであるためにはソースも配布するのが妥当です。ソース・ディストリビューションを作成すると、インターネット上のソフトウェアを検索、ダウンロードして自動インストールするツールを利用しやすくなります。このプロセスにより、ソフトウェアをローカルで開発する場合の作業が容易になるだけではなく、ソフトウェアのデプロイメントも容易になります。

つまり、ユーザーにとってソフトウェアの統合とインストールが容易になるようにし、信頼できるバージョン指定が可能になるような適切なバージョン管理手法を使用し、より広く配布されるようにパッケージを公開することで、そのプロジェクトが成功して広く採用されるようになる可能性が一層高まるはずです。プロジェクトが広く採用されると、より多くのコントリビューターが得られる可能性につながります。それはすべてのオープンソース開発者が間違いなく望むことです。


setup.py ファイルの詳細

setup.py スクリプトの目的の 1 つは、ソフトウェアをパッケージ化して配布サーバーにアップロードするための実行可能ファイルとして機能することです。よく使われる Python リポジトリーを見るとわかるように、setup.py スクリプトの内容はそれぞれ大幅に異なります。この記事では setup.py の基本部分に焦点を絞ります。さらなる詳細について探るには「参考文献」セクションを参照してください。

setup.py ファイルを使用すると、多種多様なタスクを実行することができますが、ここでは以下のコマンドを実行できるようにするための setup.py ファイルを作成します。

python setup.py register
python setup.py sdist upload

最初のコマンド register は setup.py スクリプト内にある setup() 関数から情報を取得し、このパッケージのエントリーを PyPI に作成します。このコマンドは何かをアップロードするわけではなく、プロジェクトに関するメタデータを作成し、後で PyPI にリリースをアップロードしてホストできるようにします。次の 2 つのコマンドは連結されており、sdist upload はソース・ディストリビューションをビルドし、PyPI にアップロードします。ただしその前に、.pypirc 構成ファイルを設定したり、実際に setup.py の内容を作成したりするなどの前提となる作業がいくつかあります。

まず、.pypirc ファイルを構成します。このファイルはホーム・ディレクトリーに配置されている必要がありますが、ホーム・ディレクトリーの場所はオペレーティング・システムによって異なります。UNIX、Linux、Mac OS X の場合には、cd ~/ と入力するとホーム・ディレクトリーに行くことができます。.pypirc ファイルには PyPI に対するクレデンシャルが含まれている必要があります (リスト 1)。

リスト 1. 典型的な .pypirc ファイル
[distutils]
index-servers =
    pypi

[pypi]
username:xxxxxxxxxxxxx
password:xxxxxxxxxxxxx

次に、PyPI にアクセスし、アカウントを登録します (無料ですので心配ありません)。PyPI に登録する際に作成したものと同じユーザー名とパスワードを .pypirc ファイルに記載し、pypirc ファイルの名前を必ず ~/.pypirc にします。

ここで、setup.py スクリプトを作成するためには、PyPI の index ページに表示する内容と、プロジェクトの名前を決める必要があります。最初に、私がさまざまなプロジェクトに使用している setup.py 用のテンプレートをコピーします (リスト 2)。インポート命令と関数をスキップしてテンプレートの一番下に注目し、皆さんのプロジェクトに合わせて何を変更する必要があるのかを見てください。完全なスクリプトへのリンクは「参考文献」に挙げてあります。

リスト 2. setup.py テンプレート
PACKAGE = ""
NAME = ""
DESCRIPTION = ""
AUTHOR = ""
AUTHOR_EMAIL = ""
URL = ""
VERSION = __import__(PACKAGE).__version__

setup(
    name=NAME,
    version=VERSION,
    description=DESCRIPTION,
    long_description=read("README.rst"),
    author=AUTHOR,
    author_email=AUTHOR_EMAIL,
    license="BSD",
    url=URL,
    packages=find_packages(exclude=["tests.*", "tests"]),
    package_data=find_package_data(
			PACKAGE,
			only_in_packages=False
	  ),
    classifiers=[
        "Development Status :: 3 - Alpha",
        "Environment :: Web Environment",
        "Intended Audience :: Developers",
        "License :: OSI Approved :: BSD License",
        "Operating System :: OS Independent",
        "Programming Language :: Python",
        "Framework :: Django",
    ],
    zip_safe=False,
)

まず、このテンプレートではプロジェクトに 2 つの異なるファイルがあると想定していることに注目してください。1 つ目のファイルは long_description のために使用されています。このファイルは setup.py と同じディレクトリーにある README.rst ファイルの内容を読み取り、その内容をストリングとして long_description パラメーターに渡します。このファイルが PyPI のランディング・ページに内容を追加します。そのため、このファイルの中でプロジェクトについて簡単に説明し、使い方の例を示すのは良い考えです。2 つ目のファイルはパッケージの __init__.py ファイルです。ここに明示的に記述されているわけではありませんが、VERSION 変数を設定する行によってパッケージがインポートされます。そしてパッケージがインポートされる際、Python は __init__.py ファイルを必要とし、そのモジュールの中で __version__ という変数が定義されていることを想定します。ここでは、この変数をストリングとして設定します。

# __init__.py
__version__ = "0.1"

では、入力の他の部分を見てみましょう。

  • PACKAGE はプロジェクトの中にある Python パッケージです。PACKAGE は __init__.py モジュールを含む最上位レベルのフォルダーであり、setup.py ファイルと同じディレクトリーになければなりません。例えば以下のような構成でなければなりません。
    /-
      |- README.rst
      |- setup.py
      |- dogs 
         |- __init__.py
         |- catcher.py

    つまりこの場合は dogs がパッケージです。

  • NAME は通常、PACKAGE 名と似ているか PACKAGE 名と同じですが、任意の名前で構いません。人々がそのソフトウェアを呼ぶ際の名前が NAME であり、そのソフトウェアは NAME という名前で PyPI に表示されます。そしてもっと重要な点として、ユーザーは NAME という名前のソフトウェアをインストールします (例えば pip install NAME など)。
  • DESCRIPTION はプロジェクトの簡単な説明にすぎません。1 文による説明で十分です。
  • AUTHOR と AUTHOR_EMAIL は文字どおり作成者の名前と E メール・アドレスです。この情報はオプションですが、そのプロジェクトに関して作成者に連絡を取りたい人のために E メール・アドレスを含めておくことは適切なプラクティスです。
  • URL はプロジェクトの URL です。この URL はプロジェクトの Web サイトや Github リポジトリー、その他任意の URL で構いません。この URL の情報もオプションです。

また、ライセンスや分類情報を提供することもできます。setup.py ファイルを作成するための詳細については Python のドキュメントを調べてください。(「参考文献」を参照。)


バージョン管理

バージョン管理はそれだけで 1 つのトピックになりますが、ここではパッケージ化のコンテキストにおけるバージョン管理について説明しておきます。というのも、適切なパッケージ化には適切なバージョン管理が必要だからです。バージョン管理はユーザーとのコミュニケーションの 1 つの形です。バージョン管理をすることで、ユーザーは高い安定性と信頼性を持った成果物を作成できるようになります。さらにはバージョン管理を通じて、ユーザーには何かを変更したことを伝えることになり、変更が行われた箇所に関して明示的な境界を設けることになります。

Python パッケージのバージョン管理に関する標準は PEP (Python Enhancement Proposal) 386 に記述されています (「参考文献」を参照)。この標準には実用的なルールが詳細に説明されています。PEP を読んで理解していなくても、さらには PEP に同意しない場合であっても、PEP に従った方が賢明です。PEP を見慣れている Python 開発者が次第に増えているからです。

また、バージョン管理は単に安定したリリースを PyPI にアップロードするためのものではなく、devNN 接尾辞を使用して dev リリースを作成する場合にも便利です。通常は、開発版を PyPI にアップロードするのは適切ではありませんが、パブリックな (またはプライベートな) 配布サーバーを独自にセットアップすることによって開発版を公開することは可能です。そうすれば、最新の開発版を使用しようとするユーザーは、そのバージョンを pip requirements.txt ファイルの中で参照することができます。以下はバージョン管理の例です。

1.0.1        # 1.0.1 final release
1.0.2a       # 1.0.2 Alpha (for Alpha, after Dev releases)
1.0.2a.dev5  # 1.0.2 Alpha, Dev release #5

パッケージの公開

ソフトウェアが公開されていない限り、そのソフトウェアを見つけてインストールすることは通常はできません。ほとんどの場合、PyPI にパッケージを公開する必要があります。.pypirc 構成ファイルをセットアップした後、setup.py に upload コマンドを渡すと、そのパッケージが PyPI に送信されます。通常はそれをソース・ディストリビューションのビルドと同時に行います。

python setup.py sdist upload

独自の配布サーバーを使用している場合には、その配布サーバーのロケーションに対して認証を行うためのセクションを .pypirc ファイルに追加し、アップロードの際にそのセクション名を指定することで、そのセクションの情報を参照します。以下はその一例です。

python setup.py sdist upload -r mydist

独自の配布サーバーのセットアップ

オープンソースの場合、独自の配布サーバーを使用する最大の理由は dev リリースの公開場所を提供するためです。PyPI は本来、安定版リリースのみで構成されているべきものだからです。例えば、PyPI に公開されている最新の安定版リリースをインストールするためには以下のようにします。

pip install MyPackage

しかし後で dev リリースを追加すると、上記のコマンドによって最新リリースをインストールすることになり、それは dev リリースをインストールすることを意味します。通常は、必ずリリースのバージョンまで指定するのが望ましいですが、すべてのユーザーがそうするとは限りません。そのため、バージョン番号が指定されない場合には必ず最新の安定版リリースが返されるようにする必要があります。

標準的な方法で pip を実行する場合のために安定版リリースのみを公開する一方で、パッケージ化された dev リリースをユーザーがインストールすることもできるようにする 1 つの方法は、独自の配布サーバーをホストする方法です。Pinax プロジェクト ( http://dist.pinaxproject.com) では、それをすべての dev リリースに対して行っています。(「参考文献」を参照。)

配布サーバーはサーバー上にあるファイルを HTTP (HyperText Transfer Protocol) で提供するための単なる索引にすぎません。索引を構成するファイルは以下のディレクトリー構造に従っていなければなりません。

/index-name/package-name/package-name-version.tar.gz

必要な場合には、Web サーバーの Basic-Auth を構成することで配布サーバーをプライベートにすることもできます。ソース・ディストリビューションをアップロードする機能も追加する必要があるかもしれません。そのためには、アップロードの処理や、ファイル名の構文解析、そして上記の構造を満たすディレクトリー・パスの作成のためのコードが必要です。いくつものリポジトリーをホストする Pinax プロジェクトには、この構造が採用されています。


pip と virtualenv

この記事は主にパッケージ化に焦点を絞りましたが、このセクションではパッケージを利用する場合に注目し、適切なパッケージ化とバージョン管理によってプロジェクトの利用者にどんなメリットがもたらされるのかを説明します。

pip は直接インストールすることもできるツールですが、私は virtualenv (「参考文献」を参照) の一部として pip を使用する方法を推奨します。virtualenv を使用すると Python 環境をすっきりと維持できるため、Pthon に関連するあらゆるものに virtualenv を使用するようお勧めします。仮想マシンによって複数のオペレーティング・システムを並列に実行できるのと同じように、virtualenv によって複数の Python 環境を並列に実行することができます。私は自分のシステムの Python には何もインストールせず、新しいプロジェクトやユーティリティーを扱うごとに新しい virtualenv を作成するようにしています。

virtualenv をインストールしたところで、以下のように実行してみましょう。

$ mkvirtualenv —no-site-packages testing
$ pip install Pinax
$ pip freeze|grep Pinax
$ pip uninstall Pinax
$ pip install —extra-index-url=http://dist.pinaxproject.com/fresh-start/ 
    Pinax==0.9a2.dev1017
$ pip freeze|grep Pinax

最初の pip install によって PyPI から Pinax がダウンロードされてインストールされたことに注意してください。pip freeze により、現在の virtualenv にインストールされたパッケージのすべてのバージョンが表示されます。pip uninstall はご想像どおり、virtualenv から Pinax を削除します。次に、開発版である Pinax バージョン 0.9a2.dev1017 を取得するために http://dist.pinaxproject.com にアクセスし、fresh-start リポジトリーからこの開発版をインストールします。

プロジェクトの利用者は、Web サイトへのアクセスや tarball のダウンロード、サイト内のパッケージへシンボリック・リンクするコードの作成などの作業は必要ありません (以前、私はこれらの作業を行っていましたが、それによって多くの問題が発生していました)。プロジェクトを提供する際に、適切にパッケージ化し、公開し、バージョン管理することで、利用者はこうした作業をまったくせずに済むのです。


まとめ

結論は、パッケージ化の芸術と科学を学ぶために、少し時間をかける価値があるということです。パッケージをバージョン管理することによってインストールが容易になり、安定性が高まることで、より多くのユーザーが皆さんのプロジェクトを採用するようになるはずです。この記事で説明し、「参考文献」にも挙げたテンプレート setup.py を使用することにより、皆さんのプロジェクトを素早く容易にパッケージ化できるはずです。適切なバージョン管理によってユーザーとコミュニケーションすることはユーザーに対する配慮であり、それによってユーザーはリリースごとの変更を容易に追跡できるようになります。そして、pipvirtualenv が広く採用されるようになるにつれ、(PyPI で公開する場合であれ独自の配布サーバーで公開する場合であれ) 公開されたパッケージを利用する人達の数も増えていきます。そのため、世界と共有したいプロジェクトは必ず公開するようにしてください。

この記事が、出発点として十分な情報を提供できたことを祈ります。「参考文献」には、さらに深く学ぶための資料を挙げてあります。質問がある場合には、Freenode のチャット・ルーム #pinax や #django-social などで遠慮なく私に連絡していただくか (ニックネームは “paltman” です)、あるいは Twitter (@paltman) で私をフォローしてください。

参考文献

学ぶために

  • PyPI について調べてください。
  • setuptools 0.6c11 のサイトを訪れ、Python パッケージを容易にダウンロード、ビルド、インストール、アンインストールする方法を学んでください。
  • PEP 0386 のサイトを訪れ、ディストリビューションをバージョン比較するモジュールに関して調べてください。
  • Python モジュールの配布方法に関して学んでください。
  • developerWorks の Open Source ゾーンにはオープンソース・ツールに関する情報やオープンソース技術の使い方に関する情報が豊富に用意されています。これまでに公開された Python 関連の他の記事もご覧ください。
  • developerWorks podcasts でソフトウェア開発者のための興味深いインタビューや議論を聞いてください。
  • Technical events and webcasts で最新情報を入手してください。
  • IBM オープンソース開発者にとって関心のある、世界中で今後開催される会議や業界展示会、ウェブキャスト、その他のイベントについて調べてみてください。
  • IBM とオープンソース技術、そして製品機能を調べ、学ぶために、無料の developerWorks On demand demos をご覧ください。

製品や技術を入手するために

  • pip について学び、pip をダウンロードしてください。
  • virtualenv について学び、virtualenv をダウンロードしてください。
  • この記事で使用したテンプレート setup.py を見つけてください。
  • Django の上に構築されたオープンソース・プラットフォーム、Pinax について調べてください。
  • 皆さんの次期オープンソース開発プロジェクトを IBM ソフトウェアの試用版を使って革新してください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source
ArticleID=773524
ArticleTitle=Python のパッケージ化に関するガイド
publish-date=11182011