仕様
ターミナルからcurlコマンドでjsonデータを送ると,
文字列が成型されて, 同じくjson形式でデータが返ってくる.
環境
Mac OS X 10.12
Docker for Mac 17.03
多分Linuxでも同様にできます.
1. Flask起動スクリプトの用意
Pythonの軽量WebフレームワークであるFlaskをつかって作成します.
@app.route()で指定されたディレクトリにアクセスすると,
defで定義したメソッドが起動し, returnで結果を返す, という流れです.
from flask import Flask, jsonify, request
import json
app = Flask(__name__)
@app.route("/", methods=['GET'])
def hello():
return "Hello World!"
@app.route('/reply', methods=['POST'])
def reply():
data = json.loads(request.data)
answer = "Yes, it is %s!\n" % data["keyword"]
result = {
"Content-Type": "application/json",
"Answer":{"Text": answer}
}
# return answer
return jsonify(result)
if __name__ == "__main__":
app.run(host='0.0.0.0',port=5000,debug=True)
Flaskは, デフォルトではlocalhostからの要求しか受けませんが,
app.runメソッドでhost='0.0.0.0'を渡すと, 全てのアドレスからの要求を受け付けます.
外部公開するときなどは, この設定を行います.
アプリのルートディレクトリ(reply.pyの置いてあるディレクトリ)で
GET要求を受けると, hello()メソッドが実行され, "Hello World!"を返します.
また, /reply ディレクトリでPOST要求を受けjsonデータを受けとると,
reply()メソッドが起動して, データを編集して返します.
2. DockerImageの用意
FlaskをDockerコンテナで動かすために, Pythonの公式イメージを利用します.
DockerFileは以下の通り.
FROM python:3.6
ARG project_dir=/app/
# ADD requirements.txt $project_dir
ADD reply.py $project_dir
WORKDIR $project_dir
RUN pip install flask
# RUN pip install -r requirements.txt
CMD ["python", "reply.py"]
追加で必要なモジュールがあれば, requirements.txtに記述し, ADDで追加します.
最終行のCMDにより, コンテナ起動と同時にアプリが立ち上がるように指定しています.
Dockerfileを用意したら, reply.pyと同じディレクトリに置き, 次のコマンドでビルドします.
# docker build -t flask_docker .
末尾の"."はタイプミスではなく, カレントディレクトリのDockerfileを参照するという合図です.(定番)
3. コンテナの起動
先ほど作成したImageファイル"flask_docker"を元に, コンテナを起動します.
# docker run -p 5000:5000 -it flask_docker
コンテナ内部ではflaskが使用する5000番ポートを解放し, さらにホストマシンの5000番ポートからアクセスできるよう宣言しています.
今回は, コンテナ起動と同時にflaskが起動するように設定しましたが, コンテナの中に入って作業をしたい場合は,
# docker run -p 5000:5000 -it flask_docker /bin/bash
とすれば, Dockerfile最終行のCMDが実行される代わりにbashが起動し, コンテナ内に入ることができます.
4. 動作確認
まずは,ブラウザから"localhost:5000"にアクセスします.
するとhello()メソッドが実行され, "Hello, World!"とブラウザに表示されます.
次に, いよいよJSON形式のデータをPOSTしてみます.
$ curl http://localhost:5000/reply -X POST -H "Content-Type: application/json" -d '{"keyword": "Keffia"}'
読みづらいですが, 以下のような結果が返ってきます.
{
"Answer": {
"Text": "Yes, it is Keffia!"
},
"Content-Type": "application/json"
}
今回はjsonで返しましたが, テキストで返したいときは,
reply()の返り値を"return answer"とすれば良いです.
以上です.