FastAPIを使ったAPIサーバーを構築することになり、久々にPythonをしっかり触ることになりそうなので、古い知識のアップデートついでに調べたことを備忘録としてまとめました。
古い知識の1つにpipを使ったパッケージ管理があります。
Pythonを使い始めた当時にパッケージ管理を調べていたらpip freeze
を使ったやり方をよく見かけていたので、その記憶をアップデートすることなくそのまま使っていました。
当時は、Hello Worldに毛が生えたくらいのプログラムしか書いていなかったのでそこまで気にならなかったのですが、本格的にプログラムを書くようになってくるとあれこれパッケージをたくさん使用するようになります。
それと合わせて自分のローカルマシン上だけの開発に留まらず、仮想化やCI/CDなどその先に向けた準備として再現性ある環境作りを行いながらメンテナンス性も重視していく必要があります。
しかし、pip freeze
を実行して出力した内容を改めて眺めてみるとpip install時に指定したパッケージ以外にも関連するパッケージも表示されてしまいます。
個人的には、親パッケージ以外が一覧上に表示されると読みにくさがあるので、どうしても好きになれないですし、削除する際にどれを削除したらいいのかを特定するのが一手間かかります。
その時にあれこれ調べていたらpoetryというツールを見つけたので触ってみたところ、npmと使い勝手が似ているので違和感なく使うことができました。
pipを使っていた時のやり方を前半で書いて、後半にpoetryの使い方を紹介しようと思います。
pipではどうやってたの?
よく入門書とかブログを見ていたらよく見かけるやり方と思うのですが、このような感じでやっていました。
pip install <パッケージ名> pip freeze > requirements.txt pip install -r requirements.txt
pip install
で使いたいパッケージをあれこれ適当にインストールします。仮想化技術などを使用して環境を立ち上げたり、潰したりしたい時は一括でインストールできるように情報をまとめる必要があるので、pip freeze
コマンドを実行してインストールしたパッケージ情報を出力します。
試しにfastapi[all]
をインストールしたときのイメージがこんな感じです。
依存関係が全て見えているような感じになります。
anyio==3.7.1 certifi==2023.7.22 click==8.1.6 dnspython==2.4.1 email-validator==2.0.0.post2 fastapi==0.100.1 h11==0.14.0 httpcore==0.17.3 httptools==0.6.0 httpx==0.24.1 idna==3.4 itsdangerous==2.1.2 Jinja2==3.1.2 MarkupSafe==2.1.3 orjson==3.9.2 pydantic==2.1.1 pydantic-extra-types==2.0.0 pydantic-settings==2.0.2 pydantic_core==2.4.0 python-dotenv==1.0.0 python-multipart==0.0.6 PyYAML==6.0.1 sniffio==1.3.0 starlette==0.27.0 typing_extensions==4.7.1 ujson==5.8.0 uvicorn==0.23.2 uvloop==0.17.0 watchfiles==0.19.0 websockets==11.0.3
環境を新しく立ち上げるときにpip install
にオプションで-r requirements.txt
を付け加えて、先ほど出力したファイルを指定することでまとめてインストールすることができます。
詳しい仕組みまでは調べていないのですが、子の依存関係まで出力されているのでパッと親となるパッケージが判別しにくくなっているのかなと思います。
poetryではどうやるの?
使用するOSなどによってやり方は異なりますが、今回はLinux系の手順を例に書いていきます。
インストールは
curl -sSL https://install.python-poetry.org | python3 -
を実行して行います。
インストール場所やバージョンを指定したい場合は、変数を設定することで変更することができます。
よく使いそうな変数に絞って記載しています。
変数名 | 説明 |
---|---|
POETRY_HOME | インストール先のディレクトリを変更する |
POETRY_VERSION | インストールするバージョンを指定する |
インストールが完了したら、poetry --version
などのコマンドを実行して動作確認します。
初めて使う最初のみ次のコマンドを実行します。
poetry init
するとpyproject.toml
というファイルが作成されます。これはnpmでいうpackagae.jsonのようなものです。
パッケージをインストールする際は、poetry add <パッケージ名>
を実行して、新しく環境を立ち上げ直す際などにpoetry install
を実行するとまとめてインストールしてくれます。
pyproject.toml
に依存関係の情報がまとめられますが、このような感じでインストール時に指定したパッケージのみが表示されているのでわかりやすくなりました。
・・・ [tool.poetry.dependencies] python = "^3.11" fastapi = {extras = ["all"], version = "^0.100.1"} ・・・
それ以外にも依存関係のツリーをみようとしたら
poetry show fastapi --tree
を実行するだけで表示することもできます。
fastapi 0.100.1 FastAPI framework, high performance, easy to learn, fast to code, ready for production ├── email-validator >=2.0.0 │ ├── dnspython >=2.0.0 │ └── idna >=2.0.0 ├── httpx >=0.23.0 │ ├── certifi * │ ├── httpcore >=0.15.0,<0.18.0 │ │ ├── anyio >=3.0,<5.0 │ │ │ ├── idna >=2.8 │ │ │ └── sniffio >=1.1 │ │ ├── certifi * (circular dependency aborted here) │ │ ├── h11 >=0.13,<0.15 │ │ └── sniffio ==1.* (circular dependency aborted here) │ ├── idna * (circular dependency aborted here) │ └── sniffio * (circular dependency aborted here) ├── itsdangerous >=1.1.0 ├── jinja2 >=2.11.2 ・・・(長いので途中まで)・・・
記憶が確かであればpipコマンドは標準ではサポートしておらず、別でツールをインストールする必要があったような気がします。
おわりに
日頃からPythonを使いこなしているか方からすると、poetryのようなツールを活用することは基本のキなのかもしれませんが、個人的にはまた1つ知識のアップデートなるいい機会になりました。
また改めて触り直す機会を作るにはなかなか難しいところではありますが、過去に触ったツールなども時々触ってみたいものですね。