today::エンジニアに憧れる非エンジニア

今のところは、エンジニアとは言えないところの職種です。しかしエンジニア的なものの考え方に興味津津。

Pythonあれこれ 2021-02-20 - Webアプリケーションに、テンプレートに基づいたHTMLを返す動作を実装する

概要

「Head First Python 第2版」を進めていった中で考えたことの記録です。

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

  • 作者:Paul Barry
  • 発売日: 2018/03/24
  • メディア: 単行本(ソフトカバー)

Webアプリケーションのコード

from flask import Flask, render_template, request
from vsearch import search4letters


# ...略...


@app.route('/search4', methods=['POST'])
def do_search() -> str:
  phrase = request.form['phrase']
  letters = request.form['letters']
  return str(search4letters(phrase, letters))

上記は、Flaskを用いて構築した、POSTリクエストを受け付けるWebアプリケーションの例となります。

コード各部分について解説

HTTPのリクエストデータを扱うためのオブジェクトをインポートする

from flask import Flask, render_template, request

flaskライブラリに含まれる関数・クラスのうち、Flaskクラスとrender_template関数は、これまでに実装してきた機能を使うために必要であった関数・クラスです。

今回新たに、requestという組み込みオブジェクトをflaskライブラリからインポートしています。requestオブジェクトは、HTTPのリクエストデータをWebアプリケーションで扱うために必要となる関数です。

HTMLフォームのデータを新規の変数に代入する

phrase = request.form['phrase']
letters = request.form['letters']

flaskライブラリのrequestオブジェクトには、ポストされてきたHTTPリクエストに含まれるHTMLフォームのデータにアクセスするための辞書属性formが含まれます。request.formの内容はPythonの辞書で、各要素のキーはHTMLフォームの各name属性の値となります。例えば、name属性の値がphraseであるinput要素の内容にWebアプリケーション側からアクセスするためには、request.form['phrase']という属性にアクセスすればよいということになるわけです。

<form method='POST' action='/search4'>
<p>このフォームを使って検索リクエストを送ってください。</p>
<table>
<tr><td>フレーズ:</td><td><input name='phrase' type='TEXT' width='60'></td></tr>
<tr><td>文字:</td><td><input name='letters' type='TEXT' value='aeiou'></td></tr>
</table>
<p>準備ができたら、以下のボタンを押してください。</p>
<p><input value='実行!' type='SUBMIT'></p>
</form>

上述HTMLマークアップは、上述Pythonコードで処理するための入力データを生成するHTMLフォームの例です。このHTMLフォームのSUBMIT処理を実行すると、上述Pythonコードは以下の動作を行います。

  • ポストされてきたHTMLフォームのうち、name属性の値がphraseであるinput要素に入力された文字列を変数phraseに代入する
  • ポストされてきたHTMLフォームのうち、name属性の値がlettersであるinput要素に入力された文字列を変数lettersに代入する

curlコマンド等を用い、当該HTMLフォームにより生成されるリクエストと同等のPOSTリクエストを直接投入することも可能です。当該リクエストの必要条件は以下となります。

  • リクエストの種類がPOSTであること
  • HTMLフォーム形式でエンコードされた、以下のパラメータがリクエストに含まれていること
    • phraseパラメータ
    • lettersパラメータ

作成した変数を別の関数で使用し、その戻り値を得る

return str(search4letters(phrase, letters))

このreturn文に対応する関数do_searchは、「/search4というURLを持つリソースに対するPOSTリクエスト」に割り付けられたものです。前項で内容を定義したphraseおよびletters両変数を引数として、search4letters関数を呼び出しています。結果、当該search4letters関数の戻り値は、POSTリクエストの結果としてWebアプリケーションからWebブラウザに返されることとなるわけです。

実際にPOSTリクエストを行ってみる

WindowsでHTTPのPOSTリクエストを直接投げるためには、curl.exeを用いるのが手っ取り早い方法です。

  • Windows 10 Ver.1803以降であれば、curl.exeは標準で付属している
  • cmd.exeやPowerShellといったターミナルから使うことができる
  • -X POSTというオプション指定で、POSTリクエストを投げるようにする
  • HTMLフォーム形式のパラメータをリクエストに含めたい場合は、-F 'パラメータ名=パラメータ値'というオプションを付ける
    • 複数のパラメータをリクエストに含めたい場合は、-Fオプションを必要な数だけ列挙する

事前に対象となるWebアプリケーションを起動した上で、http://127.0.0.1:5000/search4phraseパラメータとlettersパラメータを含むPOSTリクエストを送出するコマンドを送出してみます。実行結果は、例えば以下のようになります。

PS C:\webapp> curl.exe -X POST -F 'phrase=hogehoge' -F 'letters=aeiou' http://127.0.0.1:5000/search4
{'o', 'e'}