ExactTargetのCLIを仕事の便利ツール的な感じで作っていたのをPyPIに公開してみました。↓
$ pip install et-cli
でインストールできるようになってますので、ExactTarget導入している開発者の方は良ければお使いください(日本ではほとんど居ないと思いますが…)。ツールの説明は別の記事として書こうと思います。まだまだ機能不全+クソコードな感じなのでもうちょい時間作って書いていかないとなー。
ということで、今回はコマンドラインツールをPyPIにパッケージ登録するやり方を書いていきます。
全体的な流れはこんな感じです。
- ディレクトリ構成決める
- setup.py作成
- testpypiにregister&sdist upload
- 本番pypiにregister & sdist upload
ディレクトリ構成と各ファイルの説明
完成形はこんな感じ↓.
├── LICENSE
├── MANIFEST.in
├── README.rst
├── bin
│ ├── et
│ └── et.cmd
├── etcli
│ ├── __init__.py
│ └── utils.py
└── setup.py
- setup.py:パッケージのメタデータを設定する場所
- LICENSE:ライセンス条文書いたやつ。多分なくても通ります。
- MANIFEST.in:パッケージとして配布するファイル群の中でデフォルトで取り込んでくれないファイル名を指定するファイルです。
- README.rst:READMEファイル。PyPIはreStructuredText形式に対応しています。マークダウン形式でもOKですが、PyPIではそのまま表示されちゃいます。
- bin/et, bin/et.cmd:コマンドラインのエントリポイントとなるPythonスクリプトです。et.cmdはwindows用です。
- etcli/init.py:パッケージ形式でモジュールを一括で取り込む場合は、init.pyを必ず入れます。中身は空でもOKですが、import文で取り込まれた時(今回はimport etcliが呼ばれたとき)にinit.pyが呼ばれるので、初期化などを行いたい場合にはここに処理を入れるようにします。また、ディレクトリ名がパッケージ名になります。
- etcli/utils.py:普通のユーティリティモジュールですが、パッケージのディレクトリに入れておくとimport etcli.utilsという感じでimportすることが出来ます。
setup.pyの作成
setup.pyはこんな感じですfrom setuptools import setup
with open('README.rst') as f:
readme = f.read()
setup(
name="et-cli",
version="0.0.4",
packages=['etcli'],
description='ExactTarget CLI Tool',
long_description=readme,
url='https://github.com/****',
author='****',
author_email='****',
license='MIT',
scripts=['bin/et', 'bin/et.cmd'],
install_requires=[
'FuelSDK',
],
)
packagesはパッケージとして設定するディレクトリを設定します。これによってpip installでパッケージがローカルにインストールされてimportできるようになります。
long_descriptionはPyPIに表示される説明文です。
コマンドラインツールを登録する場合に必要なのがscriptsの設定になります。ここで指定したスクリプトファイルがpip installでbinディレクトリに格納されることになります。
console_scriptsを使う方法に関してはこちらを参照→Command Line Scripts — Python Packaging Tutorial
ローカルで開発、インストール
pipコマンドはローカルのプロジェクトやgithubに上がっているプロジェクトをインストールすることができます。ローカルのプロジェクトをインストールする場合↓
$ pip install -e {local project path}
githubに上がっているプロジェクトをインストールする場合↓
$ pip install git+https://github.com/tzmfreedom/hoge.git
これらのコマンドとvirutualenv等の仮想環境を使って、依存関係が通ってちゃんとインストール出来るかどうかの検証、テストが出来ます。
testpypiでPyPIへの登録テスト
本番のPyPIに登録する前に、登録に必要なファイル、記載が不足していないかどうか、ちゃんとPyPIに上げれるようになっているかどうかを確認するためのtest用のPyPIリポジトリがあります。まず、testpypiにアクセスしてユーザ登録を行います。
次にホームディレクトリに.pypircファイルを以下の内容で作成します。
[distutils]
index-servers =
pypi
pypitest
[pypi]
username:{username}
password:{password}
[pypitest]
repository: https://testpypi.python.org/pypi
username:{username}
password:{password}
[pypi]の方は本番用のPyPIアカウント、pypitestの方はtestpypiで作成したアカウントの情報を入力します。
メタデータの登録及びパッケージの中身のアップロードは以下のコマンドで実施します。
$ python setup.py register -r https://testpypi.python.org/pypi
$ python setup.py sdist upload -r https://testpypi.python.org/pypi
これでtestpypiにパッケージが登録され、以下のコマンドでインストールができます。
$ pip install --index https://testpypi.python.org/pypi {package-name}
が、上記コマンドの場合は依存関係にあるパッケージもtestpypiにある必要があるのでインストールに失敗する場合があります。なのでメタデータがちゃんと登録できているか、ソース配布物がちゃんとアップロードされているかの確認がtestpypiの主な目的になります。
本番PyPIへの登録
-rオプションをつけなければ本番PyPIに登録しにいきます。本番PyPIのアカウント登録も忘れずに。$ python setup.py register
$ python setup.py sdist upload
その他
ちなみに、一度パッケージ名を登録したら、そのパッケージ名を削除することは出来ないようです。厳密にはパッケージを削除すると外部から見れなくなりますが、再度同一パッケージ名でアップロードすると以前の履歴が残った状態で復活します。こんな感じでremoveも履歴として残っちゃいます↓また、ファイルも履歴として残されるので、「バージョン0.0.1で間違ってファイルあげちゃったのでパッケージ削除して修正したファイルをバージョン0.0.1で再度アップロードしたい」とか思っても、0.0.1のファイルアップロード履歴が残り、ファイル名重複が起こるので、バージョンを上げないとアップロードできなくなります。まぁ本番PyPIに上げる前にテストしていれば基本的には問題ないんですが…。
また、PyPIに登録するコマンドラインツールを書くときはAWS CLIが非常に参考になるので、ざっと設定周りのコードを読むことをオススメします。