2017年11月14日火曜日

pythonのpipでインストールできるライブラリを公開する方法


背景

pipとはpythonのライブラリ管理プログラムです。
ライブラリとして公開できたら良いと思うプログラム(raspberry piでLCD(AQM1602)を使い、IPを表示する方法)があったので、公開してみました。

下記のサイトなどを参考にして公開できましたが、詰まる部分があったので、備忘録を兼ねて自分の言葉で手順を残します。

Pythonで作成したライブラリを、PyPIに公開/アップロードする
Packaging and Distributing Projects

環境

PC (Intel corei7)

ubuntu17.10
python 2.7.14
pip 9.0.1
twine 1.8.1

raspberry pi 3

raspbian jessie
python 2.7.9
pip 9.0.1
twine 1.9.1

それぞれ下記のコマンドで環境を構築しました。
sudo apt install python python-pip twine
sudo pip install twine

ubuntuではpipでインストールしたtwineを呼び出せませんでしたが、記事作成時点では最新版ではない1.8.1でもファイルをアップロードできました。

ライブラリのファイル構成

自分が作ったライブラリ asukiaaa_py_i2c_lcd(github, PyPI)を元に、各ファイルの役割を説明します。
ライブラリを作るときは「asukiaaa_py_i2c_lce」をライブラリ名に置き換えてください。
asukiaaa_py_i2c_lcd
  |- README.stl
  |- setup.py
  |- asukiaaa_py_i2c_lcd
  |   |- __init__.py
  |   |- core.py
  |- examples
      |- hello_world.py

README.stl

ライブラリの説明を記述するためのファイルです。
pythonのドキュメントとしても利用したいので、mdではなくstl形式で書いています。

setup.py

ライブラリの設定ファイルです。
pythonが提供してくれているサンプルライブラリや関連ドキュメントを参照しながら作成しました。
setup.py
from setuptools import setup
from codecs import open
from os import path

here = path.abspath(path.dirname(__file__))
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
    long_description = f.read()

setup(
    name='asukiaaa_py_i2c_lcd',
    version='0.1.3',
    description='An i2c library to control AQM1602',
    long_description=long_description,
    url='https://github.com/asukiaaa/asukiaaa_py_i2c_lcd',
    author='Asuki Kono',
    author_email='asukiaaa@gmail.com',
    license='MIT',
    keywords='i2c lcd aqm1602 raspberry',
    packages=[
        'asukiaaa_py_i2c_lcd',
    ],
    classifiers=[
        'Development Status :: 4 - Beta',
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.6',
        'Programming Language :: Python :: 2.7',
    ],
)

注意すべきなのは、「packages」にソースコードを置いているディレクトリを記述必要があるところです。
packagesに何も指定せずにライブラリを公開すると、本体の無いライブラリになってしまいます。
これで数時間悩みました。

asukiaaa_py_i2c_lcd

ソースコードを入れるディレクトリです。
ライブラリ名と同じ名前にするのが慣例のようなので、それに従いました。

asukiaaa_py_i2c_lcd/__init__.py

ライブラリ読み込み時に実行されるプログラムです。
今回のライブラリは読み込み時に実行したい処理が無いので、中身は空です。

asukiaaa_py_i2c_lcd/core.py

ライブラリの主となるプログラムです。
このファイルを読み込んで、ライブラリを利用します。

examples/hello_world.py

開発時動作確認用のサンプルプログラムです。

開発中のプログラムの動作確認

ライブラリとして公開するためにファイルを構成したら、下記のコマンドで自分の環境にインストールできます。
sudo pip install -e .

ライブラリがインストールされたことは、下記のコマンドで確認できます。
pip list

pipに認識されていれば、pipのライブラリとして機能を呼び出すプログラムを実行できます。
python examples/hello_world.py

注意: 「pip install -e .」で読み込めるようにしたプログラムは、「pip install ライブラリ名」で読み込んだプログラムと比較して、setup.pyの記述内容によってはファイル構成が違う場合があります。
そのため、「pip install -e .」で動くプログラムも「pip install ライブラリ名」で動作確認することを強くお勧めします。

下記のコマンドでアンインストールできます。
pip uninstall asukiaaa_py_i2c_lcd

raspberry piでは上記のコマンドだけでは削除できなかったので、コマンド実行後にライブラリのディレクトリを消すか、ライブラリのディレクトリのパスを変更して、pipで参照できなくする必要がありました。

参考: How to uninstall editable packages with pip (installed with -e)

PiPIに会員登録

アップロードするにはpython package indexのユーザー情報が必要なので、会員登録しておきます。

ビルドとアップロード

下記のコマンドでビルドできます。
python setup.py sdist bdist_wheel

ビルドできたら、下記のコマンドを実行し、PiPIのユーザーIDとパスワードを入ろy区すると、ライブラリをアップロードできます。
twine upload dist/*


ライブラリをインストールして動作確認

アップロードができたら、pipコマンドでインストールできます。
sudo pip install asukiaaa_py_i2c_lcd

期待通りに動くことを確認できれば、ライブラリの完成です。
python examples/hello_world.py

「setup.py」や「pip install -e .」の説明でも書きましたが、packagesなどの指定によって、期待しているファイルがビルドに含まれていない場合などがあり得ます。
そのため、「pip install -e .」で動いても、「pip install ライブラリ名」では動かない可能性があります。
自分の場合は「setup.py」の「packages」で、ソースコードが含まれるディレクトリを指定していなくて、上記の状況に陥りました。

まとめ

setup.pyのpackagesに悩まされながらも、期待通りにライブラリを作れました。

共有したい情報は以上です。

変更履歴

2018.05.18
管理者権限でも実行できるようにライブラリを配置する方が良いと思ったため、pip installコマンドにsudoを付けました。

0 件のコメント :

コメントを投稿