引数・返り値とテンプレートによるAPIへの機能追加|Flaskで作る簡易APIサーバー #2

f:id:lib-arts:20191017182256p:plain

Flaskに関する情報をまとめていきます。FlaskはHTTPアクセスが可能な簡易的なAPIを作成する、Pythonベースのフレームワークです。

Flaskへ ようこそ — Flask v0.5.1 documentation

基本的には上記などのドキュメントを元にした動作確認や、簡単に内容をカスタマイズして実行してみるなどを行なっていければと思います。
#1ではFlaskの概要と簡単な動作確認について行いました。

Flaskの概要と簡単な動作確認|Flaskで作る簡易APIサーバー #1 - lib-arts’s diary

#2では引数・返り値やレンダリングテンプレートなど、よりリッチなAPIを作成するにあたって確認していければと思います。
以下目次となります。
1. 引数・返り値(HTTPとGETとPOST)
2. レンダリングテンプレート
3. まとめ

 

1. 引数・返り値(HTTPとGETとPOST)
1節では引数と返り値について取り扱います。

f:id:lib-arts:20191017212054p:plain

#1では上記のコードを実行しましたが、返り値については上記においてはreturnによって返される"Hello World!"となっているので一旦そこまで気にしなくて良いかと思います。2節ではこの返り値をリッチにするにあたって、テンプレートをご紹介します。
一方、引数については、アクセス時に渡すので、HTTPの仕様を考慮するとGETまたはPOSTで送信すると考えておくと良いです。先に簡単にHTTPとGET、POSTの概要について確認しておきます。

f:id:lib-arts:20191021202406p:plain

Hypertext Transfer Protocol - Wikipedia
まずはHTTPについて確認します。上記はWikipediaの概要の記述ですが、HTTPは"Hypertext Transfer Protocol"の略で、HTMLなどのコンテンツの送受信(リクエストに対しレスポンスを返す)に用いられる通信プロトコルとされています。このHTMLをブラウザで表示することにより、Webサービスを利用することができるのですが、返り値としてHTMLを生成するところについては2節のテンプレートのところでこちらは確認します。さて、ここで気になるのは引数(ここではリクエストに付随すると考えれば十分です)ですが、メソッドについて確認します。

f:id:lib-arts:20191021203034p:plain

メソッドについては上記のように記載されています。HTTPには8つのメソッドが定義されているとされていますが、概ねGETとPOSTのみ抑えておけば十分だと思われます。

127.0.0.1 - - [xx/Oct/2019 xx:xx:xx] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [xx/Oct/2019 xx:xx:xx] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [xx/Oct/2019 xx:xx:xx] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [xx/Oct/2019 xx:xx:xx] "GET / HTTP/1.1" 200 -

サンプルコードを元に立ち上げたサーバ側にブラウザから"http://127.0.0.1:5000/"に対してアクセス(ここでは4回アクセスしています)すると、サーバ側では上記のような出力がされます。この際に"GET / HTTP/1.1"とありますが、このGETがGETメソッドであることを表しています。
ここまでがHTTP、GET、POSTの大枠の話ですが、ここからはパラメータを引数としてどのように渡すかを見て行きます。今回はなるべく話を簡易化するにあたって、GETについて見ていきます。

@app.route("/sample_res")
def sample_res():
    text = request.args.get("msg", "Not defined")
    return text

具体的にはhello.pyに上記を書き加えて、下記のようにして保存します。

f:id:lib-arts:20191021205349p:plain

上記を"$ python hello.py"で実行し、ブラウザから"http://127.0.0.1:5000/sample_res?msg=Hello"にアクセスします。こうするとブラウザ上では下記のようにHelloが表示されます。

f:id:lib-arts:20191021205422p:plain

ここで、msgが引数のような役割を果たしています。したがってブラウザから"http://127.0.0.1:5000/sample_res?msg=Hi"のようにmsgに渡す値を変えてアクセスすると下記のように違う結果を得ることができます。

f:id:lib-arts:20191021205439p:plain

このように、引数と返り値のような機能をAPIに加えることができました。
意図していた内容について一通り確認できたので、1節はここまでとします。


2. レンダリングテンプレート
2節では1節における返り値にあたるサーバのレスポンスについて見ていくにあたり、テンプレートのレンダリングを確認していきます。サーバのレスポンスの中核をなすのがHTMLファイルなのですが、返り値にHTMLファイルの情報を持たせるにあたって、情報が冗長化してしまいます。これを防ぐために、多くのWebアプリケーションのフレームワークではテンプレートという考え方が備わっています。

f:id:lib-arts:20191021210039p:plain

クイックスタート — Flask v0.5.1 documentation

以下上記を確認していきます。

f:id:lib-arts:20191021210957p:plain

まず上記のコードをhello.pyに追加し、下記のようなファイルにします。

f:id:lib-arts:20191021211017p:plain

この際に、helloについてはrender_template関数を用いて"hello.html"を指定していることに着目すると良いです。このrender_template関数についてはデフォルトの設定では"templates"ディレクトリを参照するようなので、下記のようなパスで"hello.html"ファイルを作成します。

f:id:lib-arts:20191021211548p:plain
ファイルに関しては、参考ページのコードをコピーし、下記のようにします。

f:id:lib-arts:20191021211605p:plain

ここまでの準備がすんだら、これまでと同様に"$ python hello.py"でアプリを起動し、ブラウザに"http://127.0.0.1:5000/hello/"でアクセスすると下記のようになります。

f:id:lib-arts:20191021211721p:plain

"Hello World!"の表示のされ方が変わっていることが確認できます。以下ソース(HTMLファイルのコンテンツ)の確認も行ってみます。

f:id:lib-arts:20191021211706p:plain

上記のようにHTMLの形式でファイルが転送されていることが確認できます。このようにテンプレートをレンダリングするように実装することで、アプリの起動部分の記述を減らすことができます。
テンプレートのレンダリングにあたっての基本的な内容について概ね確認できたので、2節はここまでとします。


3. まとめ
#2ではAPIをよりリッチにするために、GETを用いたパラメータの受け渡しやテンプレートを用いたレスポンスのリッチ化を行いました。多くのフルスタックのWebフレームワークとは異なり、Flaskは最低限の機能しか実装されていないため、ここまでまとめたサーバの起動やテンプレートがメインとなっています。
近年ではJavaScript系のフレームワークが主流なので、JavaScript系のバックエンドとして見た際にはフルスタックフレームワークよりも軽量フレームワークが便利なのではと思います。また、モバイルアプリの通信にあたっても軽量フレームワークは便利です。さらに、機械学習においてはPythonが中心となっているため、PythonベースのFlaskが簡易APIの作成にあたって検討にあがるケースは多いのではと思われます。
#3以降では、より高度な機能について見ていけたらと思います。