- Linux Mint を始めたばかりの人が抑えておくべき5つのこと
- 「mintUpdate」アップデートマネージャー のレベルの意味
- フリーズしたアプリの強制終了の仕方 〜 kill コマンド〜
- CPU と OS が 32 bit なのか 64 bit なのかを確認する「lscpu コマンド」
- メモリー(RAM)の規格・周波数・全容量・空き容量・エラーの有無を調べる
- 自分の Mint のバージョン/コードネーム/Ubuntu のバージョン/コードネームを確認する方法
- Mint Tools を使い倒す
- アプリ/ソフトのアンインストールと更新する方法
- X-Apps について少し知っておこう
- 「'gksu' not found」 廃止された gksu の代わりの方法
- Linux Mint 18 : DVD/Blu-ray リッピングソフト「MakeMKV」
- Mint 19.x: 「K3b」でブルーレイディスクに焼く方法
- Mint 18: 「avconv」でデスクトップの録画も、動画や音楽の変換も行う
- Mint 19.x : 画像・音楽・動画の変換これ一本「Ciano」
- Mint 18.2 : 字幕を同時に二つ表示できる多機能な動画プレイヤー「SMPlayer」
- Mint 18 : CDDB に Freedb を利用している CD リッピングソフト「Asunder」
- Mint 19.x : 音楽ファイルのタグ編集ツール「Kid3」
- Linux Mint 19.x : インストールすべき Rhythmbox プラグイン 9 選
- Linux Mint 18.3 : VirtualBox に無料の Windows を合法的にインストールする方法
- Linux Mint 18: Wine の導入
- Linux Mint 18: Wine で「DVD Shrink」をインストール
- Linux Mint 18: Wine で「DVD Decrypter」をインストール
- Linux Mint 19.x: 5ch専ブラ「Jane Style」は Wine で普通に使える
- Linux Mint 18 : 「winetricks」を使って「Adobe Air」をインストールし「はがきデザインキット」を使う
- Linux Mint 19.x: 画像縮小 Adobe AIR アプリ「縮小専用」を使う
- Linux Mint 18: 「PlayOnLinux」を使い「Amazon Kindle」をインストールする
- Linux Mint 18.3 : ハイレゾ音源対応 Windows ユーザーに人気の「Foobar2000」をインストール & 文字化け対策
- Mint 19.x : 画像ビューア「IrfanView」を簡単にインストールして使う
- Linux Mint 18.3 : Windows アプリを Flatpak 形式でパッケージングするプロジェクト「winepak」
2022.09.19 Monday
2018.04.07 Saturday
Linux Mint 18.3 : Python ではじめるコマンドラインツールの作成とパッケージ化 | 02:32 |
今回、Python でシンプルなコマンドラインツールを作成していくにあたり、pokéapi という、番号でポケモンに関する様々な情報を取得できる REST API を使用します。コマンドラインツールの名前は「pokepy」とし、番号を指定すると、ポケモンの名前、タイプ、特性を返してくれるツールを作成します。タイプや特性の id はその番号のポケモンのタイプと特性を表しているわけではなく、タイプや特性特有の id であることに留意してください。構文は以下のような感じになります:
pokepy (pokemon|type|ability) (--id|-i)=<数字>
サンプルは GitHub にアップロードしています:
ShellingfordX/pokepy: A pokeapi wrapper command line tool
使用するモジュール
コマンドラインツールのオプションをパースするモジュール docopt と HTTP リクエストを送信するためのモジュール requests を使います。コマンドのオプションをパースするモジュールには argparse もありますが、大きな違いは argparse が使用するコマンドのオプションを定義するとヘルプが自動生成されるのに対して、docopt はヘルプを書くことによってコマンドのオプションを自動生成してくれる点です。
もし、argparse で pokepy の引数・オプションを解析しようとすると以下のようになります:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import argparse
parser = argparse.ArgumentParser(description='A simple command line tool that shows pokemon info', version='0.1.0') #パーサーオプジェクトを作成します
parser.add_argument('uri', help='Specify pokemon, type or ability') #位置引数
parser.add_argument('-i','--id', type=int, nargs=1, default=1, help='Specify a pokemon number') #オプション引数
args = parser.parse_args() #引数・オプションを解析します
print "番号:",args.id,"¥n","pokemon? type? ability?:",args.uri #表示しています
実行例:
./pokepy.py pokemon --id 25
実行結果:
番号: [25]
pokemon? type? ability?: pokemon
少し説明を加えると、位置引数はハイフンがつかない、必須の引数のことです。これを要求するためにこのコードを書いています:
parser.add_argument('uri', help='Specify pokemon, type or ability') #位置引数
同時に、help='Specify pokemon, type or ability' と書くことで、./pokepy.py -h を実行した時のヘルプに表示するようにしています:
positional arguments:
uri Specify pokemon, type or ability
同様にオプション引数も指定しています。ロング形式の --id とショート形式の -i どちらでも使えるようにし、type=int で受け取る値を数値として読み込み、nargs=1 で渡せる値は 1 つ、default=1 で id の指定がなかった場合に代入される値を指定、最後にヘルプに表示するテキストを指定しています。これはこれで便利ですが、今回はヘルプを書いて、引数を自動生成してくれる docopt を使います:
sudo apt install -y python-docopt
また、python-pip もインストールしておきましょう。今回はコマンドラインツールを作成するだけでなく、作成するスクリプトは pip でインストールするからです:
sudo apt install -y python-pip更に、パッケージ化に setuptools モジュールも使います:
sudo apt install -y python-setuptools
ファイル構成
このプロジェクトに必要な最小構成は次のとおりです:
pokepy/
├── pokepy
│ ├── __init__.py
└── setup.py
ですが、README.rst と MANIFEST.in も追加します:
pokepy/
├── pokepy
│ ├── __init__.py
├── setup.py
├── README.rst
└── MANIFEST.in
これからそれぞれのファイルについて述べていきます。
pokepy/__init__.py
pokepy の機能を実装しているスクリプトです。__init__.py はパッケージ化するにあたり必要なファイルで、import して読み込みたいモジュールがある場合、ディレクトリに含める必要が有ります。初期化のコードを書くか空っぽのままで、機能は別のファイルとして分離するようですが最小構成ということでこのなかに書いてしまいます:
'''
Usage:
pokepy (pokemon | type | ability) --id=ID
Options:
-i --id=ID # specify the id of the pokemon, type or ability
-h --help # Show this help
'''
import requests
POKEAPI = 'https://pokeapi.co/api/v2/{path}/{id}'
def get_api_path(arguments):
'''
Get pokemon or type or ability command from command line
arguments.
'''
paths = ['pokemon', 'type', 'ability']
for path in paths:
if arguments[path]:
break
return path
def get_id(arguments):
'''
Get id from command line arguments.
'''
return arguments['--id']
def call_pokeapi(path, id_number, key='name'):
'''
Call the RESTful PokeAPI and parse the response. If pokemon, ability or
type ids are not found than the error message detail is returned.
'''
url = POKEAPI.format(path=path, id=id_number)
response = requests.get(url)
response_json = response.json()
try:
res = response_json[key]
except:
res = response_json['detail']
return res
def __main__():
'''
Entrypoint of command line interface.
'''
from docopt import docopt
arguments = docopt(__doc__, version='0.1.0')
path = get_api_path(arguments)
id_number = get_id(arguments)
print(call_pokeapi(path, id_number))
docopt
このファイルにはコマンドラインツールのエントリーポイント(プログラムの開始となる位置)を含んでいます。後述する setup.py で __main__ 関数がエントリーポイントとなるよう指定します。端末から実行するとき __main__ 関数が実行されるわけです。最初から数行は docopt を使うために、ドキュメントストリングを記述しています。利用者がこの使用法に従わなかった場合、このドキュメントストリングがヘルプとして表示されます。__main__ 関数内の
from docopt import docoptで docopt モジュールを読み込み、
arguments = docopt(__doc__, version='0.1.0')としてあげることで、端末から入力された引数を参照することができます。この時、「version=数字」も指定してあげることで --version を指定した時に、指定したバージョン(ここでは 0.1.0)が返されます。docopt は内部で sys.argv を使って引数を読み取り、パースしています。パースされた引数は辞書オブジェクトとして返します。なので以下のように値を取り出すことが出来ます:
arguments = docopt(__doc__, version='0.1.0')
arguments['--id']
requests
3つのユーザー定義関数を定義しています。引数から pokemon か type か ability を得る関数(get_api_path)、引数から id を取得する関数(get_id)、GET リクエスト送り JSON データを取得し必要な情報を返す関数(call_pokeapi)の3つです。
response = requests.get(url)で GET リクエストを行い、Requests オブジェクトに対して json() メソッドを使うことで JSON 形式のレスポンスの内容を辞書として扱うことが出来ます:
response = requests.get("https://pokeapi.co/api/v2/pokemon/150/")
response_json = response.json()
print response_json['name']
出力例:
mewtwo
もし、クエリ文字を追加したい場合は以下のようにし params キーワードを使って辞書として引数を渡すことが出来ます:
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get("http://example.org/get", params=payload)
print r.url
出力例:
http://example.org/get?key2=value2&key1=value1
setup.py
パッケージ化(配布可能に)するのに必要なスクリプトです:
from setuptools import setup, find_packages
from codecs import open
from os import path
here = path.abspath(path.dirname(__file__))
# Get the long description from the README file
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
long_description = f.read()
setup(
name='pokepy',
version='0.1.0',
description='A Pokeapi wrapper command line tool',
long_description=long_description,
url='https://github.com/ShellingfordX/pokepy',
author='Shellingford',
author_email='example@gmail.com',
license='Apache 2.0',
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Topic :: Software Development :: Build Tools',
'License :: OSI Approved :: Apache License',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.5',
],
keywords='Pokeapi REST client wrapper command line interface',
packages=find_packages(),
install_requires=['docopt', 'requests'],
extras_require={ },
package_data={},
data_files=[],
entry_points={
'console_scripts': [
'pokepy=pokepy:__main__',
],
},
)
ちゃんと動作させる上で大事なのは:
install_requires=['docopt', 'requests'],と
entry_points={です。
'console_scripts': [
'pokepy=pokepy:__main__',
]
pip でインストールする必要がある依存関係は install_requires に指定します。エントリーポイント(プログラムの開始点)としてを指定するには、辞書の console_scripts の値として指定します。上の意味は「端末から pokepy を実行したならば、pokepy モジュールの __main__ 関数を呼び出せ」です。classifiers 引数に指定する値は ここ から選びます。
README.md -> README.rst
README.md は GitHub で管理していれば自動生成してくれます。setup.py では long_description の中身に README ファイルを流用していますが、読み込んでいるファイル形式は README.rst です。PyPL が md (マークダウン) 形式には対応していないため、一般的には rst (reStructuredText) 形式を使うのが普通なようです。そこで、md 形式から rst 形式に変換する必要が有ります。変換するには pandoc を使うのが便利です:
sudo apt install -y pandoc
ワーキングディレクトリを README.md がある場所に移し、以下を実行すれば README.md から README.rst を作成することが出来ます:
pandoc -f markdown -t rst -o README.rst README.md
また、Python ファイルでないもので、インストールに含めたいものは MANIFEST.in に指定する必要が有ります:
include README.rst
インストール & 試用
pokepy ディレクトリ内に入り、pip でインストールします。-e は --editable のショート形式で、開発中はソースを編集したい時もあるので、再インストールする必要なく編集できるようにするためのオプションです:
cd pokepy && sudo pip install -e .
Successfully installed pokepyと返されたらインストール成功です。
試しに図鑑番号 25 のポケモンの名前を表示してみます:
pokepy pokemon -i 25
出力例:
pikachu
以上で Python で端末で動く API ラッパーを作成する方法を習得しました。このモジュールをテンプレートにして、より便利でより複雑なツールを作ってはいかがでしょうか。
参考元: Datahovel
| プログラミング |
2022.09.19 Monday
Show some apps list:
Follow on your feed reader:
About this blog:
Linux Mint-centric chronicle with anime girls since 2009.Best View with Google Chrome 1980x1080 dimension.Info 更新は不定期です。
- Mint 18.3 : オススメ Python IDE 8 選
- Mint 18.3 : Python ではじめるコマンドラインツールの作成とパッケージ化
- Linux ユーザーなら Git を活用しよう
- Shell :シェルスクリプトを組もう! Zenity 編
- Shell :シェルスクリプトを組もう! Dialog 編