3
4

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を使ってPythonパッケージ(CLI)作成

Posted at

概要

Python用のパッケージ管理ツールPoetryを使って郵便番号から住所を取得するPythonパッケージを作成しコマンドラインから実行できるようにしてみる。

作業ディレクトリ作成

mkdir -p /tmp/$(date +%Y%m%d) && cd $_
pwd # /tmp/$(date +%Y%m%d)

開発環境構築

python3 -m venv venv
source venv/bin/activate

poetry インストール

pipのバージョンが低いとコケるのでpipをアップデートしてからインストールを行う

pip install --upgrade pip
pip install poetry

新しいPythonプロジェクト zip_code_app の作成

poetry new --src zip_code_app

プロジェクト作成後のディレクトリ構造

/tmp/$(date +%Y%m%d)/zip_code_app
├── README.rst
├── pyproject.toml
├── src
│   └── zip_code_app
│       └── __init__.py
└── tests
    ├── __init__.py
    └── test_zip_code_app.py

requests モジュールインストール

住所検索APIに問い合わせを行うために requests をインストール

cd /tmp/$(date +%Y%m%d)/zip_code_app
poetry add requests

requests がインストールされ pyproject.tomlファイルに requests が追記される。

pyproject.toml
 [tool.poetry.dependencies]
 python = "^3.7"
+requests = "^2.25.1"
>
 [tool.poetry.dev-dependencies]
 pytest = "^5.2"

郵便番号から住所を取得するプログラムを作成

vi /tmp/$(date +%Y%m%d)/zip_code_app/src/zip_code_app/core.py
core.py
import json
import requests
import sys

URL = 'http://zipcloud.ibsnet.co.jp/api/search?zipcode={}'

def zip_api(zip_code):
    r = requests.get(URL.format(zip_code))
    return r.json()

def main():
    zip_code = sys.argv[1]
    zip_json = zip_api(zip_code)
    print(json.dumps(zip_json, ensure_ascii=False))

if __name__ == '__main__':
    main()

core.py 作成後のディレクトリ構造

/tmp/20210710/zip_code_app
├── README.rst
├── poetry.lock
├── pyproject.toml
├── src
│   └── zip_code_app
│       ├── __init__.py
│       └── core.py ■ これが作成された
└── tests
    ├── __init__.py
    └── test_zip_code_app.py

実行してみる

poetry run python /tmp/$(date +%Y%m%d)/zip_code_app/src/zip_code_app/core.py 100-0001 | jq .
実行結果
{
  "message": null,
  "results": [
    {
      "address1": "東京都",
      "address2": "千代田区",
      "address3": "千代田",
      "kana1": "トウキョウト",
      "kana2": "チヨダク",
      "kana3": "チヨダ",
      "prefcode": "13",
      "zipcode": "1000001"
    }
  ],
  "status": 200
}

テストコード作成

vi /tmp/$(date +%Y%m%d)/zip_code_app/tests/test_zip_code_app.py
test_zip_code_app.py
from zip_code_app import __version__
from zip_code_app import core

def test_version():
    assert __version__ == '0.1.0'

def test_zip_api():
    expect = {
        'message': None,
        'results': [{'address1': '東京都',
              'address2': '千代田区',
              'address3': '千代田',
              'kana1': 'トウキョウト',
              'kana2': 'チヨダク',
              'kana3': 'チヨダ',
              'prefcode': '13',
              'zipcode': '1000001'}],
        'status': 200
    }
    actual = core.zip_api('100-0001')
    assert expect == actual

テスト実行

poetry install
poetry run pytest /tmp/$(date +%Y%m%d)/zip_code_app/tests/test_zip_code_app.py -vv

======================================== test session starts ========================================
platform darwin -- Python 3.7.3, pytest-5.4.3, py-1.10.0, pluggy-0.13.1 -- /private/tmp/$(date +%Y%m%d)/venv/bin/python3
cachedir: .pytest_cache
rootdir: /private/tmp/$(date +%Y%m%d)/zip_code_app
collected 2 items

tests/test_zip_code_app.py::test_version PASSED [ 50%]
tests/test_zip_code_app.py::test_zip_api PASSED [100%]

========================================= 2 passed in 0.37s =========================================


## スクリプトを登録

vi pyproject.toml


```toml:pyproject.toml
[tool.poetry.scripts]
zip-code = "zip_code_app.core:main"

スクリプトを実行してみる

poetry run zip-code 100-0001 | jq .
{
  "message": null,
  "results": [
    {
      "address1": "東京都",
      "address2": "千代田区",
      "address3": "千代田",
      "kana1": "トウキョウト",
      "kana2": "チヨダク",
      "kana3": "チヨダ",
      "prefcode": "13",
      "zipcode": "1000001"
    }
  ],
  "status": 200
}

パッケージをビルドする

poetry build
/tmp/20210710/zip_code_app
├── README.rst
|-- dist 
|   |-- zip_code_app-0.1.0-py3-none-any.whl ■ これが作成された
|   `-- zip_code_app-0.1.0.tar.gz ■ これが作成された
├── poetry.lock
├── pyproject.toml
├── src
│   └── zip_code_app
│       ├── __init__.py
│       └── core.py 
└── tests
    ├── __init__.py
    └── test_zip_code_app.py

パッケージをインストール

ビルドしたパッケージからインストールする場合

pip install /tmp/20210710/zip_code_app/dist/zip_code_app-0.1.0-py3-none-any.whl

github で管理している場合のインストール

pip install git+https://github.com/mykysyk/zip-code.git

スクリプトを実行してみる

zip-code 100-0001 | jq .
{
  "message": null,
  "results": [
    {
      "address1": "東京都",
      "address2": "千代田区",
      "address3": "千代田",
      "kana1": "トウキョウト",
      "kana2": "チヨダク",
      "kana3": "チヨダ",
      "prefcode": "13",
      "zipcode": "1000001"
    }
  ],
  "status": 200
}
3
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
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?