138
88

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PoetryとGitとDockerを使ったPython開発フロー

Last updated at Posted at 2020-03-11

はじめに

この記事は以前書いたpipenvとGitとDockerを使ったPython開発フローの姉妹記事です。Pipenvの開発があまり活発ではなくなった現在、Pythonを使ったプロジェクトではPoetryを使う場面もぼちぼち出てくると思います。そこで改めてPoetryを使った開発フローについてまとめ直してみようと思います。

全体の流れ

  1. 開発環境のインストール
  2. プロジェクトの初期化
  3. Docker化

前提環境

  • Python 3.x
  • UnixライクなOS

開発環境のインストール

Poetryのインストール

たいていの場合お使いのOS付属のパッケージマネージャーからインストールすることができると思います。

macOSの場合

$ brew install poetry

Arch Linux

$ sudo pacman -S python-poetry

Ubuntu 18.04

残念ながら標準リポジトリには登録されていないので、公式インストーラーからインストールします。

$ sudo apt install python3 python3-pip
$ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python3

インストールが完了したら ~/.poetry/bin に PATH を通してください。お使いのシェルによると思いますが、~/.zshrc~/.bashrc に以下のような設定を加えます。

~/.bashrc
export PATH=${HOME}/.poetry/bin:${PATH}

その他ツールの導入

この先 Git と Docker / Docker Compose を使うので用意しておいてください。

Python プロジェクトの初期化

ではいよいよ poetry を使って Python プロジェクトを初期化していきます。

プロジェクトの作成

まずは適当なディレクトリを作ってその中に入っておきます。

$ mkdir sample-app
$ cd sample-app

次に poetry init を実行することでプロジェクトの初期化ができます。対話式になっているので、それぞれ答えていきましょう。途中依存パッケージをインストールするかどうかも聞かれますが、今回は個別にインストールしたいのでスキップしておきます。

$ poetry init

This command will guide you through creating your pyproject.toml config.

Package name [sample_app]:
Version [0.1.0]:
Description []:  Sample App
Author [Aruneko <webmaster@example.com>, n to skip]:
License []:  MIT
Compatible Python versions [^3.7]:

Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
Generated file

[tool.poetry]
name = "sample_app"
version = "0.1.0"
description = "Sample App"
authors = ["Aruneko <aruneko99@gmail.com>"]
license = "MIT"

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

[tool.poetry.dev-dependencies]

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


Do you confirm generation? (yes/no) [yes]

対話環境を抜けると pyproject.toml ができあがっています。これでプロジェクトの初期化は完了です。

$  ls
pyproject.toml

Poetryの 初期設定

通常は ~/Library/Caches/pypoetry/virtualenvs~/.config/poetry 以下に作成される Python 仮想環境が、以下の設定を追加しておくとプロジェクトルート直下に .venv ディレクトリを作って、そこで Python 環境を管理してくれるようになります。お好みで設定してください。

$ poetry config virtualenvs.in-project true --local

なお、この設定は pyproject.toml ではなく poetry.toml に記載されるので注意してください。

パッケージの追加

Poetry 環境下では npm などと同じく add を使ってパッケージを追加します。サンプルとして FastAPI を使ったアプリケーションを開発してみましょう。

$ poetry add fastapi uvicorn

Poetry でパッケージをインストールするとその際に解決できた依存パッケージや、それぞれのパッケージのバージョン情報が poetry.lock に書き込まれます。

開発時にしか使わないパッケージはこれまた npm と同様に -D オプションを付けてインストールします。例えばコードフォーマッターである black をインストールしてみましょう。

$ poetry add -D black

ここまでのコマンドを実行すると、pyproject.tomltool.poetry.dependencies セクションと tool.poetry.dev-dependencies セクションに今までインストールしたパッケージ群が追加されていることが確認できます。

pyproject.toml
[tool.poetry.dependencies]
python = "^3.7"
fastapi = "^0.52.0"
uvicorn = "^0.11.3"

[tool.poetry.dev-dependencies]
black = "^19.10b0"

今後は必要に応じたパッケージをその都度インストールしてください。

Gitの初期化

続いてこのプロジェクトを Git で管理するために Git の初期化を行います。gitignore.io を利用して、まず .gitignore ファイルを作ってしまいましょう。今回は Python と virtualenv を指定して作ってもらいます。.gitignore に追加の設定が必要な方はここで編集しておいてください。

.gitignore ができたら手元の Git リポジトリを初期化して、ざっくり全ファイルを追加して commit しておきます。

$ curl -o .gitignore https://www.gitignore.io/api/python,virtualenv
$ git init
$ git add pyproject.toml poetry.lock poetry.toml .gitignore
$ git commit -m "Initial Commit"

仮想環境への入り方

Poetry で作成した Python 仮想環境に入るには shell サブコマンドを使います。仮想環境に入り忘れるとインストールしたはずのパッケージが見えないなどいろいろな不具合が起こりますので、よく確認するようにしましょう。なお、抜けるときは exit コマンドです。

$ poetry shell
(.venv)$ exit

Docker 化

では一通り Poetry プロジェクトを作り終わったところでいよいよ Docker 化に取り組んでいきます。

.dockerignore の準備

転送しなくて良いファイルは .dockerignore に記入するようにしましょう。特に .venv ファイルをプロジェクトルートに作るように設定している場合は必ず記述するようにします。その他にも __pycache__ ディレクトリなどは転送しないようにしておくと良いでしょう。

.dockerignore
.venv/
__pycache__/

Dockerfile の準備

ついに Dockerfile を書いていきます。今回は Multi Stage Build を使った方法を紹介します。前半で requirements.txt を作成、後半でそれを用いて Python アプリケーションの載った Docker Image を作成するという手順に分かれています。

そもそもなぜそうする必要があるのかというと、poetry.lock を読むためには Poetry をインストールする必要がある一方、アプリケーションが載るコンテナには Poetry を入れておく必要がないため、これらを切り離したいという意図があるからです。Poetry には requirements.txt を生成する機能があるため、これを活用していきます。

まず前半部分の説明から。Docker のキャッシュ戦略をうまく使うため、一番最初に Poetry をインストールしてしまいます。こうすることで、ビルドのたびに Poetry をインストールする手間が省けます。次に、pyproject.tomlpoetry.lock だけをコピーして、requirements.txt を生成してしまいます。

続いて後半の説明です。できあがった requirements.txt を前半部分からコピーしてきた上で、pip コマンドを使ってそれらのパッケージを全てインストールします。もしこれらのファイルに変更がない場合はキャッシュが使われて自動で次のレイヤのビルドが行われるので、ビルドのたびに依存パッケージをダウンロードしてくるような動作を事前に防止することができます。これで圧倒的にビルド時間を節約できるのでオススメの構成です。インストールが終わった後に、各種 Python スクリプトを転送して、動かしたいコマンドなどを書いておけば完成です。

FROM python:3.8-slim as builder

WORKDIR /usr/src/app

RUN pip install poetry

COPY pyproject.toml poetry.lock ./

RUN poetry export -f requirements.txt > requirements.txt


FROM python:3.8-slim

ENV PYTHONUNBUFFERED=1

WORKDIR /usr/src/app

COPY --from=builder /usr/src/app/requirements.txt .

RUN pip install -r requirements.txt

COPY . .

EXPOSE 8000
CMD [ "uvicorn", "main:app", "--host", "0.0.0.0" ]

ついでに Docker Compose の設定もしておくと良いでしょう。開発用にローカルファイルをマウントした上でオートリロードの設定などを入れておくとはかどるかもしれません。

docker-compose.yml
version: '3'

services:
  app:
    build: .
    volumes:
      - ./:/usr/src/app
    ports:
      - "8000:8000"
    command: ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0"]

FAQ

パッケージの更新方法

poetry update が使えます。ただし pyproject.toml に記述したバージョンを超えてアップデートされることはないので、メジャーバージョンアップの際などは注意してください。

パッケージの削除方法

poetry remove PACKAGE_NAME で削除できます。

途中から開発に参加した場合

poetry install で開発用依存パッケージごとインストールできます。

おわりに

ここまで Poetry を使った Python プロジェクトの開発フローについて説明してきました。Poetry においても Pipenv と同様に poetry.lock を活用することによって開発者間でのバージョンの差異を取り除き、安定した開発環境を提供できるようになっていると思います。また、PEP で取り決められたフォーマットに従っているため、将来性も悪くないように感じられます。

一方で、Pipenv では実現できていたワンライナーを走らせる script 機能を欠いているなど、Python アプリケーションではなく Python パッケージ開発者のためのプロジェクト管理ツールであるという印象も受けます。Lint とかテストを実行するのに結構使うんですけどね、この機能。

ということで Poetry も Pipenv も一長一短な感じがあります。お使いのプロジェクトに合わせて選択していくのが現時点では無難なのかなと思うところです。それでは皆さん良い Python ライフをお送りください。

138
88
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
138
88

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?