2022-12-12
Posted by
今回はflaskの基本構文を紹介していきます
あまり詳しくは紹介しないので詳しく知りたい人は各自調べてください(責任と存在意義の放棄)
今回はapiで使う前提なのでjinja(frontend)などを省いています
何もしないコード
from flask import Flask
app = Flask(__name__)
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
このコードは本当に何もしません
ルーティング
まずは127.0.0.1:5000/
にアクセスするとHello, world!
と表示するコードを追加しましょう
ルーティングには幾つかの方法がありますが一番簡単な方法が@app.route
を使う方法です
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def index():
return jsonify({"msg": "Hello, world!"})
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
もしかすると/user/abc
や/user/osaka
など動的に変更したい場合もあるでしょう、そのようなときは/user/<username>
などのようにすれば解決できます
@app.route("/user/<username>")
def index(username):
return jsonify({"msg": "hey {}".format(username)})
また型を付ける事も出来ます
@app.route("/user/<string:username>")
#文字列(デフォルト
@app.route("/user/<int:username>")
# 整数
@app.route("/user/<float:username>")
# 小数
@app.route("/user/<path:username>")
# "/"を使える以外は、文字列と同じ
@app.route("/user/<any:username>")
# 上記のどれか
@app.route("/user/<uuid:username>")
# uuid文字列
場合によってはデフォルトが必要になる事もあるでしょう、ぴったりの機能があります
@app.route('/users/', defaults={'page': 1})
@app.route('/users/page/<int:page>')
これで一通りできました、ですがまだ大事な事を忘れています
メソッド
@app.route("/")
このコードは暗黙的に以下のコードと同等です
@app.route("/", methods=["GET"])
その他にもPOST,DELETEがあります
@app.route("/", methods=["POST"])
@app.route("/", methods=["DELETE"])
複数の指定もできます
@app.route("/", methods=["GET", "POST"])
リクエスト
クライアントからリクエストされたデータを取得するにはrequest
クラスを使います
from flask import request
主にこのクラスを使い、リクエストされたデータを参照します
色々ありますがまずは、よく使う物を紹介します
request.args
"""
URLのクエリ文字列をwerkzeug.ImmutableMultiDictクラスで取得する
ImmutableMultiDictクラスの取り扱い方に関しては後述します
"""
request.form
"""
postなどのformデータを取得します
こちらもImmutableMultiDictで取得します
"""
request.headers
"""
headerのデータを取得します
こちらも同じです
"""
request.files
"""
fileを取得します
同じ
"""
werkzeug.ImmutableMultiDictからデータを取り出す
ここではrequest.args
を例に解説しますがrequest.form
などでも同じように使えます
データを取り出すのに一番簡単方法は.get
を使う事です
request.args.get(key, default=None, type=None)
"""
全て指定した場合
request.args.get("x", default=1, type=int)
"""
例えば127.0.0.1:3000/?x=10&y=50
の場合request.args
で取得できるデータはImmutableMultiDict([('x', '10'), ('y', '30')])
です
つまりxを取得したい場合request.args.get("x")
となります
defaultは例えば127.0.0.1:3000/?y=50
の場合None
が返されますが,
デフォルトを指定した場合defaultの値が返されます
typeはデフォルトではargsの値に関係なく全てstr型で返されますが、型を指定した場合、指定した型で返されます、strから指定した型に変換した時にエラーが出た場合はdefaultの値が返されます
getのコード
ImmutableMultiDictについての詳細
画像やファイルを取り出して保存する
最小例
import os
basedir = os.path.abspath(os.path.dirname(__file__))
file_path = os.path.join(basedir, 'contents')
@app.route("/image", methods=["POST"])
def image_save():
"""
今回は'file'と言う名前のfileを取り出していますが、適度変えてください
"""
file = request.files.get("file")
file.save(os.path.join(file_path, filename))
return jsonify({"path": filename}),200
上記の最小例でも機能しますが、少し不安です、画像のみを保存したい場合や安全に保存したい場合は少し手を加える必要があります
from werkzeug.utils import secure_filename
import os
basedir = os.path.abspath(os.path.dirname(__file__))
file_path = os.path.join(basedir, 'contents')
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route("/image", methods=["POST"])
def image_save():
file = request.files.get("file")
if not file or not file.filename or not allowed_file(file.filename):
return jsonify("file not allowed"), 400
filename = secure_filename(file.filename)
file.save(os.path.join(file_path, filename))
return jsonify({"path": filename}),200
レスポンス
jsonを返す
jsonを返す場合はjsonifyを使います
@app.route("/")
def index():
return jsonify({"msg": "Hello, world!"})
画像やファイルを返す
画像やファイルなどを返す場合はsend_from_directory
を使います
import os
from flask import send_from_directory
basedir = os.path.abspath(os.path.dirname(__file__))
file_path = os.path.join(basedir, 'contents')
@app.route("/image/<string:path>", methods=["GET"])
def image_path(path):
return send_from_directory(file_path, path)
status code
status codeを返したい場合は、2番目の戻り値で指定します
@app.route("/")
def index():
from random import random
if(random() < 0.5):
return jsonify({"msg": "変態!!"}), 418
return jsonify({"msg": "別にアンタのことなんか好きじゃないんだからね!"}), 200
主なstatus codeの一覧
設定
時に設定をいじることもあります設定を変更する方法は、色々ありますがここではfrom_mapping
を使います
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY = "secret"
,JSON_AS_ASCII = False
)
from_mapping
以外にfrom_file
など色々あります
終わり
これで一通り終わりました、だぶん、きっと
このドキュメントどう?