【Django】自作アプリを配布用にパッケージングしてpipでインストールする


投稿日 2023年2月21日 >> 更新日 2023年2月27日

概要

Djangoプロジェクトで作成したアプリ(モジュール)をパッケージングして再利用、もしくは配布用にビルドしていきます。

ビルドバックエンドツールには「Hatch」を使用し、設定ファイルである「pyproject.toml」のみでビルドを実行していきます。

開発環境&使用ライブラリ

開発環境
Windows Subsystem for Linux
Python 3.6.9
使用ライブラリ ライセンス
Django==3.2.15 BSD-3-Clause
build==0.9.0 MIT

パッケージングするサンプルアプリ

今回パッケージングするサンプルアプリは、Djangoチュートリアルで開発できる「polls」アプリケーションです。

Djangoチュートリアルの1~7を行うと以下のようなプロジェクトのディレクトリ構造になります。

mysite
├── db.sqlite3
├── manage.py
├── mysite
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── polls
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   ├── models.py
│   ├── static
│   │   └── polls
│   │       ├── images
│   │       │   └── background.jpg
│   │       └── style.css
│   ├── templates
│   │   └── polls
│   │       ├── detail.html
│   │       ├── index.html
│   │       └── results.html
│   ├── test_models.py
│   ├── test_views.py
│   ├── urls.py
│   └── views.py
└── templates
    └── admin
        └── base_site.html

Djangoプロジェクトは複数のアプリケーションをプロジェクト内に作成することができ、上記の場合だと「mysite」プロジェクト内には「polls」と言うアプリケーションが1つ作成されています。

polls
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│   ├── 0001_initial.py
│   ├── __init__.py
├── models.py
├── static
│   └── polls
│       ├── images
│       │   └── background.jpg
│       └── style.css
├── templates
│   └── polls
│       ├── detail.html
│       ├── index.html
│       └── results.html
├── test_models.py
├── test_views.py
├── urls.py
└── views.py

上記アプリケーション(モジュール)をパッケージング化して、別のDjangoプロジェクトにも再利用できるようにしていきます。

アプリをパッケージングする

Djangoアプリをパッケージングする流れとしては、Django公式チュートリアルの最後の章「高度なチュートリアル: 再利用可能アプリの書き方」を参考にして実装します。

Djangoチュートリアルと違う事と言えば、アプリをビルドしてパッケージングする際に必要な「ビルドバックエンドツール」です。

チュートリアルでは「setuptools」を使い「setup.py」等に設定内容を記述していますが、この記事では「Hatch」というビルドバックエンドツールを使い「pyproject.toml」ファイルのみでビルドの設定を記述していきます。

プロジェクトの作成

Djangoチュートリアルで開発した「polls」アプリを移動して、パッケージング用のプロジェクトに配置します。

プロジェクト名は後にパッケージ名となりますが「zfl-polls」とします。

$ ls
mysite

$ mkdir zfl-polls

$ mv mysite/polls zfl-polls/.

以下のようなディレクトリ構造となります。

zfl-polls
└── polls
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    ├── models.py
    ├── static
    ├── templates
    ├── test_models.py
    ├── test_views.py
    ├── urls.py
    └── views.py

「zfl-polls」ディレクトリには「polls」アプリというソースコードしか存在していませんが、再利用・配布物としてパッケージングしていくので使用書として「README.md」ファイルと規約事項を記した「LICENSE」ファイルを作成し、最後にパッケージングに関しての設定ファイル「pyproject.toml」を作成します。

README.mdファイルの作成

README(リードミー)ファイルは一般的にソフトウェアの説明書のことで、ソースコードと一緒に配布物として用意します。

以下はDjango公式チュートリアルの「高度なチュートリアル: 再利用可能アプリの書き方 -- アプリケーションをパッケージングする」で記載されているREADME.mdの内容の説明書きと同じ内容のものです。

=====
Polls
=====

Polls is a Django app to conduct web-based polls. For each question,
visitors can choose between a fixed number of answers.

Detailed documentation is in the "docs" directory.

Quick start
-----------

1. Add "polls" to your INSTALLED_APPS setting like this::

    INSTALLED_APPS = [
        ...
        'polls',
    ]

2. Include the polls URLconf in your project urls.py like this::

    path('polls/', include('polls.urls')),

3. Run ``python manage.py migrate`` to create the polls models.

4. Start the development server and visit http://127.0.0.1:8000/admin/
   to create a poll (you'll need the Admin app enabled).

5. Visit http://127.0.0.1:8000/polls/ to participate in the poll.

README.mdファイルを作成すると以下のようなディレクトリ構造となります。

zfl-polls
├── README.md
└── polls

LICENSEファイルの作成

LICENSEファイルは自分以外の人がモジュールを使用するに当たっての資格情報として用意します。

アプリを開発した人、使用する人の双方が安心して実装するためにも必要なファイルとなります。

私自身、自作のアプリやモジュールを配布物としてパッケージングするまではライセンスについて気にも止めていませんでしたが、これをきっかけにサードパーティを使用する際はライセンス情報を必ず確認するようにしています。

思わぬトラブルに遭わないように注意をしていきましょう。

Django公式チュートリアルの「高度なチュートリアル: 再利用可能アプリの書き方 -- アプリケーションをパッケージングする」でも「ライセンス」の重要性に少し触れています。

Django自体は「BSD」ライセンスに定めていますが、そこから派生されたアプリのライセンスは自由とのことなので、「MIT(Massachusetts Institute of Technology)」ライセンスを定めることにします。

LICENSEファイルを作成すると以下のようなディレクトリ構造となります。

zfl-polls
├── LICENSE
├── README.md
└── polls

pyproject.tomlファイルの作成

「pyproject.toml」ファイルは、ビルドを実行するための設定内容を記します。

Django公式チュートリアルの「高度なチュートリアル: 再利用可能アプリの書き方 -- アプリケーションをパッケージングする」で説明されている設定ファイルとは少し違って、この記事ではビルドを行う上での設定を全て「pyproject.toml」ファイルに書きます。

記載内容は以下の通りです。

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build]
include = [
    "polls/*",
    "polls/static",
    "polls/templates",
    "docs",
]

[project]
name = "zfl_polls"
version = "0.1"
authors = [
    { name="your name", email="mail@example.com" },
]
description = "A Django app to conduct web-based polls."
readme = "README.md"
license = {file = "LICENSE"}
requires-python = ">=3.6.9"
dependencies =  [
    "django >= X.Y",
]
classifiers =  [
    "Environment :: Web Environment",
    "Framework :: Django",
    "Framework :: Django :: X.Y",  # Replace "X.Y" as appropriate
    "Intended Audience :: Developers",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3 :: Only",
    "Programming Language :: Python :: 3.6.9",
]
  • [build-system]デーブルではビルドバックエンドツールを指定しています。「hatchling」というビルドバックエンドを指定していますが、ビルド作業中に仮想環境で自動的にインストールされるので設定するだけで大丈夫です。

  • [tool.hatch.build]テーブルは「Hatch」と言うビルドバックエンドツールの拡張機能で、ビルドに含めたいファイルがある場合に設定します。デフォルトではPythonファイルだけしか含まれないので、Pythonファイル以外のファイルをパッケージに含めたい場合はPythonファイルと共に設定します。Django公式チュートリアルの方では、「MANIFEST.in 」と言うファイルを使ってPythonファイル以外の追加ファイルを設定しています。

  • [project]テーブルではパッケージ名やバージョン番号、著者等の情報を設定します。Python公式のチュートリアルを参考にするとより理解が深まるかと思います。

除外したいファイルがある場合は「.gitignore」に設定するか、「Hatch」の拡張機能「[tool.hatch.build]」テーブルの「exclude」キーに設定するかです。例えば「venv」の仮想環境ディレクトリにはPythonファイルが含まれているので、設定を忘れると膨大なファイル群がパッケージの中に含んでしまいします。

  • 「.gitignore」を設定する場合、Hatchのデフォルトの動作ではルートディレクトリに配置された「.gitignore」を優先してファイルを選択してくれます。
$ echo 'venv' > .gitignore
zfl-polls
├── .gitignore
├── LICENSE
├── README.md
├── polls
└── pyproject.toml
  • [tool.hatch.build]テーブルで除外ファイルを指定する場合、「exclude」キーに除外されたいファイルを指定します。
[tool.hatch.build]
...
exclude = [
  "venv",
]

pyproject.tomlファイルを作成すると以下のようなディレクトリ構造となります。

zfl-polls
├── .gitignore
├── LICENSE
├── README.md
├── polls
├── pyproject.toml
└── venv

ビルドツールをインストールしてビルドを実行する

Pythonのビルドツール「build」をpipでインストールします。

$ pip install --upgrade pip

$ pip install build

インストールが完了したら、Pythonの「-m」オプションで「build」を実行します。

$ python3 -m build
* Creating venv isolated environment...
* Installing packages in isolated environment... (hatchling)
* Getting build dependencies for sdist...
* Building sdist...
* Building wheel from sdist
* Creating venv isolated environment...
* Installing packages in isolated environment... (hatchling)
* Getting build dependencies for wheel...
* Building wheel...
Successfully built zfl_polls-0.1.tar.gz and zfl_polls-0.1-py3-none-any.whl

ビルドが完了すると、作業ディレクトリに「dist」というディレクトリが作成され、その中に配布用・再利用としてパッケージングされた自作アプリが配置されています。

zfl-polls
├── .gitignore
├── LICENSE
├── README.md
├── dist
│   ├── zfl_polls-0.1-py3-none-any.whl
│   └── zfl_polls-0.1.tar.gz
├── polls
├── pyproject.toml
├── venv

Djangoプロジェクトに自作アプリをインストールして起動確認

パッケージングされた自作アプリをpipでインストールする方法は色々ありますが、この記事ではパッケージを指定してインストールを行います。

グローバルで開発環境を実行している場合はそのままpipで「dist」ディレクトリ内のパッケージを指定して実行します。

$ pip install dist/zfl_polls-0.1.tar.gz

仮想環境を構築している場合は、特定のDjangoプロジェクトの仮想環境を有効にしてから「dist」ディレクトリ内のパッケージを指定してインストールします。

$ ls
django-project zfl-polls

$ source django-project/venv/bin/activate

(venv)$ pip install zfl-polls/dist/zfl_polls-0.1.tar.gz

その他のpipでのインストール方法に関しては、こちら「「pyproject.toml」を参照したインストール」をご参照ください。

自作アプリのインストールが完了したら、起動させたいDjangoプロジェクトに移動してセットアップを行います。

django-project
├── manage.py
├── mysite
├── templates
└── venv

まずは自作アプリがインストールされているか確認します。

$ pip freeze
...
Django==3.2.18
...
zfl-polls @ file:///mnt/c/Users/Documents/dist/zfl_polls-0.1.tar.gz

「README.md」の内容に沿ってDjangoプロジェクトに設定を加える。

=====
Polls
=====

Polls is a Django app to conduct web-based polls. For each question,
visitors can choose between a fixed number of answers.

Detailed documentation is in the "docs" directory.

Quick start
-----------

1. Add "polls" to your INSTALLED_APPS setting like this::

    INSTALLED_APPS = [
        ...
        'polls',
    ]

2. Include the polls URLconf in your project urls.py like this::

    path('', include('polls.urls')),

3. Run ``python manage.py migrate`` to create the polls models.

4. Start the development server and visit http://127.0.0.1:8000/admin/
   to create a poll (you'll need the Admin app enabled).

5. Visit http://127.0.0.1:8000/ to participate in the poll.

上記の設定が完了したら、データベースを作成して移行を行います。

$ python3 manage.py makemigrations polls
Migrations for 'polls':
  venv/lib/python3.6/site-packages/polls/migrations/0001_initial.py
    - Create model Question
    - Create model Choice
$ python3 manage.py migrate

サーバーを起動させます。

$ python3 manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
February 27, 2023 - 10:37:34
Django version 3.2.18, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

問題無く「polls」アプリが表示されデータベース等に保存することができれば成功です。

自作アプリをGitHubやPyPIにアップロードする

今回作成した自作アプリを「GitHub」もしくは「PyPI」にアップロードしたい場合は以下の記事をご参照ください。

以上となります。

最後までご覧いただきありがとうございました。