背景
- 複数のアプリで利用される共通処理を自作Packageで切り出して利用したい
- 以下のようにリポジトリ内に複数アプリから共通して使われるパッケージを用意します
- common_slackという自作パッケージを用意します
.
├── README.md
├── common
│ ├── common_slack
│ │ ├── __init__.py
│ │ └── slack.py
├── app_A
│ ├── Dockerfile
│ ├── main.py
└── app_B
├── Dockerfile
├── main.py
- Python, Pipenv, Hatchlingを使った環境で進めていきます
なんでわざわざパッケージ化するの? 普通にimportじゃダメなの?
- Dockerコンテナ化するときに、app_A, app_Bの外側のディレクトリを考慮するのが面倒なので、build済みwheelを対象プロジェクトに配置して、pip installで管理できるようにしていきます
Hatchling? SetupTools?
BuildのBackendシステムとしてはHatchlingを使います. SetupToolsも有名ですが、よりモダンなBuildのBackendシステムということでhatchlingを採用しました.
用語を整理していきます.
Build Backend
source tree や source destricutionを受け取り、wheelやsource districutionをビルドするライブラリ. 例: Hatchling, Setuptools
Build Frontend
ユーザーがwheelやsource distributionをビルドするために使うツール. 実際のビルドはBuild Backendに委譲する. 例: pip, build
手順
- 1 . packageの実装
- 2 . packageのビルド
- pyproject.tomlの用意
- build
- 3 . projectAからの呼び出し
最終的に以下のようなディレクトリ構成になります.
.
├── common
│ ├── common_slack
│ │ ├── __init__.py
│ │ └── slack.py
│ ├── dist
│ │ ├── common_slack-0.0.1-py3-none-any.whl
│ │ └── common_slack-0.0.1.tar.gz
│ ├── pyproject.toml
│ ├── requirements.txt
├── projectA
│ ├── Dockerfile
│ ├── main.py
│ ├── requirements.txt
└── projectB
├── Dockerfile
├── main.py
├── requirements.txt
1. packageの実装
まずは common/common_slack/slack.py
の実装
import requests
import json
class Slack:
def post_message(self, title: str, message: str, channel_id: str) -> None:
requests.post(
url='https://slack.com/api/chat.postMessage',
headers={
'Authorization': f'Bearer xxx',
"Content-Type": "application/json"
},
data=json.dumps({
'channel': channel_id,
"attachments": [
{
"color": color,
"title": title,
"text": message,
}
]})
)
return
common/common_slack/__init__.py
の実装
from ai_sier_core.slack import Slack
__all__ = ('Slack')
2. packageのビルド
pyproject.tomlの用意
common/pyproject.toml
でpackageの設定をしていきます.
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "common_slack"
version = "0.0.1"
authors = [
{ name="Suzuki Shogo", email="xxx@jp" },
]
description = "common slack library"
readme = "README.md"
requires-python = ">=3.8"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
dependencies = ['requests']
- [project].nameはpackageの名前です. この名前と
-
packageの親ディレクトリのpathが一致している必要があります. また、nameがcommon-slack
の場合は pathはcommon_slack
で探索されるので注意してください. - packageの依存関係を作りたい場合は、dependenciesに書いてください.
build
cd common/common_slack
python3 -m pip install --upgrade build
python3 -m build
すると、common/dist
以下に wheelの生成物であるcommon_slack-0.0.1-py3-none-any.whl
と source distributionの生成物である common_slack-0.0.1.tar.gz
が出力されます.
3. projectAからの呼び出し
pip installする
以下のコマンドで生成したwheelをinstallします
cd project_A
pip install ../common/dist/common_slack-0.0.1-py3-none-any.whl
# pipenvの場合
# pipenv run pip install ../common/dist/common_slack-0.0.1-py3-none-any.whl
from common_slack import Slack
Slack().post_message('title', 'description')
これで共通処理を複数PJから呼び出せます.
Packageを更新した場合は、buildしなおして、呼び出し側がpip installしなおせば反映されます.
参考