Python界に今新しい風が巻き起こる…?
What is "responder"
pythonを使っている方なら知っている人の多い requests や pipenv の作者 kennethreitz が作ったWebフレームワーク。Pythonは Django や Flask などの登場以降「コレだ!」となるフレームワークが出てこなかったのですが、2018年に突如として登場したのが responder です。
詳しいことは公式ドキュメントを参照してほしいのですが、ざっくり言うと
- FlaskとFalconの良いとこどりのようなフレームワーク
- GraphQL、asyncなど今どき(2019年現在)の機能に対応
- APIが使いやすい(わかりやすい)
といった感じです。
作者も実績は文句なしなので、これは Python Web Framework界 の覇権最有力候補ではないかと思います。
What is "tortoise-orm"
Python製ORMと言えばご存知 SQLAlchemy ですね。しかし、こちらも如何せん古…ご高齢(初回リリース2006年)なので、新しいモノはないかと物色したところ、DjangoのORMをリスペクトして作られた Tortoise ORM を発見。
個人的にDjangoの設計思想は好きでして、ModelとSchemeを1つのコードで簡潔でき、さらに asyncio
に対応していたので、一発で採用決定。
上記理由によりresponderとの相性はかなり良い感じかと思います。
Sample
使用技術
- Python 3.7
- pipenv
- responder
- tortoise-orm
Install and Run
pipenvをインストールしておけば、サンプルのREADMEに書いている通りにコマンドを叩けば動くはずです。tortoise-ormがpipenvに対応していないみたいなので、GitHubから直接取ってくる形になっていますが、一応動いたのでよし。そのうち対応して欲しいですね。
pipenvは scripts
にコマンドを追加できるので、プロダクトで扱う時も便利ですね。
[scripts]
migrate="python migrate.py"
start="python main.py"
Migration
下記のファイルを用意してPythonで実行するだけです。
from tortoise import Tortoise, run_async
async def migrate():
# connect DB
await Tortoise.init(
db_url="sqlite://db.sqlite3", # DB URL
modules={"models": ["models"]} # Modelを書いたファイルを指定
)
# run migrate
await Tortoise.generate_schemas()
run_async(migrate())
Main
書き方は色々とあると思いますが、DBコネクションの接続・切断とルーティングの設定を行い、アプリケーションを立ち上げる main.py
を作成。
Pythonで実行するとresponderが立ち上がります。
import responder
from tortoise import Tortoise
from router import add_routers
api = responder.API()
# 立ち上げのタイミングでDBへのコネクションを確立
@api.on_event("startup")
async def start_db_connection():
await Tortoise.init(
db_url="sqlite://db.sqlite3",
modules={"models": ["models"]}
)
# 落とすタイミングでDBコネクションを切断
@api.on_event("shutdown")
async def close_db_connection():
await Tortoise.close_connections()
# router.pyにてルーティングを設定
add_routers(api)
if __name__ == '__main__':
api.run(debug=True)
Routing
mainに書いても良かったのですが、Djangoの urls.py
のようにルーティングだけのファイルが欲しかったので作成。
api: responder.API
を受け取らないで良いように改良したい。
import responder
from controllers.account import Account
def add_routers(api: responder.API):
api.add_route("/accounts", Account)
Models
もちろん tortoise-orm
で実装。
Djangoになれた人であればかなり使いやすいです。
from tortoise.models import Model
from tortoise import fields
class User(Model):
id = fields.IntField(pk=True)
name = fields.TextField()
def __str__(self):
return self.name
Controllers
Djangoにおける views.py
に相当する。
router.py
でルーティングの設定、main.py
でDBコネクションを確立できているので、かなりスッキリ書けました。また、resp
にレスポンスの設定(ステータスコード等)をしていくだけなので、視認性がとても良い。
from models import User
class Account:
async def on_get(self, req, resp):
# とりあえずテスト用のアカウント(ユーザー)を作る
await User.create(name="Test User")
user = await User.first()
resp.text = f"Hello, {user.name}"
まとめと所感
responder
のツボを付いた、かゆいところに手が届く、使いやすいAPI群。
tortoise-orm
のDjangoチックで明快なORM機能。
一言で言うと So Good!
まだ出たばかり(両方2018年に初リリース)なので、使ううちに粗が見えると思うのですが、相性がバッチリなのでこの組み合わせは十分覇権を狙えるポテンシャルを持っています。
サンプルということで、両方とも書いていない機能がたくさんあるので、Python Web Framework界の旋風 を是非みなさんもお試しください。