テクノロジー 開発 非公開: Python の非同期 Web フレームワーク トップ 9

Python の非同期 Web フレームワーク トップ 9

非同期プログラミングは、現在 Python の第一級市民です。 Web 開発者であれば、選択できる素晴らしいフレームワークがあります。

この記事の執筆時点では、非同期は Python コミュニティにおける単なる流行語ではありません。バージョン 3.5 の asyncio ライブラリのリリースにより、Python は Web 開発に対する Node.js の影響を認識し、言語に 2 つの新しいキーワード async await を導入しました。

Python 言語は緊急の必要がない限りコア構文の拡張に非常に慎重であるため、これは非常 大きな問題でした。これは、Python 開発者が非同期機能をいかに根本的に重要であると考えていたかを示しているだけです。

その結果、非同期プログラミングの水門が開かれました。新旧のライブラリがコルーチン機能を利用し始め、非同期フレームワークの人気が爆発的に高まり、現在でも新しいものが作成され続けています。

Node.js と同等かそれ以上のパフォーマンスは前例のないことではなく、読み込みパターンに CPU を大量に使用するタスクが含まれていない限り、1 秒あたり数千のリクエストを実行できない理由はありません。

でもモチベーションは十分!

現在の Python の状況を調査し、主要な非同期フレームワークをいくつかチェックしてみましょう。

Python の非同期 Web フレームワーク トップ 9
Python の非同期 Web フレームワーク トップ 9

竜巻

驚くべきことに、 Tornado は まったく新しいフレームワークではありません。最初のリリースは 2009 年で、それ以来、高い同時実行性を備えた堅牢な非同期プログラミングを提供することに重点が置かれてきました。

Tornado は基本的に Web フレームワークではありません。これは非同期モジュールのコレクションであり、Web フレームワーク モジュールの構築にも使用されます。より具体的には、これらのモジュールは次のとおりです。

  • コルーチンとその他のプリミティブ ( tornado.gen tornado.locks tornado.queues など)
  • ネットワーク モジュール ( tornado.ioloop tornado.iostream など)
  • 非同期サーバーとクライアント ( tornado.httpserver tornado.httpclient など)

これらは結合されて、最終的なフレームワーク モジュール ( tornado.web tornado.routing tornado.template など) を生成します。

 import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Tornado は Python コミュニティに強力で献身的な支持者がおり、経験豊富なアーキテクトによって高度な機能を備えたシステムを構築するために使用されています。これは、長い間並行性の問題に対する答えを持っていたフレームワークですが、WSGI 標準をサポートしておらず、賛同が大きすぎたため、おそらく主流にはならなかったでしょう (Python ライブラリの大部分は依然として同期であることを思い出してください) )。

Python の非同期 Web フレームワーク トップ 9
Python の非同期 Web フレームワーク トップ 9

サニック

Sanic は、言葉の本当の意味で「最新の」フレームワークです。Python バージョン 3.6 未満はサポートせず、すぐに使用できるシンプルで汎用的な async/await 構文をサポートします。その結果、読みにくくなります。最初の HTTP ハンドラーを作成する前に、大量のドキュメントを参照し、エッジ ケースを念頭に置いてください。

その結果、(少なくとも私の意見では) 非常に快適な構文が得られます。これは、他のマイクロフレームワーク (Flask、CherryPy など) で作成するコードに似ていますが、いくつかの async が散りばめられています。

 from sanic import Sanic
from sanic.response import json

app = Sanic()

@app.route("/")
async def test(request):
    return json({"hello": "world"})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

Sanic はおそらく、Python の世界で最も人気があり、最も愛されている非同期フレームワークです。ルーティング、ミドルウェア、Cookie、バージョン管理、ブループリント、クラスベースのビュー、静的ファイル、ストリーミング、ソケットなど、プロジェクトに必要なほぼすべての機能と、そのままでは提供されない機能が備わっています。 — テンプレート、データベース サポート、ファイル I/O、キュー — は、現時点ではこれらに十分な量の非同期ライブラリがあるため、追加できます。

Python の非同期 Web フレームワーク トップ 9
Python の非同期 Web フレームワーク トップ 9

ビボラ

Vibora は Sanic のいとこに近いものですが、最速の Python Web サーバーになることにこだわっている点が異なります。実際、Web サイトに最初にアクセスすると、フレームワークの比較が表示されます。

ご覧のとおり、Vibora は従来のフレームワークよりも数倍高速であり、最も近い競合他社である Sanic よりも 2 倍以上高速であると主張しています。もちろん、ベンチマークは割り引いて判断する必要があります。 🙂

Vibora は構文と機能の点では Sanic に匹敵します (または、人気のあるライブラリがバンドルされており、テンプレートなどの機能がすぐに利用できるため、おそらくわずかに優れているかもしれません) が、私は Sanic のほうが長く存在しており、より成熟していると考えています。より大きなコミュニティ。

 from vibora import Vibora, JsonResponse

app = Vibora()

@app.route('/')
async def home():
    return JsonResponse({'hello': 'world'})

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8000)

ただし、パフォーマンスマニアなら、Vibora を使えばボートが浮かぶかもしれません。とはいえ、この記事を書いている時点では、Vibora はさらに高速化するために完全な書き直しが行われており、パフォーマンス バージョンへの リンク には「鋭意開発中」と記載されています。 Vibora を以前に使い始めた人にとってはがっかりするでしょうし、すぐに破壊的な変更に直面することになりますが、Python 非同期の世界ではまだ初期段階にあり、物事が安定するとは誰も期待していません。

Python の非同期 Web フレームワーク トップ 9
Python の非同期 Web フレームワーク トップ 9

クォート

Flask での開発は楽しいが、非同期サポートがないことを残念に思う場合は、 Quart を 大いに楽しめるでしょう。

Quart は、有名な WSGI 標準の後継である ASGI 標準に準拠しており、非同期サポートを提供します。 Quart の興味深い点は、Flask に似ているだけでなく、実際に Flask API に準拠していることです。このフレームワークの作成者は、Flask の雰囲気を維持し、それに非同期、WebSocket、および HTTP 2 のサポートだけを追加したいと考えていました。その結果、Quart の関数が非同期であることを念頭に置くだけで、Flask ドキュメントから直接 Quart を学ぶことができます。

 from quart import Quart

app = Quart(__name__)

@app.route('/')
async def hello():
    return 'hello'

app.run()

Flask と (ほぼ) まったく同じように感じますね?!

Quart は Flask の進化版であるため、ルーティング、ミドルウェア、セッション、テンプレート、ブループリントなど、Flask 内のすべての機能が利用可能です。実際、Quart 内で直接 Flask 拡張機能を使用することもできます。 1 つの問題は、Python 3.7 以降のみがサポートされていることです。ただし、最新バージョンの Python を実行していない場合は、async が正しいパスではない可能性があります。 🙂

Flask の使用経験がない場合はドキュメントが非常に不足していますが、間もなく 1.0 リリースが近づく唯一の非同期フレームワークである Quart をお勧めします。

Python の非同期 Web フレームワーク トップ 9
Python の非同期 Web フレームワーク トップ 9

ファストAPI

このリストの最後の (ただし最も印象的な) フレームワークは FastAPI です。いいえ、API のみのフレームワークではありません。実際、FastAPI は、非同期 Python フレームワークを調査しているときに出会ったフレームワークの中で最も機能が豊富でドキュメントが豊富なようです。

興味深いのは、フレームワークの作成者が、Django のような現代的なフレームワークから Sanic のような現代的なフレームワークまで、他のいくつかのフレームワークを徹底的に研究し、NestJS (Node.js、Typescript Web フレームワーク) のテクノロジー全体を調べていることです。彼らの開発哲学と広範な比較は、 ここで 読むことができます。

構文は非常に快適です。これまでに出会った他のフレームワークよりもはるかに楽しいと主張する人もいます。

 rom fastapi import FastAPI

app = FastAPI()

@app.get("/users/me")
async def read_user_me():
    return {"user_id": "the current user"}

@app.get("/users/{user_id}")
async def read_user(user_id: str):
    return {"user_id": user_id}

次に、FastAPI を他のフレームワークよりも優れたものにするキラー機能のリストを示します。

API ドキュメントの自動生成 : エンドポイントが作成されるとすぐに、標準に準拠した UI を使用して API を操作できます。 SwaggerUI、ReDocなどがサポートされています。

このフレームワークは、JSON スキーマを使用してデータ モデルの自動ドキュメント化も行います。

モダンな開発 : はい、「モダン」という言葉はよく飛び交いますが、FastAPI が実際にその言葉を実践していることがわかりました。依存関係の挿入と型ヒントは第一級の機能であり、優れたコーディング原則を強制するだけでなく、長期的にはバグや混乱を防ぎます。

広範なドキュメント: あなたはどうか知りませんが、私は優れたドキュメントが大の苦手です。そしてこの分野では、FastAPI が断然勝利します。何ページにもわたって、ほとんどすべての微妙な点と「気をつけてください!」を説明するドキュメントが何ページにもわたって書かれています。あらゆるレベルの開発者向けの瞬間です。ここのドキュメントには明確な「心と魂」を感じますが、私が見つけることができる唯一の比較対象は Django ドキュメントです (はい、FastAPI ドキュメントはとても優れています!)。

基本を超えて: FastAPI は、CORS、セッション、Cookie などの従来のヘルパーをすべて備えていることに加えて、WebSocket、ストリーミング、GraphQL をサポートしています。

そしてパフォーマンスはどうですか? FastAPI は素晴らしい Starlette ライブラリに基づいて構築されているため、Node、場合によっては Go にも匹敵するパフォーマンスが得られます。全体として、FastAPI が Python のトップの非同期フレームワークとして先を争うだろうと私は本当に感じています。

黒い羊

BlackSheep を 使用すると、MVC パターンを使用してサーバー側アプリケーションまたはフルスタック アプリケーションを作成できます。

BlackSheep が提供する機能の一部は次のとおりです。

  • リッチコード API。
  • 組み込みの依存関係注入。
  • OpenAPI ドキュメントの組み込み生成。
  • リクエストハンドラーの自動バインド。

プロジェクトのセットアップ

BlackSheep を使用して基本的なサーバー側アプリケーションを作成してみましょう。以下のコマンドを 1 つずつすばやく実行して、プロジェクトをセットアップします。

 python -m venv basic-app
cd basic-app
source bin/activate
pip install blacksheep uvicorn

CentOS、Ubuntu、Windows に PIP パッケージ インストーラーをインストールする方法を学びます。

プロジェクトの設定が完了しました。 server.py というファイルを作成し、次のコードを配置しましょう。

 from blacksheep import Application

app = Application()

@app.router.get("/")
def home():
    return "Hello, World!"

最も有名な Hello World アプリケーションを作成しました。今のところ、 HTTP GET メソッドを持つルートは 1 つだけあり、それは / です。関数 home BlackSheep ではリクエスト ハンドラーと呼ばれます。

アプリの router デコレーターを使用しました。ルートを作成する別の方法、つまりルートがあります。このチュートリアルでは router 使用します。 route 詳細については、 ドキュメント を参照してください。

次のコマンドでアプリケーションを実行してみましょう。

 uvicorn server:app --port 8000 --reload

ブラウザで http://localhost:8000/ に移動します。ブラウザに hello world が表示されます。アプリケーションを実行するために使用したコマンドについて少し説明しましょう。

  • アプリケーションを実行するために uvicorn パッケージを使用しました。
  • server 私たちが指定したファイル名です。別のファイル名を使用する場合は、起動コマンドでも変更してください。
  • オプション --port は、アプリを実行するポートを指定します。
  • 最後に、 --reload オプションは、 server ファイルに変更を加えるたびにブラウザにアプリケーションをリロードします。

JSON応答

現実の世界では、ほとんどの場合、JSON での API 応答が必要になります。 blacksheep パッケージの json で JSON オブジェクトをラップすることで、メソッドから JSON 応答を返すことができます。どうすればできるか見てみましょう。

 from blacksheep import Application, json

app = Application()

@app.router.get("/")
def home():
    return json({"message": "Hello, World!"})

blacksheep から json インポートし、JSON オブジェクトをラップしました。ブラウザで JSON 応答を確認してください。

ルートパラメータ

リクエストに対してルートパラメータを受け入れる必要がある場合があります。 BlackSheep では、HTTP メソッド内で定義することでこれを行うことができます。それを見てみましょう。

 @app.router.get("/{name}")
def home(name):
    return json({"greetings": f"Hello, {name}!"})

name という name の 1 つのルート パラメーターを受け入れます。 http://localhost:8000/ に移動します。このメソッドは、ルートで指定された名前の挨拶を返します。

ルーター デコレータは、デコレータに与えられたのと同じ名前のパラメータを home 関数に渡します。ここでは name になります。デコレータで変更した場合は、 home 機能でも変更してください。

同様の方法で、できるだけ多くのルート パラメータを受け入れることができます。簡単な例を見てみましょう。

 @app.router.get("/{name}/{info}")
def home(name, info):
    return json({"greetings": f"Hello, {name}! Info {info}"})

info と呼ばれるもう 1 つのルート パラメーターを受け入れました。 http://localhost:8000//Chandan にアクセスして確認してください。

クエリパラメータ

クエリ パラメーターを受け入れるために何もする必要はありません。 BlackSheep は、クエリ パラメータをリストの形式で関数に自動的に送信します。例を見てみましょう。

 @app.router.get("/")
def home(name):
    print(name)
    return json({"greetings": f"Hello, {name[0]}!"})

http://localhost:8000/?name= にアクセスして応答を確認します。同じ名前のクエリ パラメータが複数ある場合、BlackSheep はそれらすべてをリストに追加します。

http://localhost:8000/?name=&name=Chandan に移動し、ターミナルの出力を確認します。同じ名前の 2 つのクエリ パラメーターを渡したため、 Chadan のリストが表示されます。

異なる複数のクエリ パラメーターが必要な場合も、それを行うことができます。クエリ パラメーター名を使用して関数に別の引数を追加し、それに対して必要な処理を実行するだけです。

リクエストオブジェクト

基本的に残っているのは、他の HTTP メソッドを確認することだけです。本題に入る前に、API の request オブジェクトを確認してみましょう。

BalckSheep 内のすべてのリクエスト ハンドラーには、受信するリクエストのすべての情報を含むリクエスト引数があります。これには、リクエスト ヘッダー、パス パラメーター、クエリ パラメーター、データなどが含まれます。

リクエストオブジェクトを確認する例を見てみましょう。

 @app.router.post("/")
def home(request):
    print(request)
    return "Hello, World!"

ターミナルに次の出力が表示されます。

 <Request POST />

リクエストからさまざまなものにアクセスできます。ドキュメントを確認してください。ここでは、リクエスト本文に焦点を当てます。リクエストオブジェクトからリクエストボディにアクセスする方法を見てみましょう。

 @app.router.post("/")
async def home(request):
    data = await request.json()
    print(data)
    return "Hello, World!"

リクエストには json と呼ばれるメソッドがあり、リクエストからのデータを返します。 API リクエストにデータを渡して呼び出します。 API に渡したデータがターミナルに表示されることがわかります。

HTTPメソッド

上記の例では、GET メソッドと POST メソッドについて説明しました。同様に、PUT、DELETE などのメソッドも使用できます。簡単なので、自分で試してみることは問題ありません。

AIOHTTP

aiohttp は 、次の主要な機能を備えた別のフレームワークです。

  • サーバー側とクライアント側の両方の WebSocket をサポートします。
  • サーバーとクライアントの両方のアプリケーション開発をサポートします。
  • その Web サーバーには、ミドルウェア、シグナル、およびプラグ可能なルーティングが含まれています。

プロジェクトのセットアップ

aiohttp を使用して基本的なサーバーサイド アプリケーションを作成しましょう。次のコマンドをすぐに実行して、プロジェクトをセットアップします。

 python -m venv basic-app
cd basic-app
source bin/activate
pip install aiohttp aiodns

server.py というファイルを作成し、その中に次のコードを配置します。

 from aiohttp import web

async def home(request):
    return web.Response(text="Hello, World!")

app = web.Application()
app.add_routes([web.get('/', home)])

web.run_app(app)

web.Application インスタンスがメイン アプリケーションです。お気に入りの hello world を返すルート / を含む HTTP GET メソッドを追加しました。 web.run_app 関数はアプリケーションを実行するために使用され、 web.Application インスタンスを引数として受け取ります。

関数 home aiohttp ではリクエスト ハンドラーと呼ばれます。そして、これには request という唯一の引数があり、これには受信リクエストのすべての情報が含まれます。

次のコマンドでアプリケーションを実行します。通常のPythonプログラムを実行するのと同じです。

 python3 server.py

ブラウザで http://localhost:8080/ に移動します。ブラウザに hello world が表示されます。

JSON応答

web.json_response 関数を使用すると、JSON 形式で応答を返すことができます。応答を返す際に、JSON データをその関数に渡します。例を見てみましょう。

 async def home(request):
    return web.json_response({"message": "Hello, World!"})

http://localhost:8080/ にアクセスすると、ブラウザーに JSON オブジェクトが表示されます。

ルートパラメータ

ルートを追加するときにルート パラメーターを定義できます。また、リクエスト ハンドラーの request 引数からアクセスできます。例を見てみましょう。

 from aiohttp import web

async def home(request):
    return web.json_response({"message": f"Hello, {request.match_info['name']}!"})

app = web.Application()
app.add_routes([web.get('/{name}', home)])

web.run_app(app)

上記の例に示すように、すべてのルート パラメーターには request.match_info からアクセスできます。 http://localhost:8080/ にアクセスして確認してください。

ルートに一致する正規表現を使用することもできます。 /{any_number} のみを受け入れる必要があるとしましょう。これを行うには、 '/{name}' r'/{number:\d+}' に置き換えます。 path パラメーターに正規表現を追加しました。これは、正規表現が渡された場合にのみ受け入れられます。

例を見てみましょう

from aiohttp import web

async def home(request):
    return web.json_response({"message": f"Hello, {request.match_info['number']}!"})

app = web.Application()
app.add_routes([web.get(r'/{number:\d+}', home)])

web.run_app(app)

http://localhost:8080/ にアクセスすると、 指定された正規表現パターンと一致しないため、404 エラーが発生します。次に、 http://localhost:8080/1234567890 にアクセスすると、ブラウザーに応答が表示されます。

クエリパラメータ

クエリ パラメーターを受け入れるために何も追加する必要はありません。 request.query オブジェクトからクエリ パラメーターを受け入れることができます。例を見てみましょう。

 from aiohttp import web

async def home(request):
    return web.json_response({"message": f"Hello, {request.query.get('name')}"})

app = web.Application()
app.add_routes([web.get('/', home)])

web.run_app(app)

http://localhost:8080/?name= にアクセスして結果を確認します。 request.query からアクセスしている応答に 表示されます。

キー名を使用してアクセスできる複数のクエリ パラメーターを渡すこともできます。

HTTPメソッド

上記の例では、HTTP GET メソッドを作成する方法を説明しました。次に進む前に、リクエスト データにアクセスする方法を知っておく必要があります。その例を見てみましょう。

 from aiohttp import web

async def home(request):
    data = await request.json()
    print(data)
    return web.json_response({"message": f"Hello, World!"})

app = web.Application()
app.add_routes([web.post('/', home)])

web.run_app(app)

上記の例では、API メソッドを GET から POST に変更しました。 request.json メソッドを使用してリクエスト データにアクセスしました。

http://localhost:8080/ にポストリクエストを送信すると、ターミナルにリクエストデータが表示されます。

同様に、PUT、DELETE などのメソッドも使用できます。ぜひ試してみて楽しんでください。

ドキュメント でフレームワークについてさらに詳しく調べることができます。

ファルコン

Falcon は、 REST API とマイクロサービスを構築するための ASGI フレームワークです。以下の主な特徴があります。

  • WebSocketをサポートしています。
  • リクエスト処理のためのミドルウェアとフックをサポートします。
  • シンプルでわかりやすい例外処理。

プロジェクトのセットアップ

Falcon フレームワークの基本を学ぶプロジェクトを設定しましょう。以下のコマンドを使用してプロジェクトをセットアップします。

 python -m venv basic-app
cd basic-app
source bin/activate
pip install falcon uvicorn

server.py というファイルを作成し、次のコードを配置します。

 from falcon import asgi
import falcon


class Home:
    async def on_get(self, request, response):
        response.status = falcon.HTTP_200  # This is the default status
        response.content_type = falcon.MEDIA_TEXT  # Default is JSON, so override
        response.text = 'Hello, World!'

app = asgi.App()
app.add_route('/', Home())

HTTPのGETメソッドである on_get メソッドを使用したクラスを作成しました。このメソッドには 2 つの引数があります。 1 つは request 、もう 1 つは if response です。名前自体からそれらが何であるかを推測できるはずです。

request 引数には、リクエストを処理するためにアクセスできる受信リクエストのすべての情報が含まれています。そして、 response 引数はさまざまなことを設定して応答を送信するために使用されます。

BlackSheep や AIOHTTP とは異なり、応答を返す必要はありません。応答を使用して、応答として送信する必要がある詳細を設定できます。上の例では、ステータスを 200、コンテンツ タイプをテキスト、テキストを hello world に設定しています。

次のコマンドでアプリケーションを実行します

uvicorn server:app --reload

http://localhost:8000/ にアクセスすると、応答として hello world が表示されます。

JSON応答

json.dumps メソッドを使用してデータを JSON に変換することで、応答を JSON として返すことができます。例を見てみましょう

from falcon import asgi
import falcon
import json

class Home:
    async def on_get(self, request, response):
        response.text = json.dumps({"greetings": "Hello, World!"})

app = asgi.App()
app.add_route('/', Home())

http://localhost:8000/ に移動すると、JSON で応答が表示されます。

ルートパラメータ

リクエスト パラメータは HTTP メソッドに引数として渡されます。よりよく理解するために、以下の例を参照してください。

 from falcon import asgi
import falcon
import json

class Home:
    async def on_get(self, request, response, name):
        response.text = json.dumps({"greetings": f"Hello, {name}!"})

app = asgi.App()
app.add_route('/{name}/', Home())

name path パラメータは引数として on_get メソッドに渡されます。 http://localhost:8000// に移動し、応答を確認します。ルートパラメータは必要なだけ持つことができます。

クエリパラメータ

request.get_param(param_name) メソッドを使用してクエリパラメータにアクセスできます。以下の例を確認してください。

 from falcon import asgi
import falcon
import json

class Home:
    async def on_get(self, request, response):
        response.text = json.dumps({"greetings": f"Hello, {request.get_param('name')}!"})

app = asgi.App()
app.add_route('/', Home())

http://localhost:8000/?name= にアクセスして応答を確認します。クエリパラメータは必要なだけ持つことができます。

HTTPメソッド

上の例では GET メソッドを見てきました。他のメソッドについて知っておく必要があるのは、リクエスト データにアクセスする方法です。 request.stream.read メソッドを使用してリクエスト データにアクセスできます。例を見てみましょう。

 from falcon import asgi
import falcon
import json

class Home:
    async def on_get(self, request, response):
        response.text = json.dumps({"greetings": "Hello, World!"})

    async def on_post(self, request, response):
        data = await request.stream.read()
        print(json.loads(data))
        response.text = "Hello, World!"

app = asgi.App()
app.add_route('/', Home())

リクエスト データにアクセスし、それを JSON に変換した後に端末に出力する POST メソッドを 1 つ追加しました。出力を確認するために、いくつかのデータを含む POST リクエストを作成します。

DELETE、PUT などの他の HTTP メソッドを自分で追加してみてください。 Falcon フレームワークの基本部分のみを変換しました。しかし、その中にはたくさんのものが含まれています。 ドキュメントを 読んで、さらに詳しく調べてください。

スターレット

Starlette は 、Python の軽量 ASGI フレームワークです。サーバー側アプリケーションを構築するためのほぼすべての基本機能が同様に備わっています。

以下のコマンドを使用してプロジェクトをセットアップします。

 python -m venv basic-app
cd basic-app
source bin/activate
pip install starlette uvicorn

Starlette を使用した API の作成は、これまでのフレームワークで見てきたものと似ています。 API の構文と作成方法は異なります。すべてのコンセプトは同じままです。したがって、すべてを 1 つのプログラムに含めることにします。

server.py というファイルを作成し、次のコードを配置します。

 from starlette.applications import Starlette
from starlette.responses import PlainTextResponse, JSONResponse
from starlette.routing import Route


def homepage(request):
    return PlainTextResponse('Hello, World!')

def json_response(request):
    return JSONResponse({'message': 'Hello, World!'})

def path_params(request):
    name = request.path_params['name']
    return JSONResponse({'greetings': f'Hello, {name}!'})

def query_params(request):
    name = request.query_params['name']
    return JSONResponse({'greetings': f'Hello, {name}!'})

async def post_method(request):
    data = await request.json()
    print(data)
    return JSONResponse({'message': f'Hello, World!'})

def startup():
    print('Starlette started')

routes = [
    Route('/', homepage),
    Route('/json', json_response),
    Route('/path-params/{name}', path_params),
    Route('/query-params', query_params),
    Route('/post', post_method, methods=['POST']),
]

app = Starlette(debug=True, routes=routes, on_startup=[startup])

次のコマンドでアプリケーションを実行します。

 uvicorn server:app --reload

これまでのフレームワークで確認したことをすべてテストします。 Starlette フレームワークの詳細については、 ドキュメント を参照してください。

結論

最近、Python の非同期環境では多くのことが起こっています。新しいフレームワークが登場し、古いフレームワークが書き直され、非同期の動作に合わせてライブラリが進化しています。 Python にはイベント ループのサポートが組み込まれており、アプリケーションの一部を非同期にすることができますが、ここにあるフレームワークの 1 つをオールインして構築することもできます。

ただし、長期的なことを念頭に置いてください。世にある Python 非同期フレームワークのいくつかは初期段階にあり、急速に進化しているため、開発プロセスに悪影響を及ぼし、ビジネス コストが上昇する可能性があります。

注意が鍵です!

しかし、すべてが終わった。 Python は、Web フレームワークに関してはすぐにでもパフォーマンスを発揮できるよう実稼働環境に対応しています。長い間 Node への移行を考えていたとしても、今はその必要はありません。 🙂

かっこいいね? 今日はPythonをマスターしましょう !

「 Python の非同期 Web フレームワーク トップ 9」についてわかりやすく解説!絶対に観るべきベスト2動画

【初心者必見!】PythonのWebフレームワークおすすめ5選を紹介
【FastAPI超入門】直感的にWeb API開発ができるモダンなPython WebフレームワークFastAPIの基礎を80分でマスター

非同期プログラミングは、現在 Python の第一級市民です。 Web 開発者であれば、選択できる素晴らしいフレームワークがあります。

この記事の執筆時点では、非同期は Python コミュニティにおける単なる流行語ではありません。バージョン 3.5 の asyncio ライブラリのリリースにより、Python は Web 開発に対する Node.js の影響を認識し、言語に 2 つの新しいキーワード async await を導入しました。

Python 言語は緊急の必要がない限りコア構文の拡張に非常に慎重であるため、これは非常 大きな問題でした。これは、Python 開発者が非同期機能をいかに根本的に重要であると考えていたかを示しているだけです。

その結果、非同期プログラミングの水門が開かれました。新旧のライブラリがコルーチン機能を利用し始め、非同期フレームワークの人気が爆発的に高まり、現在でも新しいものが作成され続けています。

Node.js と同等かそれ以上のパフォーマンスは前例のないことではなく、読み込みパターンに CPU を大量に使用するタスクが含まれていない限り、1 秒あたり数千のリクエストを実行できない理由はありません。

でもモチベーションは十分!

現在の Python の状況を調査し、主要な非同期フレームワークをいくつかチェックしてみましょう。

Python の非同期 Web フレームワーク トップ 9
Python の非同期 Web フレームワーク トップ 9

竜巻

驚くべきことに、 Tornado は まったく新しいフレームワークではありません。最初のリリースは 2009 年で、それ以来、高い同時実行性を備えた堅牢な非同期プログラミングを提供することに重点が置かれてきました。

Tornado は基本的に Web フレームワークではありません。これは非同期モジュールのコレクションであり、Web フレームワーク モジュールの構築にも使用されます。より具体的には、これらのモジュールは次のとおりです。

  • コルーチンとその他のプリミティブ ( tornado.gen tornado.locks tornado.queues など)
  • ネットワーク モジュール ( tornado.ioloop tornado.iostream など)
  • 非同期サーバーとクライアント ( tornado.httpserver tornado.httpclient など)

これらは結合されて、最終的なフレームワーク モジュール ( tornado.web tornado.routing tornado.template など) を生成します。

 import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Tornado は Python コミュニティに強力で献身的な支持者がおり、経験豊富なアーキテクトによって高度な機能を備えたシステムを構築するために使用されています。これは、長い間並行性の問題に対する答えを持っていたフレームワークですが、WSGI 標準をサポートしておらず、賛同が大きすぎたため、おそらく主流にはならなかったでしょう (Python ライブラリの大部分は依然として同期であることを思い出してください) )。

Python の非同期 Web フレームワーク トップ 9
Python の非同期 Web フレームワーク トップ 9

サニック

Sanic は、言葉の本当の意味で「最新の」フレームワークです。Python バージョン 3.6 未満はサポートせず、すぐに使用できるシンプルで汎用的な async/await 構文をサポートします。その結果、読みにくくなります。最初の HTTP ハンドラーを作成する前に、大量のドキュメントを参照し、エッジ ケースを念頭に置いてください。

その結果、(少なくとも私の意見では) 非常に快適な構文が得られます。これは、他のマイクロフレームワーク (Flask、CherryPy など) で作成するコードに似ていますが、いくつかの async が散りばめられています。

 from sanic import Sanic
from sanic.response import json

app = Sanic()

@app.route("/")
async def test(request):
    return json({"hello": "world"})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

Sanic はおそらく、Python の世界で最も人気があり、最も愛されている非同期フレームワークです。ルーティング、ミドルウェア、Cookie、バージョン管理、ブループリント、クラスベースのビュー、静的ファイル、ストリーミング、ソケットなど、プロジェクトに必要なほぼすべての機能と、そのままでは提供されない機能が備わっています。 — テンプレート、データベース サポート、ファイル I/O、キュー — は、現時点ではこれらに十分な量の非同期ライブラリがあるため、追加できます。

Python の非同期 Web フレームワーク トップ 9
Python の非同期 Web フレームワーク トップ 9

ビボラ

Vibora は Sanic のいとこに近いものですが、最速の Python Web サーバーになることにこだわっている点が異なります。実際、Web サイトに最初にアクセスすると、フレームワークの比較が表示されます。

ご覧のとおり、Vibora は従来のフレームワークよりも数倍高速であり、最も近い競合他社である Sanic よりも 2 倍以上高速であると主張しています。もちろん、ベンチマークは割り引いて判断する必要があります。 🙂

Vibora は構文と機能の点では Sanic に匹敵します (または、人気のあるライブラリがバンドルされており、テンプレートなどの機能がすぐに利用できるため、おそらくわずかに優れているかもしれません) が、私は Sanic のほうが長く存在しており、より成熟していると考えています。より大きなコミュニティ。

 from vibora import Vibora, JsonResponse

app = Vibora()

@app.route('/')
async def home():
    return JsonResponse({'hello': 'world'})

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8000)

ただし、パフォーマンスマニアなら、Vibora を使えばボートが浮かぶかもしれません。とはいえ、この記事を書いている時点では、Vibora はさらに高速化するために完全な書き直しが行われており、パフォーマンス バージョンへの リンク には「鋭意開発中」と記載されています。 Vibora を以前に使い始めた人にとってはがっかりするでしょうし、すぐに破壊的な変更に直面することになりますが、Python 非同期の世界ではまだ初期段階にあり、物事が安定するとは誰も期待していません。

Python の非同期 Web フレームワーク トップ 9
Python の非同期 Web フレームワーク トップ 9

クォート

Flask での開発は楽しいが、非同期サポートがないことを残念に思う場合は、 Quart を 大いに楽しめるでしょう。

Quart は、有名な WSGI 標準の後継である ASGI 標準に準拠しており、非同期サポートを提供します。 Quart の興味深い点は、Flask に似ているだけでなく、実際に Flask API に準拠していることです。このフレームワークの作成者は、Flask の雰囲気を維持し、それに非同期、WebSocket、および HTTP 2 のサポートだけを追加したいと考えていました。その結果、Quart の関数が非同期であることを念頭に置くだけで、Flask ドキュメントから直接 Quart を学ぶことができます。

 from quart import Quart

app = Quart(__name__)

@app.route('/')
async def hello():
    return 'hello'

app.run()

Flask と (ほぼ) まったく同じように感じますね?!

Quart は Flask の進化版であるため、ルーティング、ミドルウェア、セッション、テンプレート、ブループリントなど、Flask 内のすべての機能が利用可能です。実際、Quart 内で直接 Flask 拡張機能を使用することもできます。 1 つの問題は、Python 3.7 以降のみがサポートされていることです。ただし、最新バージョンの Python を実行していない場合は、async が正しいパスではない可能性があります。 🙂

Flask の使用経験がない場合はドキュメントが非常に不足していますが、間もなく 1.0 リリースが近づく唯一の非同期フレームワークである Quart をお勧めします。

Python の非同期 Web フレームワーク トップ 9
Python の非同期 Web フレームワーク トップ 9

ファストAPI

このリストの最後の (ただし最も印象的な) フレームワークは FastAPI です。いいえ、API のみのフレームワークではありません。実際、FastAPI は、非同期 Python フレームワークを調査しているときに出会ったフレームワークの中で最も機能が豊富でドキュメントが豊富なようです。

興味深いのは、フレームワークの作成者が、Django のような現代的なフレームワークから Sanic のような現代的なフレームワークまで、他のいくつかのフレームワークを徹底的に研究し、NestJS (Node.js、Typescript Web フレームワーク) のテクノロジー全体を調べていることです。彼らの開発哲学と広範な比較は、 ここで 読むことができます。

構文は非常に快適です。これまでに出会った他のフレームワークよりもはるかに楽しいと主張する人もいます。

 rom fastapi import FastAPI

app = FastAPI()

@app.get("/users/me")
async def read_user_me():
    return {"user_id": "the current user"}

@app.get("/users/{user_id}")
async def read_user(user_id: str):
    return {"user_id": user_id}

次に、FastAPI を他のフレームワークよりも優れたものにするキラー機能のリストを示します。

API ドキュメントの自動生成 : エンドポイントが作成されるとすぐに、標準に準拠した UI を使用して API を操作できます。 SwaggerUI、ReDocなどがサポートされています。

このフレームワークは、JSON スキーマを使用してデータ モデルの自動ドキュメント化も行います。

モダンな開発 : はい、「モダン」という言葉はよく飛び交いますが、FastAPI が実際にその言葉を実践していることがわかりました。依存関係の挿入と型ヒントは第一級の機能であり、優れたコーディング原則を強制するだけでなく、長期的にはバグや混乱を防ぎます。

広範なドキュメント: あなたはどうか知りませんが、私は優れたドキュメントが大の苦手です。そしてこの分野では、FastAPI が断然勝利します。何ページにもわたって、ほとんどすべての微妙な点と「気をつけてください!」を説明するドキュメントが何ページにもわたって書かれています。あらゆるレベルの開発者向けの瞬間です。ここのドキュメントには明確な「心と魂」を感じますが、私が見つけることができる唯一の比較対象は Django ドキュメントです (はい、FastAPI ドキュメントはとても優れています!)。

基本を超えて: FastAPI は、CORS、セッション、Cookie などの従来のヘルパーをすべて備えていることに加えて、WebSocket、ストリーミング、GraphQL をサポートしています。

そしてパフォーマンスはどうですか? FastAPI は素晴らしい Starlette ライブラリに基づいて構築されているため、Node、場合によっては Go にも匹敵するパフォーマンスが得られます。全体として、FastAPI が Python のトップの非同期フレームワークとして先を争うだろうと私は本当に感じています。

黒い羊

BlackSheep を 使用すると、MVC パターンを使用してサーバー側アプリケーションまたはフルスタック アプリケーションを作成できます。

BlackSheep が提供する機能の一部は次のとおりです。

  • リッチコード API。
  • 組み込みの依存関係注入。
  • OpenAPI ドキュメントの組み込み生成。
  • リクエストハンドラーの自動バインド。

プロジェクトのセットアップ

BlackSheep を使用して基本的なサーバー側アプリケーションを作成してみましょう。以下のコマンドを 1 つずつすばやく実行して、プロジェクトをセットアップします。

 python -m venv basic-app
cd basic-app
source bin/activate
pip install blacksheep uvicorn

CentOS、Ubuntu、Windows に PIP パッケージ インストーラーをインストールする方法を学びます。

プロジェクトの設定が完了しました。 server.py というファイルを作成し、次のコードを配置しましょう。

 from blacksheep import Application

app = Application()

@app.router.get("/")
def home():
    return "Hello, World!"

最も有名な Hello World アプリケーションを作成しました。今のところ、 HTTP GET メソッドを持つルートは 1 つだけあり、それは / です。関数 home BlackSheep ではリクエスト ハンドラーと呼ばれます。

アプリの router デコレーターを使用しました。ルートを作成する別の方法、つまりルートがあります。このチュートリアルでは router 使用します。 route 詳細については、 ドキュメント を参照してください。

次のコマンドでアプリケーションを実行してみましょう。

 uvicorn server:app --port 8000 --reload

ブラウザで http://localhost:8000/ に移動します。ブラウザに hello world が表示されます。アプリケーションを実行するために使用したコマンドについて少し説明しましょう。

  • アプリケーションを実行するために uvicorn パッケージを使用しました。
  • server 私たちが指定したファイル名です。別のファイル名を使用する場合は、起動コマンドでも変更してください。
  • オプション --port は、アプリを実行するポートを指定します。
  • 最後に、 --reload オプションは、 server ファイルに変更を加えるたびにブラウザにアプリケーションをリロードします。

JSON応答

現実の世界では、ほとんどの場合、JSON での API 応答が必要になります。 blacksheep パッケージの json で JSON オブジェクトをラップすることで、メソッドから JSON 応答を返すことができます。どうすればできるか見てみましょう。

 from blacksheep import Application, json

app = Application()

@app.router.get("/")
def home():
    return json({"message": "Hello, World!"})

blacksheep から json インポートし、JSON オブジェクトをラップしました。ブラウザで JSON 応答を確認してください。

ルートパラメータ

リクエストに対してルートパラメータを受け入れる必要がある場合があります。 BlackSheep では、HTTP メソッド内で定義することでこれを行うことができます。それを見てみましょう。

 @app.router.get("/{name}")
def home(name):
    return json({"greetings": f"Hello, {name}!"})

name という name の 1 つのルート パラメーターを受け入れます。 http://localhost:8000/ に移動します。このメソッドは、ルートで指定された名前の挨拶を返します。

ルーター デコレータは、デコレータに与えられたのと同じ名前のパラメータを home 関数に渡します。ここでは name になります。デコレータで変更した場合は、 home 機能でも変更してください。

同様の方法で、できるだけ多くのルート パラメータを受け入れることができます。簡単な例を見てみましょう。

 @app.router.get("/{name}/{info}")
def home(name, info):
    return json({"greetings": f"Hello, {name}! Info {info}"})

info と呼ばれるもう 1 つのルート パラメーターを受け入れました。 http://localhost:8000//Chandan にアクセスして確認してください。

クエリパラメータ

クエリ パラメーターを受け入れるために何もする必要はありません。 BlackSheep は、クエリ パラメータをリストの形式で関数に自動的に送信します。例を見てみましょう。

 @app.router.get("/")
def home(name):
    print(name)
    return json({"greetings": f"Hello, {name[0]}!"})

http://localhost:8000/?name= にアクセスして応答を確認します。同じ名前のクエリ パラメータが複数ある場合、BlackSheep はそれらすべてをリストに追加します。

http://localhost:8000/?name=&name=Chandan に移動し、ターミナルの出力を確認します。同じ名前の 2 つのクエリ パラメーターを渡したため、 Chadan のリストが表示されます。

異なる複数のクエリ パラメーターが必要な場合も、それを行うことができます。クエリ パラメーター名を使用して関数に別の引数を追加し、それに対して必要な処理を実行するだけです。

リクエストオブジェクト

基本的に残っているのは、他の HTTP メソッドを確認することだけです。本題に入る前に、API の request オブジェクトを確認してみましょう。

BalckSheep 内のすべてのリクエスト ハンドラーには、受信するリクエストのすべての情報を含むリクエスト引数があります。これには、リクエスト ヘッダー、パス パラメーター、クエリ パラメーター、データなどが含まれます。

リクエストオブジェクトを確認する例を見てみましょう。

 @app.router.post("/")
def home(request):
    print(request)
    return "Hello, World!"

ターミナルに次の出力が表示されます。

 <Request POST />

リクエストからさまざまなものにアクセスできます。ドキュメントを確認してください。ここでは、リクエスト本文に焦点を当てます。リクエストオブジェクトからリクエストボディにアクセスする方法を見てみましょう。

 @app.router.post("/")
async def home(request):
    data = await request.json()
    print(data)
    return "Hello, World!"

リクエストには json と呼ばれるメソッドがあり、リクエストからのデータを返します。 API リクエストにデータを渡して呼び出します。 API に渡したデータがターミナルに表示されることがわかります。

HTTPメソッド

上記の例では、GET メソッドと POST メソッドについて説明しました。同様に、PUT、DELETE などのメソッドも使用できます。簡単なので、自分で試してみることは問題ありません。

AIOHTTP

aiohttp は 、次の主要な機能を備えた別のフレームワークです。

  • サーバー側とクライアント側の両方の WebSocket をサポートします。
  • サーバーとクライアントの両方のアプリケーション開発をサポートします。
  • その Web サーバーには、ミドルウェア、シグナル、およびプラグ可能なルーティングが含まれています。

プロジェクトのセットアップ

aiohttp を使用して基本的なサーバーサイド アプリケーションを作成しましょう。次のコマンドをすぐに実行して、プロジェクトをセットアップします。

 python -m venv basic-app
cd basic-app
source bin/activate
pip install aiohttp aiodns

server.py というファイルを作成し、その中に次のコードを配置します。

 from aiohttp import web

async def home(request):
    return web.Response(text="Hello, World!")

app = web.Application()
app.add_routes([web.get('/', home)])

web.run_app(app)

web.Application インスタンスがメイン アプリケーションです。お気に入りの hello world を返すルート / を含む HTTP GET メソッドを追加しました。 web.run_app 関数はアプリケーションを実行するために使用され、 web.Application インスタンスを引数として受け取ります。

関数 home aiohttp ではリクエスト ハンドラーと呼ばれます。そして、これには request という唯一の引数があり、これには受信リクエストのすべての情報が含まれます。

次のコマンドでアプリケーションを実行します。通常のPythonプログラムを実行するのと同じです。

 python3 server.py

ブラウザで http://localhost:8080/ に移動します。ブラウザに hello world が表示されます。

JSON応答

web.json_response 関数を使用すると、JSON 形式で応答を返すことができます。応答を返す際に、JSON データをその関数に渡します。例を見てみましょう。

 async def home(request):
    return web.json_response({"message": "Hello, World!"})

http://localhost:8080/ にアクセスすると、ブラウザーに JSON オブジェクトが表示されます。

ルートパラメータ

ルートを追加するときにルート パラメーターを定義できます。また、リクエスト ハンドラーの request 引数からアクセスできます。例を見てみましょう。

 from aiohttp import web

async def home(request):
    return web.json_response({"message": f"Hello, {request.match_info['name']}!"})

app = web.Application()
app.add_routes([web.get('/{name}', home)])

web.run_app(app)

上記の例に示すように、すべてのルート パラメーターには request.match_info からアクセスできます。 http://localhost:8080/ にアクセスして確認してください。

ルートに一致する正規表現を使用することもできます。 /{any_number} のみを受け入れる必要があるとしましょう。これを行うには、 '/{name}' r'/{number:\d+}' に置き換えます。 path パラメーターに正規表現を追加しました。これは、正規表現が渡された場合にのみ受け入れられます。

例を見てみましょう

from aiohttp import web

async def home(request):
    return web.json_response({"message": f"Hello, {request.match_info['number']}!"})

app = web.Application()
app.add_routes([web.get(r'/{number:\d+}', home)])

web.run_app(app)

http://localhost:8080/ にアクセスすると、 指定された正規表現パターンと一致しないため、404 エラーが発生します。次に、 http://localhost:8080/1234567890 にアクセスすると、ブラウザーに応答が表示されます。

クエリパラメータ

クエリ パラメーターを受け入れるために何も追加する必要はありません。 request.query オブジェクトからクエリ パラメーターを受け入れることができます。例を見てみましょう。

 from aiohttp import web

async def home(request):
    return web.json_response({"message": f"Hello, {request.query.get('name')}"})

app = web.Application()
app.add_routes([web.get('/', home)])

web.run_app(app)

http://localhost:8080/?name= にアクセスして結果を確認します。 request.query からアクセスしている応答に 表示されます。

キー名を使用してアクセスできる複数のクエリ パラメーターを渡すこともできます。

HTTPメソッド

上記の例では、HTTP GET メソッドを作成する方法を説明しました。次に進む前に、リクエスト データにアクセスする方法を知っておく必要があります。その例を見てみましょう。

 from aiohttp import web

async def home(request):
    data = await request.json()
    print(data)
    return web.json_response({"message": f"Hello, World!"})

app = web.Application()
app.add_routes([web.post('/', home)])

web.run_app(app)

上記の例では、API メソッドを GET から POST に変更しました。 request.json メソッドを使用してリクエスト データにアクセスしました。

http://localhost:8080/ にポストリクエストを送信すると、ターミナルにリクエストデータが表示されます。

同様に、PUT、DELETE などのメソッドも使用できます。ぜひ試してみて楽しんでください。

ドキュメント でフレームワークについてさらに詳しく調べることができます。

ファルコン

Falcon は、 REST API とマイクロサービスを構築するための ASGI フレームワークです。以下の主な特徴があります。

  • WebSocketをサポートしています。
  • リクエスト処理のためのミドルウェアとフックをサポートします。
  • シンプルでわかりやすい例外処理。

プロジェクトのセットアップ

Falcon フレームワークの基本を学ぶプロジェクトを設定しましょう。以下のコマンドを使用してプロジェクトをセットアップします。

 python -m venv basic-app
cd basic-app
source bin/activate
pip install falcon uvicorn

server.py というファイルを作成し、次のコードを配置します。

 from falcon import asgi
import falcon


class Home:
    async def on_get(self, request, response):
        response.status = falcon.HTTP_200  # This is the default status
        response.content_type = falcon.MEDIA_TEXT  # Default is JSON, so override
        response.text = 'Hello, World!'

app = asgi.App()
app.add_route('/', Home())

HTTPのGETメソッドである on_get メソッドを使用したクラスを作成しました。このメソッドには 2 つの引数があります。 1 つは request 、もう 1 つは if response です。名前自体からそれらが何であるかを推測できるはずです。

request 引数には、リクエストを処理するためにアクセスできる受信リクエストのすべての情報が含まれています。そして、 response 引数はさまざまなことを設定して応答を送信するために使用されます。

BlackSheep や AIOHTTP とは異なり、応答を返す必要はありません。応答を使用して、応答として送信する必要がある詳細を設定できます。上の例では、ステータスを 200、コンテンツ タイプをテキスト、テキストを hello world に設定しています。

次のコマンドでアプリケーションを実行します

uvicorn server:app --reload

http://localhost:8000/ にアクセスすると、応答として hello world が表示されます。

JSON応答

json.dumps メソッドを使用してデータを JSON に変換することで、応答を JSON として返すことができます。例を見てみましょう

from falcon import asgi
import falcon
import json

class Home:
    async def on_get(self, request, response):
        response.text = json.dumps({"greetings": "Hello, World!"})

app = asgi.App()
app.add_route('/', Home())

http://localhost:8000/ に移動すると、JSON で応答が表示されます。

ルートパラメータ

リクエスト パラメータは HTTP メソッドに引数として渡されます。よりよく理解するために、以下の例を参照してください。

 from falcon import asgi
import falcon
import json

class Home:
    async def on_get(self, request, response, name):
        response.text = json.dumps({"greetings": f"Hello, {name}!"})

app = asgi.App()
app.add_route('/{name}/', Home())

name path パラメータは引数として on_get メソッドに渡されます。 http://localhost:8000// に移動し、応答を確認します。ルートパラメータは必要なだけ持つことができます。

クエリパラメータ

request.get_param(param_name) メソッドを使用してクエリパラメータにアクセスできます。以下の例を確認してください。

 from falcon import asgi
import falcon
import json

class Home:
    async def on_get(self, request, response):
        response.text = json.dumps({"greetings": f"Hello, {request.get_param('name')}!"})

app = asgi.App()
app.add_route('/', Home())

http://localhost:8000/?name= にアクセスして応答を確認します。クエリパラメータは必要なだけ持つことができます。

HTTPメソッド

上の例では GET メソッドを見てきました。他のメソッドについて知っておく必要があるのは、リクエスト データにアクセスする方法です。 request.stream.read メソッドを使用してリクエスト データにアクセスできます。例を見てみましょう。

 from falcon import asgi
import falcon
import json

class Home:
    async def on_get(self, request, response):
        response.text = json.dumps({"greetings": "Hello, World!"})

    async def on_post(self, request, response):
        data = await request.stream.read()
        print(json.loads(data))
        response.text = "Hello, World!"

app = asgi.App()
app.add_route('/', Home())

リクエスト データにアクセスし、それを JSON に変換した後に端末に出力する POST メソッドを 1 つ追加しました。出力を確認するために、いくつかのデータを含む POST リクエストを作成します。

DELETE、PUT などの他の HTTP メソッドを自分で追加してみてください。 Falcon フレームワークの基本部分のみを変換しました。しかし、その中にはたくさんのものが含まれています。 ドキュメントを 読んで、さらに詳しく調べてください。

スターレット

Starlette は 、Python の軽量 ASGI フレームワークです。サーバー側アプリケーションを構築するためのほぼすべての基本機能が同様に備わっています。

以下のコマンドを使用してプロジェクトをセットアップします。

 python -m venv basic-app
cd basic-app
source bin/activate
pip install starlette uvicorn

Starlette を使用した API の作成は、これまでのフレームワークで見てきたものと似ています。 API の構文と作成方法は異なります。すべてのコンセプトは同じままです。したがって、すべてを 1 つのプログラムに含めることにします。

server.py というファイルを作成し、次のコードを配置します。

 from starlette.applications import Starlette
from starlette.responses import PlainTextResponse, JSONResponse
from starlette.routing import Route


def homepage(request):
    return PlainTextResponse('Hello, World!')

def json_response(request):
    return JSONResponse({'message': 'Hello, World!'})

def path_params(request):
    name = request.path_params['name']
    return JSONResponse({'greetings': f'Hello, {name}!'})

def query_params(request):
    name = request.query_params['name']
    return JSONResponse({'greetings': f'Hello, {name}!'})

async def post_method(request):
    data = await request.json()
    print(data)
    return JSONResponse({'message': f'Hello, World!'})

def startup():
    print('Starlette started')

routes = [
    Route('/', homepage),
    Route('/json', json_response),
    Route('/path-params/{name}', path_params),
    Route('/query-params', query_params),
    Route('/post', post_method, methods=['POST']),
]

app = Starlette(debug=True, routes=routes, on_startup=[startup])

次のコマンドでアプリケーションを実行します。

 uvicorn server:app --reload

これまでのフレームワークで確認したことをすべてテストします。 Starlette フレームワークの詳細については、 ドキュメント を参照してください。

結論

最近、Python の非同期環境では多くのことが起こっています。新しいフレームワークが登場し、古いフレームワークが書き直され、非同期の動作に合わせてライブラリが進化しています。 Python にはイベント ループのサポートが組み込まれており、アプリケーションの一部を非同期にすることができますが、ここにあるフレームワークの 1 つをオールインして構築することもできます。

ただし、長期的なことを念頭に置いてください。世にある Python 非同期フレームワークのいくつかは初期段階にあり、急速に進化しているため、開発プロセスに悪影響を及ぼし、ビジネス コストが上昇する可能性があります。

注意が鍵です!

しかし、すべてが終わった。 Python は、Web フレームワークに関してはすぐにでもパフォーマンスを発揮できるよう実稼働環境に対応しています。長い間 Node への移行を考えていたとしても、今はその必要はありません。 🙂

かっこいいね? 今日はPythonをマスターしましょう !

「 Python の非同期 Web フレームワーク トップ 9」についてわかりやすく解説!絶対に観るべきベスト2動画

【初心者必見!】PythonのWebフレームワークおすすめ5選を紹介
【FastAPI超入門】直感的にWeb API開発ができるモダンなPython WebフレームワークFastAPIの基礎を80分でマスター