A Practical Guide to Using Setup.py

Data & AI Training Guide 2021

GoDataDriven brochureをダウンロードして、利用できるトレーニング セッションやデータ エンジニア、データ科学、データ アナリスト、分析トランスレータ学習ジャーニーの全概略を確認することができます。

Python を専門的に使用している場合、一貫した方法でプロジェクト
をセットアップすることが重要です。 これは、共同作業者がプロジェクトの
構造を素早く理解するのに役立ち、また、彼らのマシン上でプロジェクト
をセットアップするのをより簡単にします。 このブログでは、このファイルの詳細について説明します。

Where we start

ここでは、セットアップしたいパッケージがすでにあるものと仮定します。 空のパッケージでも構いません。
ただ、package フォルダが存在し、init.py という名前のファイル (空でもかまいません) が含まれていることを確認してください。

私の同僚である Henk のプロジェクトの構造
に従うと、開始時の状況は次のようになります:

example_project/├── exampleproject/ Python package with source code.│ ├── __init__.py Make the folder a package.│ └── example.py Example module.└── README.md README with info of the project.

構造内に他のファイルやフォルダ、たとえば notebooks/tests/data/ というフォルダがあるかもしれませんが、これらは必要ではありません。

setup.py

このようなパッケージを作成したら、
他の場所でコードの一部を使用する可能性があります。 例えば、
これをノートブックで行いたいとします:

from exampleproject.example import example_function

これは現在の作業ディレクトリが example_project/ であれば動作しますが、
他のすべてのケースでは python は次のような出力をします。

ModuleNotFoundError: No module named 'exampleproject'

環境変数 PYTHONPATH
を設定したり、sys.path にパスを追加することで Python にパッケージを探す場所を教えることもできますが、これは理想からは程遠いです: 異なる
プラットフォームで異なるアクションが必要になり、設定すべきパスはコードの場所に依存します。
より良い方法は、setup.pypip を使ってパッケージをインストールすることです。
なぜなら、pip は他のすべてのパッケージをインストールする標準の方法であり、
すべてのプラットフォームで同じように動作することが保証されているからです。 以下は最小限の例です0:

from setuptools import setup, find_packagessetup( name='example', version='0.1.0', packages=find_packages(include=))

ここで、次の 3 つを指定します。

  • The name of the package, which is the pip will use for your package.
    This does not have the same as the folder name the package lives
    in, but if it is confused if it are not the different to. パッケージ名とディレクトリが一致しない例として、Scikit-Learn があります:
    pip install scikit-learn を使ってインストールし、sklearn からインポートして使用します。 これは pip が報告するバージョンで、例えば PyPI でパッケージを公開する際に
    使用されます1.
  • どのパッケージを含めるか; この例では exampleproject/ だけです2. 原理的には引数なしで find_packages()
    を使用することもできますが、これは潜在的に不要なパッケージが
    含まれる可能性があります。 例えば、tests/
    ディレクトリに __init__.py を含めた場合、
    が発生する可能性があります。 また、exclude 引数を使用して明示的に
    パッケージへのテストの組み込みを禁止することもできますが、これは若干
    ロバストではありません。

さて、パッケージをインストールするために必要なことは、example_project/ ディレクトリ 3:

pip install -e .

ここで . は現在の作業ディレクトリを指し、これは setup.py が見つかるディレクトリ
であると仮定しています。 -e フラグは、
を編集可能モードでインストールすることを指定します。これは、
パッケージ内のファイルを編集しても、変更が有効になる前に
パッケージを再インストールする必要がない、という意味です。 しかし、
python を再起動するか、パッケージを再読み込みする必要があります!

setup.py 自体の情報を編集する場合、ほとんどの場合
パッケージを再インストールする必要があり、さらに新しい (サブ) パッケージを追加した場合にも再インストールが必要です。 pip install -e .をもう一度実行してください。

Requirements

ほとんどのプロジェクトには依存関係があります。 ほとんどの場合、以前に
requirements.txt
ファイル、または conda を使用している場合は environment.yml
を使用したことがあるはずです。 setup.py を作成したので、install_requires 引数に
依存関係を指定できます。
たとえば、典型的なデータ サイエンス プロジェクトでは、次のようなものがあります:

setup( name='example', version='0.1.0', packages=find_packages(include=), install_requires=)

バージョンなしで要件を指定したり (PyYAML)、バージョンを指定したり (pandas==0.23.3)、最低
バージョンを指定したり ('numpy>=1.14.5)、バージョン範囲を設定したり (matplotlib>=2.2.0,<3.0.0)、することが可能です。 これらの
要件は、パッケージをインストールする際に pip によって自動的にインストールされます。

Extras-require

時には、特定の状況でのみ必要とされる依存関係がある場合があります。 データ サイエンティストとして
私はしばしば、モデルを訓練するために使用するパッケージを作成します。 このようなモデルで対話的に作業する場合、
データを対話的に操作し、モデルのパフォーマンスの視覚化
を作成するために、matplotlibjupyterをインストールする必要があるかもしれません。 一方、モデルが実稼働環境で動作している場合、
学習や推論を行うマシン(またはコンテナ)にはmatplotlibjupyterをインストールしたくありません。 幸いにも setuptools では extras_require:

setup( name='example', version='0.1.0', packages=find_packages(include=), install_requires=, extras_require={ 'interactive': , })

でオプションの依存関係を指定できます。

さて、普通に (pip install example from PyPI or pip install -e . locally)
パッケージをインストールすると、PyYAML, pandas, numpy の依存関係だけがインストールされるでしょう。 しかし、オプションの依存関係 (pip install example
または pip install -e .) を
指定すると、matplotlibjupyter もインストールされます。

Scripts and entry points

PYPI からインストールするほとんどの Python パッケージの主要用途は他の python コードで使用する機能
を提供することです。 言い換えれば、それらのパッケージから import 利用することができます。
データ サイエンティストとして、私はしばしば、他の python コードで使用することを意図しないが、
例えばモデルを訓練するために何かを行うことを意図するパッケージを作成します。

パッケージの機能をコマンド ラインに公開する最良の方法4 は、次のように entry_point を定義することです:

setup( # ..., entry_points={ 'console_scripts': })

これで、コマンド ラインから my-command コマンドを使用でき、それによって main
Function within exampleproject/example.py が実行されます。

テスト

何かコードを書いたら、そのコードのテストも書くことを強くお勧めします。 python で
テストを行う場合、pytest を使用することをお勧めします。 もちろん、pytestinstall_requires の依存関係
に追加したくはないでしょう: あなたのパッケージのユーザには必要ありません。 テストを実行するときに自動的に
をインストールするには、以下を setup.py に追加します:

setup( # ..., setup_requires=, tests_require=,)

さらに、次の内容で setup.cfg というファイルを作成する必要があります:

test=pytest

ここで python setup.py test を実行すれば、 setuptools はあなたに代わって必要な依存関係
をインストールおよび pytest 実行します (ただし、pytest がインストールされていることは確認します)。 もし、
引数を与えたり、pytest の設定オプションを設定したい場合は、ここを見てください。tests_require.

もし、テストのための追加要件 (例: pytest-flask) があれば、それを追加することができます。

Flake8

個人的には、
あなたのコードのフォーマットをチェックするために Flake8 を実行するとよいと考えています。 pytest と同様に、flake8
install_requires の依存関係に追加することはお勧めしません。 その代わりに、setup_requires:

setup( # ..., setup_requires=)

これで python setup.py flake8 を実行するだけでよいのです。 もちろん、setup_requires.

にある flake8 (または他のパッケージ) のバージョン
を固定することもできます。

もし Flake8 の設定パラメータのいくつかを変更したい場合は、
あなたの setup.cfgセクションを追加することができます。 例えば:

max-line-length=120

Package data

時には、パッケージに Python 以外のファイルを含めたいことがあるかもしれません。 たとえば、スキーマ ファイルや小さなルックアップ テーブルなどです。 そのようなファイル
はあなたのコードと一緒にパッケージ化されるので、一般的に
大きなファイルを含めるのは良くないということに注意してください。
これをパッケージに含めたい場合、setup:

setup( # ..., package_data={'exampleproject': })

これでファイルがパッケージに含まれることが確認されます。 例えば、

setup( # ..., package_data={'': })

これは遭遇したパッケージのすべての *.json ファイルを追加します。
pkg_resources には非常に便利な機能があるので、インストールされたファイルの場所を自分で見つけ出そうとしないでください。

  • pkg_resources.resource_stream は、open() を呼び出したときに得られる
    オブジェクトのように、ファイルのストリームを与えてくれます。
  • pkg_resources.resource_filename は、上記の2つのオプション
    が必要性に合わない場合、ファイルのファイル名を与える(zipパッケージに含まれている場合は
    それをテンポラリに展開する)。

たとえば、次のようにスキーマを読み込むことができます:

from json import loadfrom pkg_resources import resource_streamschema = load(resource_stream('exampleproject', 'data/schema.json'))

Metadata

パッケージを公開する場合、おそらく潜在ユーザーに対して、説明、
著者またはメンテナの名前、パッケージのホームページへの url などパッケージに関する詳細情報を提供したいことでしょう。
許容されるメタデータの完全なリストは setuptools
docs で見ることができます。

さらに、もしあなたが PyPI に公開しようとしているなら、README.md
の内容を long_description に自動的にロードし、pipあなたのパッケージについてさらに
伝えるために分類子を提供したいと思うかもしれません。

まとめ

このブログは Python プロジェクトのほとんどをセットアップするための良い出発点になるでしょう。
もし Python パッケージングについてもっと読みたいなら、ドキュメントを
見てください。 このブログで紹介したすべてのパーツを組み合わせたsetup.py
例:

from setuptools import setup, find_packagessetup( name='example', version='0.1.0', description='Setting up a python package', author='Rogier van der Geer', author_email='[email protected]', url='https://blog.godatadriven.com/setup-py', packages=find_packages(include=), install_requires=, extras_require={'plotting': }, setup_requires=, tests_require=, entry_points={ 'console_scripts': }, package_data={'exampleproject': })

および付随するsetup.cfg:

test=pytestmax-line-length=120

Improve your Python skills, learn from the experts!

GoDataDrivenでは初心者からエキスパートまでの多くのPythonコースがあり、業界の最高の専門家が指導を行っています。

  • Python Essentials – Pythonを始めたばかりの方に最適です。
  • Certified Data Science with Python Foundation – データ分析や可視化から、真のデータサイエンスへとステップアップしませんか?
  • Advanced Data Science with Python – プロ並みにモデルをプロダクション化し、機械学習のためにPythonを使用することを学ぶ。 あるいは、
    python のパッケージングの標準ツールである distutils
    を使うこともできますが、find_packages()関数や entry_points などの機能
    が欠けています。
    Setuptools の使用は今日では非常に一般的で、その多くの機能
    は特に便利なので、setuptools を使うことをお勧めします。

    1: もしあなたのパッケージのバージョンを python 内部でも利用可能にしたい場合は、
    こちらを参照してください。

    2: 手動でパッケージをリストアップすることもできますが、これは特にエラーが起こりがちです。

    3: 代わりに python setup.py install を実行することもできますが、pip を使用すると
    多くの利点があり、中でも依存関係の自動インストールと
    パッケージをアンインストールまたはアップデートできるようになります。

    4: scripts 引数を使用することもできます (ここに
    例があります)
    が、これは python シェルスクリプトを作成する必要があるので、Windows ではうまく
    動かないかもしれません (あるいは全く動かないかもしれません)

コメントを残す

メールアドレスが公開されることはありません。