LoginSignup
6
4

More than 1 year has passed since last update.

Poetryプロジェクトのテンプレートを作ってみた

Last updated at Posted at 2023-02-14

概要

新しいプロジェクトを作るとき、毎回一から環境構築するのは面倒だし、ミスがあるかもしれないし、そんな反復作業をするより開発に時間を回したい!
ということで、Python用のパッケージ管理ツールの一つである「Poetry」を使ったPythonプロジェクトのテンプレートを作ってみた。
自分用ではあるけど、基本的な構成ではあるため他の人も使えるように公開している。

構成はざっと以下の通り。

  • poetry (パッケージ管理ツール)
  • flake8 (リンター)
  • black (フォーマッター)
  • pytest (テスト)
  • taskipy (タスク定義)
  • pyinstaller (実行ファイル化)
  • .vscode/settings.jsonでファイル保存時自動フォーマット

本記事で説明すること

  • つかいかた
  • 内容解説

本記事で説明しないこと

  • poetryのインストール手順 (poetryはインストール済であることが前提)
  • poetry自体の使い方・解説
  • 各ライブラリの詳細な解説

つかいかた

clone

GitHubに公開してるので基本的にcloneしてあとは良しなに。
projectNameは好きなプロジェクト名に置き換えてください。

git clone https://github.com/torippy1024/poetry-template.git projectName
cd projectName
poetry install

ディレクトリ構成

ディレクトリ構成は以下の通り。

┣ .vscode/           # vscode用の設定記述
┣ src/               # ソースコードはここに置く
┃   ┗ main.py        # エントリーポイント
┣ tests/             # テストコードはここに置く
┃   ┗ test_main.py
┣ .flake8            # flake8の設定
┣ .gitignore
┣ README.md
┣ poetry.lock
┗ pyproject.toml

src/main.pyif __name__ == "__main__":にメイン処理を書く。
テンプレートは足し算のサンプル。

src/main.py
def addition(num1: float, num2: float):
    return num1 + num2


if __name__ == "__main__":
    print("Please enter two numbers.")

    try:
        num1 = float(input("num1: "))
        num2 = float(input("num2: "))
    except ValueError:
        print("Invalid input. Please enter number.")
        exit()

    result = addition(num1, num2)
    print(f"{num1} + {num2} = {result}")

後述するが、task runsrc/main.pyを実行できる。

> task run
Please enter two numbers.
num1: 5
num2: 3
5.0 + 3.0 = 8.0

testsフォルダにはテストコードを書く。

tests/test_main.py
from src.main import addition


def test_addition():
    result = addition(2, 3)
    assert result == 5

task testでpytestによるテストを実行できる。

> task test
====================== test session starts =======================
platform win32 -- Python 3.10.0, pytest-7.2.1, pluggy-1.0.0        
rootdir: ...
collected 1 item

tests\test_main.py .                                        [100%] 

======================= 1 passed in 0.02s ========================

機能

poetry shellで仮想環境に入ったあと、以下のコマンドが使える。

  • task run: src/main.py を実行
  • task lint: flake8 で lint
  • task build: pyinstaller で exe化
  • task build-one: pyinstaller で exe化 (+ 1つのファイルにまとめる)
  • task test: pytest 実行

また、vscodeでファイル保存時、自動フォーマットが動いてくれる。

ちょっとした解説とカスタマイズのしかた

以下はもう少し構成が知りたい人と、一部カスタマイズして使いたいな~と思った人向け。

リンター・フォーマッター

リンターはflake8、フォーマッターはblackを採用している。
選定はこちらの記事を参考にした。

どちらの設定もデフォルトのままでいいかなと思っているが、flake8とblackのルールに一部競合するところがあるらしいので、その部分だけflake8の設定を変えてあげている。

.flake8
[flake8]
max-line-length = 88
extend-ignore = E203

また、VSCodeでファイルを保存したとき、blackで自動フォーマットしてほしいため、vscodeの設定ファイルを以下のようにしている。

.vscode/settings.json
{
  "python.formatting.provider": "black",
  "editor.formatOnSave": true
}

flake8をカスタマイズしたい場合は、以下の公式ドキュメントを参考に.flake8に追記すると良いだろう。

blackのカスタマイズは以下ご参考に。

テスト

テストモジュールはpytestを採用。
選定は以下の記事を参考にした。

詳しい解説は私自身まだ十分に使いこなせていないため省略するが、
pytestは、testから始まるファイルのtestから始まる関数を対象にするらしいので注意。

タスク定義

タスク定義にはtaskipyを使っている。
taskipyはPythonのタスクランナーである。
taskipyを使うとpyproject.tomlにタスクを定義することができる。

例えば、今回作成したテンプレートのpyproject.tomlの下には以下の記述がある。

pyproject.toml
[tool.taskipy.tasks]
run = "poetry run python src/main.py"
lint = "poetry run flake8 src --show-source --statistics"
build = "poetry run pyinstaller -y src/main.py"
build-one = "poetry run pyinstaller -y src/main.py --onefile"
test = "poetry run pytest"

このようにタスク名 = "実行したいコマンド"としてあげると、task タスク名実行したいコマンドが実行される。

src/main.pyを実行するためにpython src/main.pyなどと打つことなくtask runのように短いコマンドかつ意味のあるコマンドで実行できるためとても便利。
加えて、fastapiのプロジェクトの場合はrun = "poetry run uvicorn src.main:app"と書き換えてあげたり、プロジェクトによってタスク名に合わせたコマンドに修正してあげることで、「どのプロジェクトでも実行したいときはtask run!」と統一することができる。

実行ファイル化

こちらは利用できるケースが限られているが、ものによってはpyinstallerというモジュールを使うことで実行ファイル化(exe化)することができる。

実行ファイル化できてしまえばPython環境が要らなくなるので配布しやすくなる。
適切なPythonバージョンをインストールしてもらって、pipで必要なモジュールを全部インストールしていもらって…などせずとも、exeファイル一個投げてダブルクリックしてもらうだけで動くのだ。

実際にPythonで作ったものをpyinstallerを使ってexeファイル化して配布などもしてみたりしている。
(コードは全然大した内容じゃないが、ダウンロードしてすぐ使える形式で配布しているだけで、なんか中身があるように見える)

前述の通り、task buildtask build-oneでpyinstallerが走るように設定している。
実行すると、上手くいけばdist/ディレクトリの中にexeファイルが生成されるはずである。
特にtask build-oneはファイルを完全に一つのファイルにまとめてくれるので、基本的にこっちを使っている。(開発のときはtask buildの方が早いかも?)

poetry管理外のバイナリに依存していたり、fastapiなどの単純にsrc/main.pyを実行するわけではないサーバ系だったり、なんか必要なライブラリをpyinstallerが網羅してくれなかったり(transformers使っているプロジェクトで直面した)する場合は、色々な設定をしないと実行ファイル化できないので、そこは調べてがんばってください…。

最後に

自分用のテンプレートがあると、何か作りたくなったときに一瞬で環境ができるのでとても快適です。
みなさんも自分用のテンプレートを作ってみてはいかがでしょうか?

また、「このテンプレートのこの設定方法あまり推奨されないよ!」だったり、「こっちのライブラリの方がいいかも!」だったり、「このライブラリも追加で使ってみない?」などありましたら、ぜひコメントいただけると嬉しいです。

6
4
0

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
6
4