【pythonモジュールパッケージ化】poetryで自作してGithubのprivate repositoryから使用する方法

ここでは自作したモジュールをパッケージ化して、別レポジトリで使用するまでの道のりを書いております。簡単そうに見えて結構詰まったところだったので、共有をしていきたいと思いました。

タイトルの通り、pythonで使うモジュールを別プロジェクトのレポジトリで使用するときの方法を書いていきます。
パッケージ化を使用する利点としては、主に<b>同じ処理を使うときに開発・管理の工数が減る</b>、参照先のレポジトリで、同じ処理を使う場合、テストを無駄に書かなくて良くなるなどがあります。

使いこなせれば、開発をスムーズに進めることができるので、参考にしていただきたいと思います。

今回は以下の内容を説明していきたいと思います。

```
1.パッケージ化について
2.poetryでモジュールをパッケージ化する方法
3.private repositoryから参照先でパッケージを使用する方法
4.注意点
```

poetryのversionは1.5.2で投稿時最新のものです。

<h2>パッケージ化とは？</h2>
パッケージとは、簡単にいうと作成したモジュールをディレクトリにあつまたものです。

プロジェクトで下記のように作成したpythonファイルがあります。
```
process
├── aaa
│   └── process_1.py
└── bbb
    └── process_b.py
```

上の「process」がパッケージに当たります。
このようにしておくと、下記コードで中のディレクリで定義した関数等が呼び出せるようになります。

```Python
from process.aaa import process_1
from process.bbb import process_2
```

ここまでだと、「それ当たり前じゃない？」と思うかもしれません。
ただ、同じプロジェクト（レポジトリ）では普通にモジュールを作成して、呼び出すということはしていると思います。


ここで紹介するのは、<b>１つのレポジトリで作成したパッケージを別のレポジトリで呼び出す方法</b>です。
なので、同じモジュールを別レポジトリで簡単に呼び出せるので、同じpythonファイルなら次回以降は作成する必要はなくなります。


<h2>poetryでモジュールをパッケージ化する方法</h2>
poetryを使用してパッケージを作成していきます。
pythonのパッケージ化で調べると、「setup.py（パッケージの定義ファイル）が必要」という記事が出てきますが、7月28日現在では必要ありません。<br><br>
poetryのファイルを記述し、コマンドを使うだけでパッケージ化できます。

まずは、作成したいパッケージ名でpoetry newを打ち込みます。
```
$ poetry new <パッケージ名>
```
ここでは「demo-package」という名前でパッケージができます。

すると以下のディレクトリ構成になります。

```
$ tree
.
└── demo-package
    ├── README.md
    ├── demo_package # このディレクトリに追加
    │   └── __init__.py
    ├── pyproject.toml
    └── tests
        └── __init__.py
```

＊既存のディレクトリを作成したいときは、poetry initを入力してください。


作成されたpyproject.tomlを見るとこのようになっている。
```
[tool.poetry]
name = "demo-package"
version = "0.1.0"
description = ""
authors = ["<名前> <メールアドレス>"]
readme = "README.md"
packages = [{include = "demo_package"}]

[tool.poetry.dependencies]
python = "^3.10"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

```
name = "demo-package"でdemo-packageという名前のパッケージができていることがわかります。

poetry addなどで使うライブラリを追加してもらって、パッケージに入れるモジュールはdemo-package内に作成します。ここでいうaaa.pyとbbb.pyになります。

```
.
└── demo-package
    ├── README.md
    ├── demo_package
    │   ├── __init__.py
    │   ├── aaa.py
    │   └── bbb.py
    ├── pyproject.toml
    └── tests
        └── __init__.py
```

ここでaaa.pyで関数などを作成すれば、poetry installでモジュールを入れておきましょう。


<h2>private repositoryから参照先でパッケージを使用する方法</h2>
それでは、上記で作成したパッケージを別レポジトリでインストールする方法を解説していきます。
私がやったように、Githubのprivate repositoryで作成したパッケージを、他のレポジトリにどう入れるのかを説明します。

privateなので、当然、認証を通さなければならないので<b>Githubのアクセストークンが必要</b>です。

アクセストークンについては[こちら](https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)を参考にしてください。


アクセストークンを手に入れたあとは下記のコマンドを打てば、認証が通ります。
```
$ git config --global url.https://<ユーザー名>:<アクセストークン>@github.com/.insteadOf https://github.com/
```
これでprivateからでもパッケージのインストールができるようになります。
Dockerファイルでpoetry installする場合は、RUNでコマンドを打てばいいです。

<br>
そして、あとは参照先のレポジトリでインストールするだけです。

参照先のpyproject.tomlで下記のように記述してください。

```
[tool.poetry.dependencies] # この項目に追記
demo-package = {git = "https://github.com/<レポジトリのURL>", branch = "develop" }
```
[tool.poetry.dependencies]でパッケージ名とレポジトリを指定すればインストールできます。
また、ブランチを指定することもできますが、コミットハッシュとバージョンタグにも対応しています。

```
コミットハッシュの場合
demo-package = {git = "https://github.com/<レポジトリのURL>", rev = "<commit hash>"
```
```
バージョンタグの場合
demo-package = {git = "https://github.com/<レポジトリのURL>", tag = "v0.13.0"
```
参照方法の参考は[こちら](https://cocoatomo.github.io/poetry-ja/dependency-specification/)。

pyproject.tomlに追記して、poetry installを打ち込めばパッケージが無事にインストールできます。



<h2>注意点</h2>
パッケージ化は大変便利ではあるんですが、注意点もあります。<br>
特に、環境依存については注意が必要です。<br><br>

パッケージをインストールするときは、当然、参照元のライブラリがインストールされるので、参照先でライブラリのバージョンが違った場合、コンフリクトを起こします。
なので、特に<b>ライブラリのバージョン管理は徹底する</b>必要があります。

ライブラリのバージョン管理は当然、参照元に合わせることになるので、アップデートするときは参照元で動作確認後に参照先で動作確認することになると思います。

参照先でインストールが動かない場合は、
<b>まずは参照元のアップデート、バージョンが合わなければ参照元で調整する</b>
とスムーズです。


環境をきちんと揃えられればそれにこしたことはないので、pythonやpoetryなどのバージョンは共通を使うようにするとパッケージ化の際のトラブルは少なくなると思います。