自分のライブラリをPyPIに登録したい
...が、PythonにはRubyのbundlerのようなものが
なく、(合ったとしても統一されてないと思う)
プロダクト別に自由なディレクトリ構成になっている状態...
せめて自分のプロダクトについては統一したいなあと思ったので
Pythonのライブラリを作る場合のディレクトリ構成や
環境構築などについてメモを書く。忘れちゃうので...
利用するPythonのバージョンは3.3以降を意識してる。
それより前(3.2, 3.1...2.x)は考慮しない。問題無いと思うけど...
テスト目的で作成したライブラリ
**fizzbuzz**というアレなライブラリを作った。
ライブラリというかコマンドラインツールだけれど。
このライブラリの構成を元に、メモを書いていく。
ライブラリのディレクトリ・ファイル構成
以下のディレクトリ・ファイル構成とする。
fizzbuzz
└lib # ライブラリ本体
└bin # 実行スクリプト本体
└fizzbuzz # ライブラリ名のディレクトリ
└ __init__.py # ライブラリimport時の初期化設定はここで
└test # テストファイル
requirements.txt # travis-ci及びsetup.pyで利用する。pip --freezeで作れる。
info.py # パッケージの作者情報などを収めるファイル
version.py # バージョン情報を収めるファイル
setup.py #キモとなるファイル
こういうのでいいんじゃないかな。
pyvenvの環境をライブラリディレクトリ以下に構築する
Python 3.3より、virtualenv
が包含された。
ライブラリの動作テストを行うために、以下のコマンドで
ローカルなPython実行環境を作成する。
> pyvenv .venv
virtualenvの頃から使っているため、.venv以下に
pyvenvの環境を作るようにしているが、任意で良いと思う(.pvenvとか)。
ローカルなPython実行環境を構築したので、
activate
を shellのsource
コマンドにて取り込む。
こうすることで、.venv
以下のPython環境を使う形になる。(pythonコマンドとか)
> source .venv/bin/activate
setuptoolsのインストール
virtualenvのとあるバージョンまでは
システムのライブラリをvirtualenvで取り込んでくれたりしたけど、
virtualenvの新しいバージョン及びpyvenvだと取り込んでもらえない。
pyvenvを実行するとピュアな環境が構築される。
そのため、easy_install
が無い状態で環境が作られる。
以下のコマンドを実行してsetuptools
をセットアップしよう。
setuptoolsのPyPIページより引用。
> wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python
これでeasy_installコマンドを実行し、PyPIにある
パッケージをインストールできるようになる。
が、easy_installでPyPIのパッケージをインストールするより、
pip
を使うほうが使いやすい。pipを入れよう...
pip のインストール
easy_installを入れている状態であれば、pipは気軽にインストールすることができる。
> easy_install pip
以上で準備完了。
必要なライブラリのリストを作成する
自作ライブラリが他のライブラリを使っている場合、
setuptools.setup 関数に渡すhashに
install_requiresを指定しないといけない。
pipを利用すると気軽に必須ライブラリのリストを作ることができる。
> pip freeze > requirements.txt
TravisCIもrequirements.txtを利用するので
setup.pyにて、requirement.txt
を利用してinstall_requiresを指定するようにする。
setup({
install_requires: open('requirements.txt').read().splitlines(),
})
これでライブラリが必要としている外部ライブラリがインストールされる。
パッケージの情報をどこに持たせるか
パッケージ作成者の情報
PyPIで表示されるライブラリ作成者の情報について、どのファイルに持たせるか
なんか迷ったけど、package root直下にinfo.py
として置く形にした。
# package information.
INFO = dict(
name = "PyFizzBuzz",
description = "FizzBuzz cli tool",
author = "Keiji Matsuzaki",
author_email = "futoase@gmail.com",
license = "MIT License",
url = "https://github.com/futoase/fizzbuzz",
classifiers = [
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3",
"License :: OSI Approved :: MIT License"
]
)
classifiersは、ここのリストより自分のライブラリが
マッチしてそうなジャンルを選択し、設定する。
パッケージバージョン
version.py
の中にVERSIONを指定する。
VERSION = "0.0.3"
MANIFEST.in ファイルの作成
20131017追記
package_dir
ではinfo.py
, version.py
, requirements.txt
ファイルを指定していないため、
MANIFEST.inファイルを書かないといけない。
この記事を書いたときにチェックを怠って居たため、includeされていない問題を発見できませんでした。
ので追記。
include info.py
include version.py
include requirements.txt
パッケージのテスト
pipコマンドを利用し、パッケージのテストを行う
> pip install .
自分自身のディレクトリ内で自分自身を指定してpip installを行うことで、
pyvenv
の環境内で自己のライブラリを利用することができる。
> pip list
konira (0.3.2)
pip (1.4.1)
PyFizzBuzz (0.0.3)
setuptools (1.1.5)
もし、pip install後、自分のライブラリにバグが合った場合は
pyvenvの環境以下で以下のコマンドを実行すれば良い。
> pip uninstall PyFizzBuzz
Gemfileにgemspec
を指定するような...気持ちでコマンドを実行すればいいと思う...
動作チェック
今回、fizzbuzzはコマンドとして実行されるようにしたので、
.venv/bin/fizzbuzz
にコマンドが置かれている。
(.venv) > fizzbuzz 10 | head -3
1
2
Fizz
動作チェックは行えた。
PyPIへの登録
PyPIへの登録を行っていない場合は、以下のコマンドを実行し、登録する。
~/.piprc
ファイルを生成していない場合はユーザー名、パスワードの登録を促される(はず)...
> python setup.py register
PyPIへパッケージのアップロードを行う。
> python setup.py sdist upload
C拡張のライブラリの場合は異なるかもしれない。
(eggファイルのアップロードについては考慮していない...)
PyPIへのアップロード後
一日のダウンロード数や、過去にアップロードしたバージョンのファイルの一覧などを
PyPIページから見ることができる。(要ログイン済)
結構楽しい。
余談
setuptoolsがdistributeと統合されたので、setuptoolsのみimportしている形になったけど、
統合される前は以下の形でsetup.pyにてimportするパッケージの切り分けをしていた。
try:
import setuptools
except ImportError:
from distribute_setup import use_setuptools
use_setuptools()
from setuptools import setup, find_packages
distribute_setup.pyをここから落として(なんか書いてる今アクセスできないや)、パッケージに含める形で対応していた。
setuptoolsに統一されてよかった。(この記事では下位互換性のことは考慮してないからこうできるのかもしれない...)