Pythonパッケージに非Pyファイルを含める方法

setuptoolsとMANIFEST.inを使用して構成ファイルを配布パッケージに含める

プロジェクトディレクトリが以下のような構成になっている場合を考えます。
myapp/
├── myapp
│   ├── configs
│   │   ├── data
│   │   │   └── data.yaml
│   │   └── trainer
│   │       └── trainer.yaml
│   ├── __init__.py
│   ├── run.py
│   └── trainer
│       ├── __init__.py
│       └── train.py
└── setup.py
この構造において、configs ディレクトリ内のYAMLファイルはPythonスクリプトではありませんが、アプリケーション実行時に必要となる設定データです。標準の setup.py では、こうした非.pyファイルはデフォルトでパッケージに含まれません。 以下の setup.py を使用しても、
from setuptools import setup, find_packages

setup(
    name="myapp",
    version="1.0",
    description="This is my app.",
    author="marsggbo",
    packages=find_packages(),
    include_package_data=True,
)
コマンドを実行:
python setup.py sdist bdist_wheel
生成された配布物(.tar.gz や .whl)の中身を確認すると、.yaml ファイルが含まれていないことがわかります。これは、setuptoolsが自動的に検出できるのはPythonモジュール(.pyファイル)のみだからです。 これを解決するには、MANIFEST.in というテキストファイルを作成し、パッケージに明示的に含めたい追加ファイルを指定する必要があります。 プロジェクトルートに MANIFEST.in を作成し、以下のように記述します:
recursive-include myapp/configs *.yaml
この指令は、「myapp/configs」ディレクトリ以下にあるすべての.yaml拡張子ファイルを再帰的にパッケージに含める」という意味です。サブディレクトリも対象とするため、data/data.yaml や trainer/trainer.yaml の両方が正しく取り込まれます。 もし特定の階層だけを対象にする場合は、代わりに次のように記述できます:
include myapp/configs/trainer/*.yaml
ただし、複数のディレクトリにまたがる場合は recursive-include の方が簡潔です。 再度ビルドコマンドを実行:
python setup.py sdist bdist_wheel
今度は出力されたパッケージ内に、期待通りYAMLファイルが含まれていることを確認できます。実際に生成されるSOURCES.txtや展開後のbuild/libの内容を見れば、構成ファイルも正しくコピーされているのが分かります。 重要なポイントとして、setup.py での include_package_data=True 設定も必須です。これにより、MANIFEST.in で指定されたファイルが実際にwheelやsdistに組み込まれます。 この手法は、JSON、YAML、テンプレート、モデルファイルなど、Pythonコード以外のアセットを含めたいすべてのケースに応用可能です。

タグ: Python setuptools MANIFEST.in package-distribution wheel

9月30日 22:42 投稿