Closed8

Poetry を使ってみる

Yuki YamadaYuki Yamada

インストール

GitHub の README に従って実施する。
(どうでも良いがこういうcurlからパイプでスクリプト実行するタイプのインストール形式の場合は、脳死で実行しない方が良いね。ざっとでもソースコード読んだ方が良い。)

curl -sSL https://install.python-poetry.org | python3 -

macOS の場合、インストール先は$HOME/.local/binになるようなのでパスを通す必要がある。
私は普段、zshを使っているので~/.zshrcに以下のように追記した。

.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
Yuki YamadaYuki Yamada

poetry でプロジェクト作成

公式ドキュメントの手順に準拠する形で進める。

https://python-poetry.org/docs/master/basic-usage/

poetry new {プロジェクト名}でプロジェクトを作成できる。

poetry new sample

作成されたプロジェクトのディレクトリ構成は以下の通り。

sample
├── README.rst
├── pyproject.toml
├── sample
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_sample.py

特徴的なのはpyproject.tomlファイル。
このファイルを使ってプロジェクトの依存ライブラリなどを管理する。
作成時点での中身は以下の通り(メールアドレスは適当にマスクしてある)。

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"
Yuki YamadaYuki Yamada

poetry の設定

Poetry の設定の変更/確認にはconfigコマンドを使う。

https://python-poetry.org/docs/master/cli/#config

--listオプションをつけることで現在の設定を参照できる。

poetry config --list

出力は以下の通り。

output
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 --listvirtualenvs.in-project = trueとなっていれば問題はない。

依存関係の解決

依存関係の解決はinstallコマンドを使用する。

https://python-poetry.org/docs/master/cli/#install

installコマンドではpyproject.tomlの情報を読み取って、外部ライブラリなどを取得する。
またこの時に.venvディレクトリが存在しなければ作成される。

ということでひとまず実行する。

poetry install

.venvディレクトリが存在しない初回は少し時間を要する。

output
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ファイルはインストールした依存ライブラリのバージョンを正確に記録したもです。

Yuki YamadaYuki Yamada

Hello, World

設定が完了したので兎にも角にも恒例のプログラムを書いて実行する。
まずsampleディレクトリにmain.pyファイルを作成し以下の内容を記述する。

sample/main.py
#! /usr/bin/env python

def main() -> None:
    print("Hello, World!!")


if __name__ == "__main__":
    main()

スクリプトの実行にはrunコマンドを使用する。

poetry run sample/main.py
output
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 を追加して実行した。

Yuki YamadaYuki Yamada

Django プロジェクトを作成する

Web アプリケーションフレームワークの Django を使って簡単な Web アプリケーションを作ってみようと思う。

https://docs.djangoproject.com/ja/4.0/

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/ でおなじみの以下の画面を見ることができる。

Yuki YamadaYuki Yamada

Django プロジェクトにnlpアプリケーションを作成

先ほど作成した Djnaog プロジェクトのtiny_appnlpアプリケーションを作成する。

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.pyurls.pyを設定する必要がある。

nlp アプリケーションのviews.pyの設定

まずはHello, World!と出力するindex関数をviews.pyを記述する。

nlp/views.py
from django.http import HttpRequest, HttpResponse


# Create your views here.
def index(request: HttpRequest) -> HttpResponse:
    return HttpResponse("Hello, World")

nlp アプリケーションのurls.pyの設定

次にnlpアプリケーションのルーティングを制御するurls.pyを作成する。
こちらはまずファイルの作成から行う。

touch nlp/urls.py

作成したviews.pyにルーティンが行われるようにurls.pyに記述する。

nlp/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index')
]

tiny_app プロジェクトのurls.pyの設定

続いてプロジェクト全体のurls.pyで nlp アプリケーションへのルーティングを追加する。

urls.py
"""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と表示されてることを確認する。

Yuki YamadaYuki Yamada

閑話休題 dev-dependencies を利用する

Django のプロジェクトのセットアップは終わったので、Poetry で開発用のパッケージを管理する方法について調べる。

Poetry ではaddコマンドに--dev (-D)オプションを渡すことで開発用の依存関係にパッケージを追加できる。

ここでは開発用のパッケージとして、pysen を導入する。

  • GitHub

https://github.com/pfnet/pysen

  • PyPI

https://pypi.org/project/pysen/

GitHub の README を参考にして以下のコマンドで導入する。

poetry add -D pysen==0.10.1 -E lint

GitHub の README を参考にpyproject.tomlに以下を追記する。
変更点は Python 3.8 を使用しているのでpy_versionpy38にしたくらい。

pyproject.toml
[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
このスクラップは2022/08/22にクローズされました