hugでAPIやCLIを作る
【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を積極的に使っていこうと思いました。