English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Pythonモジュールのパッケージ化と公開方法の詳細

前書き

昨日、自分のVASPファイル処理ライブラリをパッケージ化してPyPIにアップロードしました。今ではpipやeasy_installでVASPyをインストールできます(VASPで計算化学をしている方々、ぜひ星を付けたり参加したりしてください)。

VASPyのGitHubアドレス:https://github.com/PytLab/VASPy
VASPyのPyPIアドレス:https://pypi.python.org/pypi/vaspy/

自分の記憶力が悪いので、時間が経つと忘れてしまいます。そこでここで熱を盛って、自分のVASPyプログラムを例にしてPythonのパッケージ化とアップロードについてまとめました。

VASPyパッケージのファイル構造

まずVASPyパッケージの全体のファイル構造を書き込んで、後の内容はすべてこれを例として説明します:

VASPy/
├── LICENSE
├── MANIFEST
├── MANIFEST.in
├── README.rst
├── requirements.txt
├── scripts
│  ├── change_incar_parameters.py
│  ├── create_inputs.py
│  └── ...
├── setup.cfg
├── setup.py
├── tests
│  ├── incar_test.py
│  ├── __init__.py
│  ├── oszicar_test.py
│  ├── outcar_test.py
│  ├── testdata
│  │  ├── CONTCAR
│  │  ├── DOS_SUM
│  │  ├── ELFCAR
│  │  └── ...
│  └── ...
└── vaspy
  ├── __init__.py
  ├── iter.py
  ├── matstudio.py
  └── ...
4 directories, 54 files

パッケージのパッケージ化とインストールに使用するツール

ここでは、setuptoolsやpipなどのツールを使用して、自分のパッケージのパッケージ化、公開、インストールを行う必要があります。wheelに構築する場合は、wheelモジュールをインストールする必要があります。2.7.9または>=3.4、setuptoolsとpipは既にインストールされていますが、最新バージョンに更新する必要があるかもしれません。

pip install -U pip setuptools

パッケージ管理ツールを使用できます。例えば、

yum install pip
sudo apt-get install pip

getを通じて-pip.pyスクリプトのインストールでは、wheelとsetuptoolsがインストールされていない場合でも自動的にインストールされます。

python get-pip.py

具体的なツールのインストールと紹介は省略しますが、requirements for installing packagesを参照してください。

パッケージ内の異なるファイルの役割

setup.py

このファイルはプロジェクト全体をパッケージ化する最も重要なファイルであり、以下の2つの主要機能を提供しています:

setup()関数は、この関数の引数がプロジェクトの設定方法を指定します。
コマンドラインツールで、パッケージのパッケージ化、テスト、公開などが含まれています。以下のコマンドで確認できます;

python setup.py --help-commands

setup.cfg

このファイルには、ビルド時の一部のデフォルトパラメータが含まれています。例えば、bdist_wheelをビルドする際の--universalパラメータ

[bdist_wheel]
universal=1

このようにして、パッケージをパッケージ化するたびにデフォルトで使用されます--universalパラメータを設定すると、効果は以下のようになります:

python setup.py bdist_wheel --universal

README.rst

この最初は私はmarkdownで書いていました。PyPIにパッケージを公開した後、PyPIはmarkdownのレンダリングをサポートしていないことが判明し、ページはごちゃごちゃになりました。それで、reStructuredTextの構文で再書き直しました。なぜなら、マークアップ言語の構文は基本的に直感的で、本当に難しい場合はテンプレートをコピーして塗り絵でも大丈夫だからです。
reStructuredTextの文法規則は公式ドキュメントを参照してください:Quick reStructuredText

実際には別の方法もあります。それはpandocを使用してmarkdownをrst形式に変換することです。便利な方法の一つは、pyandocモジュールを使用してリリース時に自動的に変換することです。
具体的な方法は以下を参照してください:Use Markdown README's in Python modules

MANIFEST.in

このファイルはパッケージ化の際にsetuptoolsに追加でパッケージ化する必要があるファイルを教えます。例えば、私のVASPyのユニットテストのテストデータファイルは、このファイルを使用して含めます。もちろんREADME、LICENSEなどのファイルもこれで一緒にパッケージ化できます。
以下は私のMANIFEST.inの内容です:

include README.rst
include requirements.txt
include LICENSE
recursive-include scripts *
recursive-include tests *

具体的な文法規則は以下を参照してください:The MANIFEST.in template

vaspy/

このフォルダーはvaspyのソースコードが所在するパッケージです。

tests/

このフォルダーもまたサブパッケージであり、ユニットテストスクリプトが含まれています。python setup.py testを使用してユニットテストを実行できるように、特別に__init__.pyを追加してパッケージとして作成しました。

setup()のパラメータ

ここでは私が使用しているいくつかのパラメータについて説明します。他のパラメータの詳細な使用方法は以下を参照してください:https://docs.python.org/3/distutils/setupscript.html

name

versions = "vaspy"

これはプロジェクトの全体の名前であり、パッケージ化後にはこの名前とバージョン番号を使用します。

version

from vaspy import __version__
version = __version__

description

プロジェクトの短い説明であり、一般的には一つの文で十分です。これはpypi上の名前の下に表示されます。

long_description

これは長い説明であり、プロジェクトの簡潔な概要に相当します。この文字列がrst形式であれば、PyPIは自動的にHTMLとして表示します。ここではREADME.rstの内容を読み込むことができます。

url

パッケージのリンクです。通常、GitHubのリンクまたはreadthedocsのリンクです。

packages

含める必要のあるサブパッケージのリストです。setuptoolsはfind_packages()関数を提供し、ルートディレクトリ下でパッケージを検索します。この関数はdistutilにはありません。

setup_requires

このパラメータは、VASPyのインストールと正常な動作に必要な他の依存関係(最も基本的なもの)を定義し、pipでインストールする際にこれらの依存関係がインストールされます。
このパラメータとrequirements.txtの違いについては、以下を参照してください:install_requires vs Requirements files

classifier

このパラメータは、PyPI上で異なるディレクトリにプロジェクトを分類するためのカテゴリを提供します。
具体的なcategoriesの名称と規則については、以下を参照してください:https://pypi.python.org/pypi#63;%3Aaction=list_classifiers

test_suite

このパラメータは、以下のように使用を助けます:

python setup.py test

ユニットテストを実行するために、run_tests.pyのような別のスクリプトを書く必要がなくなります。
このパラメータの公式説明:

unittest.TestCaseサブクラス(またはそれを含むパッケージやモジュール、またはそのサブクラスのメソッド)を名前付ける、または無引数で呼び出せる関数を名前付ける。指定されたスイートがモジュールで、モジュールにadditional_tests()関数がある場合、それが呼び出され、実行するテストに結果が追加される。指定されたスイートがパッケージの場合、サブモジュールやサブパッケージが再帰的に全体のテストスイートに追加される。

つまり、この引数は複数のタイプの引数を受け入れることができます:

unittest.TestCaseのサブクラスを受け取ります。すべてのユニットテストを1つのテストケースに書き込み、それをimportしてtest_suiteに渡すことができます。
関数オブジェクトを受け取ります。この関数オブジェクトにはパラメータがなく、unittest.TestSuiteを返します。したがって、複数のテストケースを1つのスイートにまとめて返す関数を書き、それをimportしてtest_suiteに渡すことができます。

モジュールとパッケージの名前、私はこの方法を使用して、以前のテストは分離された複数のスクリプトで行われていました。__init__.pyを追加することで、これをパッケージに変換し、パッケージ名をtest_suiteに渡します。setuptoolsはそのパッケージの下にあるすべてのテストを実行するために魔法のように動作します。今後、テストスクリプトを追加する場合は、新しいスクリプトを直接追加するだけで、他のものは変更しない必要はありません。

运行效果:

zjshao@SHAO-PC:/mnt/d/Dropbox/Code/CentOS_code/VASPy$ python setup.py test
running test
running egg_info
creating vaspy.egg-info
writing vaspy.egg-info/PKG-INFO
writing top-level names to vaspy.egg-info/top_level.txt
writing dependency_links to vaspy.egg-info/dependency_links.txt
manifestファイル 'vaspy.egg' を書き込み中-info/SOURCES.txt'
reading manifest file 'vaspy.egg-info/SOURCES.txt'
manifestテンプレート 'MANIFEST.in' を読み込み中
manifestファイル 'vaspy.egg' を書き込み中-info/SOURCES.txt'
building build_ext
test_compare (tests.incar_test.InCarTest)
InCarオブジェクトを正しく比較できることを確認してください。 ... ok
test_eq (tests.incar_test.InCarTest)
Test __eq__() function. ... ok
...
ここではいくつかの出力を省略しています
----------------------------------------------------------------------
Ran 22 tests in 3.574s
OK

自分のpythonパッケージを公開

1. まずPyPIにアカウントを登録

2. 設定~/.pypircは以下の通りです:

[distutils]
index-servers =
  pypi
  pypitest
[pypi]
username:ShaoZhengjiang
password:mypassword
[pypitest]
username:ShaoZhengjiang
password:mypassword

3. 然后自分のパッケージをテストサーバーに登録しアップロード

pypiはテストサーバーを提供しており、そのテストサーバーでテストを行うことができます。

python setup.py register -r pypitest

それから

python setup.py sdist upload -r pypitest

問題がなければエラーは発生しないでしょう。

4. PyPIにアップロード

上記のテストが成功した場合、同じ手順でパッケージを登録しアップロードすることができます。

python setup.py register -r pypi
python setup.py sdist upload -r pypi

Ok,それからPyPIにhttps://pypi.python.org/pypi/vaspy/)上で自分のパッケージが見つかる。

基本教程
おすすめ