【Sansan Advent Calendar 2017 1日目の記事です。】
Pythonで、WebAPIやコマンドラインツールを作ったりするときに、ボトルネックになりがちなのが、ルーティングや引数の管理です。 hugは、ここらへんをよしなにやってくれるPythonモジュールです。
hugを使った、WebAPIやコマンドラインツールの作成について備忘録として記します。
もう少しhugについて知ってみる
hugの公式サイトでは、なんともかわいらしいコアラが出迎えてくれます。
一言で言うと、デコレータでメソッドをラップすることで、メソッド単位でシンプルにAPIを構築できるモジュールです。 公式サイトでも挙げられている特徴をまとめると、
- デコレータでラップ(例:
@hug.get())するだけで、APIのエンドポイントとなります - 裏側はfalconが動いているため、動作は高速です
- APIのバージョンが簡単に切れます(例:
@hug.get('/', versions=1)) - APIドキュメントをコードから作成してくれます
- 引数のバリデーションは、型を指定するだけで可能です(例:
def test_method(name: hug.types.text)) - コマンドラインインターフェイスとしても利用できます
インストールは、いつものpipで pip install hugで完了です。
Python 3.3以降が要件ですので、2系のかたは注意してください。
WebAPIを作ってみる
おきまりのHello World!
# hello_world.py import hug @hug.get("/") def hello_world(): return "Hello World!"
hugには検証用にlocalhostにhttpサーバーを立ててくれる機能があります。
$ hug -f hello_world.pyと入力して、実際にAPIが動作しているか確認します。

これだけで、APIが作成できていることが確認できました。
パラメータを渡す
GETリクエストのパラメータを受け取ります。 特徴で挙げたように、hugには引数の型を指定してバリデーションをしてくれる機能があります。
先ほどのHello Worldに変更を加えてみます。
# hello_world_2.py import hug @hug.get("/") def hello_world(name: hug.types.text): return {"message": "Hello World {0}!".format(name)}
ルートにリクエストすると、nameという名前のテキスト型のパラメータを取得するメソッドとなります。
試しにアクセスしてみると、Hello World name !が返ってきます。

ここで、パラメータが足りないとどうなるでしょうか? パラメータが足りないと、返ってきます。

デコレータでラップして、引数に型を指定するだけで、いとも簡単にAPIが作れる素晴らしいモジュールです。
他にも、独自の型を作れたり、デフォルト引数を与えたりと多機能です。
デプロイするときは
WSGIに対応しているため、Apache+mod_wsgiやnginx+uwsgiで簡単に公開できます。
具体的には、__hug_wsgi__というインターフェースが用意されているため、これを起動します。
Flaskやbottleだと、app = __hug_wsgi__を最終行に追加すれば動きますし、
uwsgiだと、--callable __hug_wsgi__をオプションに加え、gunicornも___hug_wsgi__を呼んであげれば動きます。
コマンドラインツールを作ってみる
サンプルですが、以下のコードとなります。
# coding:utf-8 import hug @hug.cli() def hello_world(name: hug.types.text): return {"message": "Hello World {0}!".format(name)} if __name__ == "__main__": hello_world.interface.cli()
以下の2つの処理を追記することでコマンドラインツールとなります。
- 対象のメソッドを@hug.cli()というデコレータでラップすること
- Pythonスクリプトを直接実行(__name__ == "__main__")した際に、メソッド名.interface.cli()を呼ぶ
あとは、python ファイル名 引数で実行することで、コマンドラインツールとして動作します。
引数が必要な場合に、引数が入力されていないと、エラーとなります。
$ python hello_world_cli.py usage: hello_world_cli.py [-h] name hello_world_cli.py: error: the following arguments are required: name $ python hello_world_cli.py Taro {'message': 'Hello World Taro!'}
内部ではargparseが使われているようで、意外とargparseを記述するのは大変なのでhugは便利かもしれません。
(いろいろなモジュールに依存するようになりますが)
まとめ
爆速かつ完結にAPIやCLIを作るPythonモジュールのhugについて書きました。
デコレータでラップするだけで、Web APIやCLIを作れる便利なモジュールです。
CLI作るときは、argparseもいいですが、hugを積極的に使っていこうと思いました。