Poetry を始める

Poetry を使ってみよう。

# Poetry をインストール

[これ](https://python-poetry.org/docs/) に従う。

# Poetry をはじめる前に Python の仮想環境をつくる

Poetry も仮想環境を作る機能を持つが、ここではそうさせない。というのも、例えば docker の中で Poetry を使おうとする場合は container の持つ Python をそのまま利用するケースもあるので、それを想定して Poetry の外部に Python がある状態でやる。

開発環境を整えるときなんかは、以下の手順がそのまま使えるだろう。

以下、ローカルに python3.11 がインストールされていることが前提。

```bash
# 仮想環境を作る
python3 -m venv .venv

# activate
source .venv/bin/activate
```

# Poetry をはじめる

プロジェクトを一から始める場合は、以下のコマンドで始める。

```bash
poetry init
```

こうすると、 `pyproject.toml` というものができあがる。 `pyproject.toml` は、正確ではないが雰囲気がわかる言い方をすれば、 `requirements.txt` に相当するファイル。

以下で、今の poetry が認識している環境情報を得ることができる。 venv がちゃんと利いているかなんかは、これで確かめるとよい。

```bash
poetry env info
```

# Poetry をつかう

参考 → https://python-poetry.org/docs/cli/

Poetry コマンドの使い方をみる。

```bash
poetry list
```

`pyproject.toml` にあるライブラリを一斉にインストール。開発用のライブラリも含む。

```bash
poetry install
```

`pyproject.toml` にあるライブラリを一斉にインストール。ただし、開発用のライブラリは除く。これは本番環境に使う。

```bash
poetry install --only main
```

`pyproject.toml` にあるライブラリに、環境を一致させる。例えば、自分の環境にぐちゃぐちゃと試しに入れてみたライブラリが入っているときなど、そういうのを掃除して、理想的なライブラリの状態にしてくれる。これはめっちゃいい。

```bash
poetry install --sync
```

ライブラリ追加。 `pyproject.toml` にも行が追加される。

```bash
poetry add openai
```

ライブラリ追加(開発用のライブラリ)。 `pyproject.toml` にも行が追加される。

```bash
poetry add --group dev autopep8
```

ライブラリ削除。 `pyproject.toml` からも行が削除される。

```bash
poetry remove openai
```

# Poetry でライブラリをアップデートする手順

このセクションでは、 Poetry を用いてライブラリをアップデート手順を示す。

例として openai のライブラリを使う。

まず、現在インストールされている openai のバージョンを確認する。

```bash
poetry show
```

```
(...)
openai             0.27.5    Python client library for the OpenAI API
(...)
```

今現在 openai は 0.27.**5** がインストールされている。

さて、 `pyproject.toml` に以下のような記述があるとする。

```toml
[tool.poetry.dependencies]
python = "^3.11"
openai = "^0.27.0"
```

`"^0.27.0"` とある。これは「0.27.0 以上、 0.28.0 未満のバージョンだけ許可する」という意味。これはライブラリのバージョンの**制約を意味している**。**現在インストールされているバージョンが記載されているわけではないことに注意する。** このあたりの文法は [こちら](https://python-poetry.org/docs/dependency-specification/) を参照。

この状態から 2 種類のアップデートの方法がある。

## `pyproject.toml` に書かれた制約の範囲内でアップデートする

つまり、「0.27.0以上、0.28.0未満のバージョンの中の最新バージョン」にアップデートする方法が、以下の `update` コマンドで OK.

```bash
poetry update openai
```

すると以下のようにバージョンが 0.27.**10** に上がった。ここで制約を満たしていることに注意する。

```
(...)
openai             0.27.10   Python client library for the OpenAI API
(...)
```
## `pyproject.toml` に記載された制約を超えて、とにかくライブラリを最新バージョンにアップデートする

以下のように、ライブラリの名前の末尾に `@latest` をつけて `add` する。

```bash
poetry add openai@latest
```

すると以下のように(2023/10/07時点の)最新バージョンの 0.**28.1** がインストールできた。ここでは `pyproject.toml` に記載された制約を超えてインストールできていることに注意する。

```
poetry show
```

```
(...)
openai             0.28.1    Python client library for the OpenAI API
(...)
```

このコマンドが実行されるときに `pyproject.toml` も一緒に書き変わってるので安心してほしい。

```toml
[tool.poetry.dependencies]
python = "^3.11"
openai = "^0.28.1"
```

このあたりの挙動を知りたければ [こちら](https://python-poetry.org/docs/cli/#add) を参照。

# Docker コンテナの中で Poetry を使う

本番向けの設定例

```Dockerfile
FROM python:3.11

WORKDIR /app
COPY pyproject.toml poetry.lock /app/
RUN pip install -U pip && pip install poetry && \
    poetry config virtualenvs.create false && \
    poetry install --only main

CMD ["sleep", "3600"]
```

ポイント:
* `poetry config virtualenvs.create false` で vertualenv を作らず、 docker が持っている Python を使うことを指定している。
* `poetry install --only main` で、開発用のライブラリをインストールしないようにしている。


# 補遺

## `poetry show` の見え方

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285861/edee93b0-7e06-bc36-e711-1197b715e5d8.png)

`poetry install --only main` などすると、このように赤文字と青文字で見え方が変わる。
青文字が実際にインストールされているライブラリ、つまり `pip freeze` と一致するもの。一方赤文字は、実際にはインストールされていないもの。

## Rye との比較

[Rye](https://rye-up.com/guide/basics/) も流行っている。今ライブラリ管理を考えるとしたら Rye も見ておく必要があるだろう。

Rye と Poetry の違いは、 Python の仮想環境も面倒みるか、みないか、というところ。 Rye は面倒みるけど、 Poetry は面倒みない。

例えば `rye pin 3.11 && rye sync` で、勝手に python3.11 をインストールして、さらにそれに合うライブラリもインストールしてくれる。ここで `rye pin 3.10 && rye sync` とすれば、勝手に python3.10 をインストールして、さらにそれに合うライブラリもインストールしてくれる。

これは確かに良い。これ以外の使用感は Poetry に似ている。それもまた良い。

良いのだが、一方で、以下の点で今のところ微妙なところがあって、使うのにためらう:
* [Rye の github の repository](https://github.com/mitsuhiko/rye) に "Rye: An Experimental Package Management Solution for Python" と書いてある。 Experimental 、という文字がなんかね。
* Docker では使いにくいかも。 [この issue](https://github.com/mitsuhiko/rye/discussions/239) を見ると、めっちゃめんどくさい。そもそも Docker の中では指定した Python のバージョンを使うから Rye である積極的な意味はない。

ということで、個人開発で便利に使うには良さそうだけれども、 Docker やら Railway で動かそうとするとめんどくささが勝つかもしれない。

... という見立てなのだけど、どうだろう。「Rye が Python のパッケージ管理のデファクトになりつつある」という言葉も見かけるので、このあたりはひょっとして僕が知らないだけで解決できているのかも。