Poetry を使ってみる
Poetry とは
Python のパッケージ管理ソフトウェアの一つ。
- GitHub リポジトリ
- 公式ドキュメント
実行環境
- macOS Big Sur
- Python 3.8.7(pyenv)
インストール
GitHub の README に従って実施する。
(どうでも良いがこういうcurl
からパイプでスクリプト実行するタイプのインストール形式の場合は、脳死で実行しない方が良いね。ざっとでもソースコード読んだ方が良い。)
curl -sSL https://install.python-poetry.org | python3 -
macOS の場合、インストール先は$HOME/.local/bin
になるようなのでパスを通す必要がある。
私は普段、zshを使っているので~/.zshrc
に以下のように追記した。
# poetry
export POETRY_ROOT="$HOME/.local/"
export PATH="$POETRY_ROOT/bin:$PATH"
以上でインストール完了。
poetry --version
Poetry version 1.1.12
アンイストール方法の確認
インストール方法を確認したので、アンインストール方法も確認しておく。
インストールスクリプトに--uninstall
オプションをつければ良い。
(これもcurl
からパイプするのか…)
curl -sSL https://install.python-poetry.org | python3 - --uninstall
poetry でプロジェクト作成
公式ドキュメントの手順に準拠する形で進める。
poetry new {プロジェクト名}
でプロジェクトを作成できる。
poetry new sample
作成されたプロジェクトのディレクトリ構成は以下の通り。
sample
├── README.rst
├── pyproject.toml
├── sample
│ └── __init__.py
└── tests
├── __init__.py
└── test_sample.py
特徴的なのはpyproject.toml
ファイル。
このファイルを使ってプロジェクトの依存ライブラリなどを管理する。
作成時点での中身は以下の通り(メールアドレスは適当にマスクしてある)。
[tool.poetry]
name = "sample"
version = "0.1.0"
description = ""
authors = ["wf-yamaday <*****@*******>"]
[tool.poetry.dependencies]
python = "^3.8"
[tool.poetry.dev-dependencies]
pytest = "^5.2"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
poetry の設定
Poetry の設定の変更/確認にはconfig
コマンドを使う。
--list
オプションをつけることで現在の設定を参照できる。
poetry config --list
出力は以下の通り。
cache-dir = "/Users/yamaday/Library/Caches/pypoetry"
experimental.new-installer = true
installer.parallel = true
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/yamaday/Library/Caches/pypoetry/virtualenvs
poetry プロジェクトの仮想環境
Poetry のデフォルトの設定だとキャッシュディレクトリに仮想環境を作成する。
この設定は何かと不便になるので、プロジェクト内に.venv
ディレクトリを作成するようにしたい。
そこで以下のコマンドでvirtualenvs.in-project
の値をtrue
に変更する。
poetry config virtualenvs.in-project true
変更後、poetry config --list
でvirtualenvs.in-project = true
となっていれば問題はない。
依存関係の解決
依存関係の解決はinstall
コマンドを使用する。
install
コマンドではpyproject.toml
の情報を読み取って、外部ライブラリなどを取得する。
またこの時に.venv
ディレクトリが存在しなければ作成される。
ということでひとまず実行する。
poetry install
.venv
ディレクトリが存在しない初回は少し時間を要する。
Updating dependencies
Resolving dependencies... (89.6s)
Writing lock file
Package operations: 8 installs, 0 updates, 0 removals
• Installing pyparsing (3.0.6)
• Installing attrs (21.4.0)
• Installing more-itertools (8.12.0)
• Installing packaging (21.3)
• Installing pluggy (0.13.1)
• Installing py (1.11.0)
• Installing wcwidth (0.2.5)
• Installing pytest (5.4.3)
Installing the current project: sample (0.1.0)
実行後はプロジェクト配下に.venv
ディレクトリとpoetry.lock
ファイルが作成される。
poetry.lock
ファイルはインストールした依存ライブラリのバージョンを正確に記録したもです。
Hello, World
設定が完了したので兎にも角にも恒例のプログラムを書いて実行する。
まずsample
ディレクトリにmain.py
ファイルを作成し以下の内容を記述する。
#! /usr/bin/env python
def main() -> None:
print("Hello, World!!")
if __name__ == "__main__":
main()
スクリプトの実行にはrun
コマンドを使用する。
poetry run sample/main.py
Hello, World!!
ひとまず世界への挨拶は完了。
run 時に遭遇したエラー
一応、Hello, World!!
出力を得るまでに遭遇したエラーをまとめておく。
PermissionError: [Errno 13] Permission denied: 'sample/main.py'
作成したmain.py
に実行権限がなかった。
(なおファイル作成操作は VSCode 上で GUI で行った。)
解決策としては単純で実行権限を付与した。
chmod +x sample/main.py
OSError: [Errno 8] Exec format error: 'sample/main.py'
pyenv
を使っている影響なのかどのpyhton
インタプリタを使うのかを選択できていない模様。
解決策としてはmain.py
の先頭行に#! /usr/bin/env python
を追加して実行した。
Django プロジェクトを作成する
Web アプリケーションフレームワークの Django を使って簡単な Web アプリケーションを作ってみようと思う。
Djnago を依存関係に追加
add
コマンドを利用して Django を依存関係に追加する。
poetry add Django
Django プロジェクトの作成
Djnago を依存関係に追加したらrun
コマンドからdjango-admin
を使って、Djnago のプロジェクトを作成する。
ひとまずプロジェクト名はtiny_app
とする。
poetry run django-admin startproject tiny_app
プロジェクトルートに以下のような構造のtiny_app
ディレクトリができる。
tiny_app
├── manage.py
└── tiny_app
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py
以下のコマンドで開発用サーバを使ってアプリケーションを立ち上げる。
poetry run tiny_app/manage.py runserver
正常に起動すれば http://127.0.0.1:8000/ でおなじみの以下の画面を見ることができる。
nlp
アプリケーションを作成
Django プロジェクトに先ほど作成した Djnaog プロジェクトのtiny_app
にnlp
アプリケーションを作成する。
cd tiny_app
poetry run ./manage.py startapp nlp
nlp
ディレクトの構造は以下の通り。
nlp
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py
nlp アプリケーションの最低限の設定
Djangoでアプリケーションを作成する場合にはまずviews.py
とurls.py
を設定する必要がある。
views.py
の設定
nlp アプリケーションのまずはHello, World!
と出力するindex
関数をviews.py
を記述する。
from django.http import HttpRequest, HttpResponse
# Create your views here.
def index(request: HttpRequest) -> HttpResponse:
return HttpResponse("Hello, World")
urls.py
の設定
nlp アプリケーションの次にnlp
アプリケーションのルーティングを制御するurls.py
を作成する。
こちらはまずファイルの作成から行う。
touch nlp/urls.py
作成したviews.py
にルーティンが行われるようにurls.py
に記述する。
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index')
]
urls.py
の設定
tiny_app プロジェクトの続いてプロジェクト全体のurls.py
で nlp アプリケーションへのルーティングを追加する。
"""tiny_app URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('nlp/', include('nlp.urls')),
path('admin/', admin.site.urls),
]
アプリケーションの立ち上げ
runserver
コマンドを使ってアプリケーションを立ち上げます。
poetry run ./manage.py runserver
http://127.0.0.1:8000/nlp/ にアクセスし、Hello, World
と表示されてることを確認する。
閑話休題 dev-dependencies を利用する
Django のプロジェクトのセットアップは終わったので、Poetry で開発用のパッケージを管理する方法について調べる。
Poetry ではadd
コマンドに--dev (-D)
オプションを渡すことで開発用の依存関係にパッケージを追加できる。
ここでは開発用のパッケージとして、pysen を導入する。
- GitHub
- PyPI
GitHub の README を参考にして以下のコマンドで導入する。
poetry add -D pysen==0.10.1 -E lint
GitHub の README を参考にpyproject.toml
に以下を追記する。
変更点は Python 3.8 を使用しているのでpy_version
をpy38
にしたくらい。
[tool.pysen.lint]
enable_black = true
enable_flake8 = true
enable_isort = true
enable_mypy = true
mypy_preset = "strict"
line_length = 88
py_version = "py38"
[[tool.pysen.lint.mypy_targets]]
paths = ["."]
pysen は以下のコマンドで実行できる。
# 静的解析
poetry run pysen run lint
# フォーマッターの実行
poetry run pysen run format