ZEIT NowでFlaskをデプロイする


NOWを使ってPython(Flask)をどうさせようとしたら苦戦した。公式ドキュメントも見づらいので改めてまとめる。

Flaskを最低限動かす

Flaskを動かすだけならこれで動作する。now.jsonの builds が重要なポイント。

index.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def index():
    return "hello"
requirements.txt
flask==1.0.2
now.json
{
    "version": 2,
    "builds": [{ "src": "index.py", "use": "@now/python" }]
}

複数のルーティングに対応する

問題点

index.pyに /hello を処理するルーティングを追加したとする。

index.py
from flask import Flask
app = Flask(__name__)


@app.route("/")
def index():
    return "hello"

@app.route("/hello")
def world():
    return "world"

404になっている様子

この状態でデプロイして /hello にアクセスすると404になってしまう。

now.jsonにroutesを追加し回避する

適切に処理するためには、now.jsonを編集し、routesを追加する。これで、どんなリクエストでもwsgiのrootで処理されるようになる。

now.json
{
    "version": 2,
    "builds": [{ "src": "index.py", "use": "@now/python" }],
    "routes": [{ "src": "/.*", "dest": "/" }]
}

正常にリクエストをさばけている様子

すべてのパスをFlaskが処理するようになっている様子

routesを追加したため、存在しないパスへリクエストが来ると必ずFlask経由で処理される。

404ページをカスタマイズする

Flaskの公式ドキュメントのカスタムエラーページを見てカスタマイズできる

index.py
from flask import Flask, jsonify
app = Flask(__name__)

@app.route("/")
def index():
    return "hello"

@app.route("/hello")
def world():
    return "world"

@app.errorhandler(404)
def resource_not_found(e):
    return jsonify(error=str(e)), 404

様子