らくがきちょう

なんとなく ~所属組織/団体とは無関係であり、個人の見解です~

Python の responder を使った AJAX サンプル

responderPython の Web フレームワークです。 responder でシンプルな AJAX を書いたのでメモしておきます。 サンプルは以下の 2 つです。

  1. テキストを入力してボタンを押すとタイトルを書き換えるサンプル
  2. テキストを入力するとタイトルが書き換わるサンプル

ディレクトリ構成

ディレクトリ構成は以下の通りです。

├── app.py
├── static
│   └── js
│       └── sample.js
└── templates
    └── index.html

サンプル 1 ~ボタンを押したらタイトルを書き換える~

app.py

import responder

api = responder.API()

@api.route("/")
class hello():
    def on_get(self, req, resp):
        resp.content = api.template('index.html')

    async def on_post(self, req, resp):
        data = await req.media()
        resp.media = {'ResultSet': '{"result": "' + data['text'] + '"}'}

if __name__ == '__main__':
    api.run(address='0.0.0.0', port=5042, debug=True)

static/js/sample.js

$(function () {
  $("#button").click(function () {
    var textData = JSON.stringify({ "text": $("#input_text").val() });
    $.ajax({
      type: 'POST',
      url: '/',
      data: textData,
      contentType: 'application/json',
      success: function (data) {
        var result = JSON.parse(data.ResultSet).result;
        $("#resulttext").text(result);
      }
    });
    return false;
  });
});

templates/index.html

<!DOCTYPE html>
<html lang="ja">

<head>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <meta charset="UTF-8">
    <title>Responder Ajax Sample</title>
</head>

<body>
    <div class="container">
        <div class="container-fluid">
            <div class="row">
                <div class="col-sm-12">
                    <h1 class="text-center" id="resulttext">Responder Ajax Sample</h1>
                    <input type="text" class="form-control" id="input_text" placeholder="Please input text">
                    <button class="btn btn-primary" id="button">Change title.</button>
                </div>
            </div>
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"
        integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.bundle.min.js"
        integrity="sha384-6khuMg9gaYr5AxOqhkVIODVIvm9ynTT5J4V1cfthmT+emCG6yVmEZsRHdxlotUnm"
        crossorigin="anonymous"></script>
    <script src="../static/js/sample.js"></script>
</body>

</html>

実行結果

ファイルが用意出来たらアプリケーションを開始します。

# python app.py
INFO:     Started server process [1302]
INFO:     Uvicorn running on http://0.0.0.0:5042 (Press CTRL+C to quit)
INFO:     Waiting for application startup.
INFO:     Application startup complete.

ブラウザでアクセスすると以下のような画面になるはずです。

f:id:sig9:20200126014116p:plain

テキストボックスに文字列を入力し、ボタンを押すと ページ上部の文字列が書き換わります。

f:id:sig9:20200126014557p:plain

サンプル 2 ~テキストを入力したらタイトルを書き換える~

app.py

import responder

api = responder.API()

@api.route("/")
class hello():
    def on_get(self, req, resp):
        resp.content = api.template('index.html')

    async def on_post(self, req, resp):
        data = await req.media()
        resp.media = {'ResultSet': '{"result": "' + data['text'] + '"}'}

if __name__ == '__main__':
    api.run(address='0.0.0.0', port=5042, debug=True)

static/js/sample.js

$(function () {
  var $input_text = $('#input_text');

  function send() {
    var textData = JSON.stringify({ "text": $("#input_text").val() });
    $.ajax({
      type: 'POST',
      url: '/',
      data: textData,
      contentType: 'application/json',
      success: function (data) {
        var result = JSON.parse(data.ResultSet).result;
        $("#resulttext").text(result);
      }
    });
  };

  var send_timeout_id = null
  $input_text.on('keyup', function () {
    if (send_timeout_id) {
      clearTimeout(send_timeout_id);
    }
    send_timeout_id = setTimeout(send, 500);
  });
});

templates/index.html

<!DOCTYPE html>
<html lang="ja">

<head>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <meta charset="UTF-8">
    <title>Responder Ajax Sample</title>
</head>

<body>
    <div class="container">
        <div class="container-fluid">
            <div class="row">
                <div class="col-sm-12">
                    <h1 class="text-center" id="resulttext">Responder Ajax Sample</h1>
                    <input type="text" class="form-control" id="input_text" placeholder="Please input text">
                </div>
            </div>
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"
        integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.bundle.min.js"
        integrity="sha384-6khuMg9gaYr5AxOqhkVIODVIvm9ynTT5J4V1cfthmT+emCG6yVmEZsRHdxlotUnm"
        crossorigin="anonymous"></script>
    <script src="../static/js/sample.js"></script>
</body>

</html>

実行結果

アプリケーションを開始すると以下のように表示されます。 このサンプルではボタンが表示されません。

f:id:sig9:20200126015432p:plain

テキストを入力して 500 ミリ秒経過するとタイトルが書き換わります。 「ボタンを押す」「エンターキーを押す」といったアクションは不要です。

f:id:sig9:20200126015436p:plain