Help us understand the problem. What is going on with this article?

DockerコンテナでFlaskを起動し, JSONデータのPOSTとGET

More than 1 year has passed since last update.

仕様

ターミナルからcurlコマンドでjsonデータを送ると,
文字列が成型されて, 同じくjson形式でデータが返ってくる.

環境

Mac OS X 10.12
Docker for Mac 17.03
多分Linuxでも同様にできます.


1. Flask起動スクリプトの用意

Pythonの軽量WebフレームワークであるFlaskをつかって作成します.
@app.route()で指定されたディレクトリにアクセスすると,
defで定義したメソッドが起動し, returnで結果を返す, という流れです.

reply.py
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は以下の通り.

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"とすれば良いです.

以上です.

paperlefthand
Automobile, Linux and Mathematics
https://paperlefthand.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした