はじめに
本稿は下記ドキュメントの意訳です.
本ページの全ての著作権は PyPA に帰属します.
Python Packaging Authority
https://www.pypa.io/en/latest/
An Overview of Packaging for Python
Pythonは,様々な用途を実現可能なプログラム言語としてデザインされており,ウェブサイトや工業用のロボット,また友人と一緒に遊ぶためのゲーム,その他様々なものを作り上げることが出来ます.
全てのPythonプロジェクトが必ず考える「ユーザはだれか」「どの環境で動くことになるか」といった問に応えるために,Pythonは柔軟である必要があります.コーディングの前にパッケージング方法を考えることは,奇妙に思えるかもしれませんが,将来的に頭を悩ます種を避けることができるでしょう.
この概要では,数多く存在するPythonのパッケージ方法を選ぶ判断基準を提供します.
配布方法を決める前に考えるべき問い
- あなたのソフトウェアのユーザは?
そのソフトウェアは他の開発者が開発するためのもの?データセンターのオペレーターが使うもの?もしくはソフトウェアから縁遠い人々が使うもの? - そのソフトウェアはどこで動く想定?
サーバ,デスクトップ,モバイル端末,もしくは組み込みデバイス? - そのソフトウェアは,単体でインストールするもの?もしくは大きなデプロイ用のバッチの中で?
上記に対する答えだけでも様々な組み合わせがあるように,パッケージ方法は,あなたの目的や置かれている環境によって様々です.本記事では,あなたに適したパッケージ方法を紹介します.
Pythonライブラリとツールのパッケージ化
PyPI, setup_py, wheelファイル.これらはPythonで書かれたコードの配布方法のごく一部にすぎません.
これからしばらく,あなたのソフトウェアは開発者向けだと想定してパッケージ化の方法を紹介します.もしそうでない場合(非技術者や組み込み系を対象としている場合)は,「Pythonアプリケーションのパッケージング」セクションまで飛ばしてください.
Pythonモジールの配布
標準ライブラリのみを使用しているスクリプトをユーザ間で共有するときは,EmailやGitHub gistsなどでそのまま共有します.その際は下記を十分に確認しましょう.
- ユーザ間で互換性のあるPythonのバージョンが使われているか
- 標準のライブラリのみを本当に使用しているか
しかしこの方法はスケールしません.上記の2つに反する場合,もしくは複数ファイルから成り立っている場合は他のオプションを取ります.
ソースの配布
複数のファイルから構成されたコードの場合,多くの場合はディレクトリー構造を持ちます.そのコード群が,Pythonのファイルのみを含み,尚且つデプロイ先のPythonのバージョンをサポートする場合,Pythonの標準パッケージングツールを使用し配布用ソース群(source distribution package) 略して sdist を使用しましょう.Pythonのsdistは1つ以上のパッケージ/モジュールを含む圧縮ファイルです.作り方はこちら. から学ぶことができます.
次のセクションでは,あなたのコードがPython以外のコードや,パッケージを含む場合に使用可能な方法を説明します.その方法は,純粋なPythonライブラリーを使用する場合でも多くのメリットがあります.
実行ファイルの配布
Pythonの実用性は,Python以外の言語で実装された多くの実用的なライブラリに支えられています.このライブラリを含んだコードを配布する場合,バイナリ形式 別名 wheelで配布する方法がベストです.配布先がビルド環境を持つとは限らないためです.また,Pythonのみで構成されたpackageでもこの方法が好まれます.配布先にてsdistをビルドしない分,インストールが高速だからです.sdistもしくはwheelだけが必要とされる特別な環境ではない限り,その両方を公開することが標準的です.Packaging Python Projects
このチュートリアルは,PyPIを使用したsdistとwheel両方の作成方法です.
Pythonアプリケーションのパッケージング
ここまでは,Python標準の配布用ツールについて説明しました.それらが対象としていたのは,既にPythonの実行環境が整っていたり,packageのインストール方法を知っている人のみです.setuptools entry_points.のような技術に頼ることもできます.
しかし,ライブラリは完全なアプリケーションではなく構成要素です.アプリケーションの配布には全く別の技術が存在します.
ここから先,いくつかのセクションにて,アプリケーションをデプロイする先の環境別にパッケージング方法を整理します.
フレームワークに依存している場合
ウェブサイトのバックエンドやネットワークサービスといったPythonアプリケーションでは,大体の場合,フレームワーク自体がデプロイ方法やパッケージ方法を持っています.また,Webフロントエンドやモバイルクライアントにも便利なものがありますが,それ以上に複雑です.
上記の場合,フレームワークが持つデプロイやパッケージ方法を起点に,遡って作業すると良いでしょう.また,一部のフレームワークは他のセクションで紹介したデプロイシステムを内包しており,用意されている手順にそのまま従うことが,簡単かつ一番信頼の置ける方法となります.
もし,プラットフォームとフレームワークが見えない部分でどのように連携しているか疑問に思ったなら,これ以降のセクションを読むと良いでしょう.
PaaSの場合
HerokuやGoogle App EngineといったPlatform-as-a-Serviceを使っており,それらが定義している開発パターンに従っている場合は,各々のガイドに従ってください.パターンに沿っていない場合は,これ以降のセクションを参照してください.
ブラウザ or モバイル アプリケーションの場合
近年,Pythonでフロントエンドやモバイルアプリをコーディングすることが可能となりました.プログラミング言語はお馴染みですが,デプロイとパッケージ方法は全く新しいものです.もし下記の新しいフレームワークを使う予定の場合は,それぞれのガイドを参照してください.
もしあなたが,フレームワークやプラットフォームを使わない場合,もしくは上記フレームワークで使われている技術や手法に興味がある場合は,以降のセクションを読み進めてください.
Pythonがプリインストールされている場合
MacOSや多くのLinuxOSにPythonが標準搭載されて久しい今,あなたのソフトウェアをデータセンターや開発者やデータサイエンティストのPCに配布する場合に,Pythonがプリインストールさていると期待することは理にかなっています.
このパターンに用いることができる技術は下記の通りです.
ソフトウェア配布用エコシステムを使用する場合
長い間,MacやWindowsはパッケージマネジメント用の仕組みを標準搭載しておらず,アプリストアを搭載した近年においても,主なターゲットユーザは開発者ではありませんでした.開発者は苦悩の末,Homebrewなどの,独自のパッケージマネジメントの仕組みを生み出しました.Python開発者にとってそれは,Anacondaでした.Anacondaは教育現場,データ分析,サーバサイドの開発を行う環境で一般的になりつつあります.
Anacondaを使ったビルド・配布方法はこちらで紹介しています.
似たような配布モデルが他にもありますが,特定のOSをサポートしていなかったりします.
Pythonを実行環境ごと配布する場合
全てのOSは必ず,プログラムを実行するなにかしらの仕組みを標準搭載しています.その実行プログラム自体に,PythonインタープリターとライブラリやPythonコードを埋め込むテクニックが多く存在します.
このアプローチはfreezingと呼ばれ,幅広い互換性とプログラムの即時実行性を提供しますが,複数の技術やツール,またそれなりの学習時間を必要とします.
これらがfreezingを行うための技術です.
- pyInstaller - Cross-platform
- cx_Freeze - Cross-platform
- constructor - For command-line installers
- py2exe - Windows only
- py2app - Mac only
- bbFreeze - Windows, Linux, Python 2 only
- osnap - Windows and Mac
- pynsist - Windows only
ここで挙げた多くは,単一ユーザの利用を想定しています.マルチコンポーネントから成り立つサーバアプリケーションを配布する場合は,Chef Omnibus.を参照してください.
ユーザ実行環境まるごと配布する場合
コンテナ化技術を利用することで,アプリケーション自体を軽量なイメージとして配布し,OSに設定することが可能です.コンテナ化技術についてはoperating-system-level virtualizationを参照してください.この技術は大抵の場合,Pythonやパッケージだけでなく,OS丸ごとイメージ化することになります.
Linuxサーバが配布先の場合に最もよく採用されます.下記の技術と最も親和性のあるからです.
カーネルまるごと配布する場合
大抵のOSは,パッケージ化されたアプリケーションを含む完全なOSイメージ(別名 VMイメージ)の実行環境をサポートしています.VMイメージの利用は熟成されたアプローチであり,データセンターの環境構築時に用いられる場合が殆どです.ですが,複雑な構成を持つアプリケーションもこの恩恵を受けることもできます.実現には下記の技術を用いられますが,Python固有のものではありません.
- Vagrant
- VHD, AMI, and other formats
- OpenStack - Pythonと広域のVMサポートを有するクラウド環境のマネジメントシステム
ハードウェアまるごと配布する場合
もっとも包括的な方法は,あなたのソフトウェアをインストールしたハードウェアをそのまま送ることです.ユーザが必要なのは電気だけです.
ここまでのセクションで説明してきた方法は主に技術者向けでしたが,この方法なら先進的なデータセンターから子供まで幅広いユーザに利用してもらえます.
Adafruit, MicroPython,もしくはよりパワフルなハードウェアにあなたのコードを埋め込み,データセンターやユーザの自宅に送ることで,プラグにつなげてすぐに利用可能になります.
その他
OSのパッケージ
ソフトウェア配布用エコシステムを使用する場合で触れたように,いくつかのOSはパッケージマネージャーを備えています.もしあなたが配布先にしているOSが特定済みならば,deb(Debian, Ubuntu向け)やRPM(Red Hat, Fedora向け)や,その他の標準でインストールされているパッケージマネージャーを使用します.FPMを使えばdebとRPMを同じソースから生成できます.
殆どのデプロイパイプラインでは,OS標準のパッケージマネージャーは,多くの構成要素の1つにすぎません.
virtualenv
Virtualenvsは長年,Pythonユーザとって必要不可欠なツールでした.ですが最近は見かけることが徐々に少なくなり,より高機能なツールにラップされています.特にパッケージングにおいては,
the dh-virtualenv toolや
osnapといったツールの根底に置かれて利用されています.
プロダクトを本番環境にデプロイする場合は,開発環境で行うようにpip installを使ってvirtualenvnにインストールする方法に依存しないでください.ここまでに説明した方法の方が優れたソリューションです.
セキュリティ
あなたのパッケージが,より低レイヤーに組み込むにつれ,パッケージのアップデートが困難になります.全てがより密接に結びつく為です.
カーネルのセキュリティ問題が発生したケースを考えてみましょう.例えば,あなたがコンテナを用いてデプロイしていた場合でも,カーネルはアプリケーションの新しいビルドを必要とせずにアップデートされてしまいます.例えば,あなたがVMイメージを使用してデプロイしていた場合では,新しくビルドし直さなくてはなりません.このような更新がセキュリティを強固にしているか,もしくは脆くしているのか.依然,議論されています.static versus dynamic linking.
最後に
Pythonのパッケージ化はちょっと困難な印象があります.これはPythonの高い汎用性の副産物です.いくつかある配布方法の使い分けを一度理解すれば,あなたが見ている色々な景色は,最もバランスがよく柔軟な言語を使用するために必要な小さな対価であることに気付き始めるでしょう.
Comments
Post a Comment