Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
88
Help us understand the problem. What is going on with this article?
@nskydiving

はじめての Responder(Python の次世代 Web フレームワーク)

More than 1 year has passed since last update.

この記事は Python のモダンな Web フレームワークである「Responder」の入門チュートリアルです。

公式のチュートリアル「Quick Start!」に沿って進めていきます。

この記事のサンプルコードは GitHub で公開していますので、参考にしてください。
https://github.com/nskydiving/responder_quick_start

Responder とは

ResponderRequestsPipenv の開発者として知られる Kenneth Reitz 氏 によって開発された Web フレームワークです。

Responder のコンセプトは、人気の Web フレームワークである FlaskFalcon の両方から良い部分を取り入れ、さらに Kenneth Reitz 氏の持つ新しいアイデアを加えることで、新しい一つのWeb フレームワークに統合することです。

さらに詳しい情報を知りたい方は、以下のブログを参考にしてください。

人間のためのイケてるPython WebFramework「responder」、そして作者のKenneth Reitzについて
https://blog.ikedaosushi.com/entry/2018/12/01/195512

Responder の特徴

  • 単一のインポート文で使える API
  • 継承のないクラスベースのビュー
  • ASGI
  • 他の ASGI / WSGI アプリケーションをマウント可能
  • f-strings 構文によるルート宣言
  • 変更可能なレスポンスオブジェクトがビューに渡されます。何も return する必要はありません。
  • ThreadPoolExecutor によるバックグラウンドタスク
  • GraphiQL による GraphQL
  • OpenAPI スキーマの生成
  • SPA(シングルページアプリケーション)

動作環境

  • Mac OS X 10.12.6
  • Pipenv 2018.11.26
  • Python 3.6.7
  • Responder 1.1.2

環境構築

Mac のターミナルを開いて、必要なソフトウェアをインストールします。

Pipenv のインストール

最初に Pipenv をインストールします。
Pipenv は Python の仮想環境を構築するためのツールです。

$ brew install pipenv

Python のインストール

適当な作業ディレクトリを作成し、Python 環境を構築します。
Python はバージョン 3.6.0 以上が必須となるので注意してください。

$ mkdir work
$ cd work
$ pipenv install --python 3.6.7

Responder のインストール

最後に Responder をインストールします。

$ pipenv install responder --pre

Hello World!

準備が整ったら、お決まりの「Hello World!」を書いてみましょう!

「hello_world.py」という名前でファイルを作成し、以下のコードを記述してください。

hello_world.py
import responder

api = responder.API()

@api.route("/")
def hello_world(req, resp):
    resp.text = "hello, world!"

if __name__ == '__main__':
    api.run()

このコードを実行します。

$ python hello_world.py

うまくいけば Responder アプリケーションが起動し、以下のようなメッセージが表示されます。

INFO: Started server process [50733]
INFO: Waiting for application startup.
INFO: Uvicorn running on http://127.0.0.1:5042 (Press CTRL+C to quit)

ブラウザを開いて、以下の URL にアクセスしてみましょう。
http://127.0.0.1:5042/

「hello, world!」という文字列が表示されれば成功です!

※「ModuleNotFoundError: No module named 'starlette.lifespan'」エラーが出る場合は?
この問題を回避するために、以下のコマンドを実行してください。

$ pipenv install starlette==0.8

この問題の詳細は GitHub の issues を参照してください。
https://github.com/kennethreitz/responder/issues/255

引数を受け取る

以下のコードを記述して、Responder アプリケーションを起動してください。

accept_route_arguments.py
import responder

api = responder.API()

@api.route("/hello/{who}")
def hello_to(req, resp, *, who):
    resp.text = f"hello, {who}!"

if __name__ == '__main__':
    api.run()

ブラウザを開いて、以下の URL にアクセスしてみましょう。
http://127.0.0.1:5042/hello/brettcannon

引数「brettcannon」が Responder アプリケーションへ渡され、「hello, brettcannon!」と表示されます。

JSON / YAML を返す

以下のコードを記述して、Responder アプリケーションを起動してください。

returning_json_yaml.py
import responder

api = responder.API()

@api.route("/hello/{who}/json")
def hello_to(req, resp, *, who):
    resp.media = {"hello": who}

if __name__ == '__main__':
    api.run()

ブラウザを開いて、以下の URL にアクセスしてみましょう。
http://127.0.0.1:5042/hello/guido/json

JSON 形式のデータ「{"hello": "guido"}」がブラウザに表示されます。

テンプレートを描画する

以下のコードを記述してください。

rendering_a_template.py
import responder

api = responder.API()

@api.route("/hello/{who}/html")
def hello_html(req, resp, *, who):
    resp.content = api.template('hello.html', who=who)

if __name__ == '__main__':
    api.run()

次にサブディレクトリ「template」の配下にテンプレートファイル「hello.html」を作成し、以下のコードを記述してください。

templates/hello.html
Hello, {{ who }}

「rendering_a_template.py」と「templates/hello.html」が作成できたら、Responder アプリケーションを起動してください。

ブラウザを開いて、以下の URL にアクセスしてみましょう。
http://127.0.0.1:5042/hello/guido/html

テンプレートファイル「templates/hello.html」に名前「guido」が渡され、「Hello, guido」と表示されます。

Responder では、テンプレートエンジン「Jinja2」が使えます。

Responder は Jinja2 を内包しているので、インストールどころかインポートすら必要ありません。

レスポンスのステータスコードを設定する

以下のコードを記述して、Responder アプリケーションを起動してください。

setting_response_status_code.py
import responder

api = responder.API()

@api.route("/416")
def teapot(req, resp)
    resp.status_code = api.status_codes.HTTP_416   # ...or 416

if __name__ == '__main__':
    api.run()

ブラウザを開いて、以下の URL にアクセスしてみましょう。
http://127.0.0.1:5042/416

ステータスコード「416」が返されます。
ステータスコードは Chrome のデベロッパーツール「Network > Status」で確認することができます。

レスポンスのヘッダ情報を設定する

以下のコードを記述して、Responder アプリケーションを起動してください。

setting_response_headers.py
import responder

api = responder.API()

@api.route("/pizza")
def pizza_pizza(req, resp):
    resp.headers['X-Pizza'] = '42'

if __name__ == '__main__':
    api.run()

ブラウザを開いて、以下の URL にアクセスしてみましょう。
http://127.0.0.1:5042/pizza

ヘッダ情報「X-Pizza」に「42」が設定されます。
ヘッダ情報は Chrome のデベロッパーツール「Network > Name(pizza)」をクリックして確認することができます。

データの受け取りとバックグラウンドタスク

以下のコードを記述して、Responder アプリケーションを起動してください。

setting_response_headers.py
import responder
import time

api = responder.API()

@api.route("/incoming")
async def receive_incoming(req, resp):

    @api.background.task
    def process_data(data):
        """Just sleeps for three seconds, as a demo."""
        time.sleep(3)


    # Parse the incoming data as form-encoded.
    # Note: 'json' and 'yaml' formats are also automatically supported.
    data = await req.media()

    # Process the data (in the background).
    process_data(data)

    # Immediately respond that upload was successful.
    resp.media = {'success': True}

if __name__ == '__main__':
    api.run()

curl を使って Responder アプリケーションへ JSON データを送信します。

$ curl http://127.0.0.1:5042/incoming -X POST -H "Content-Type: application/json" -d '{"key": "value"}'

Responder アプリケーションは、データの受け取り処理で 3 秒のスリープを行なっていますが、この処理はバックグラウンドで処理されるため、即座にレスポンス「{'success': true}」が返されます。

さいごに

Responder は 2018 年 10 月に公開されたばかりの新しい Web フレームワークですが、GitHub のスターはすでに 2000 を超えています。

Responder がここまで支持されている理由として、モダンな機能を搭載し、Flask の進化版のような立ち位置にあること、さらに有名モジュールの作者によって開発されていることが大きいように思います。

まだ少しさわった程度ですが、将来有望な Web フレームワークであると感じています。

Responder のことをもっと知りたいという方は、Responder の公式サイト を読んでください。

88
Help us understand the problem. What is going on with this article?
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.
Sign Up
If you already have a Qiita account Login
88
Help us understand the problem. What is going on with this article?