Edited at

JSON ファイルを出入力するだけの簡単な API をつくる ~Python/Flask 編~

More than 5 years have passed since last update.

(※ 編集リクエストをマージしたのでコード大きく変わりました. 機能に変更はありません.)


目的

クライアントから簡単に JSON の読み書きできるような API をさくっと作る。


この記事でやること


  • Python2.7 / Flask を使う。

  • DB の代わりに JSON ファイルを生成/読みこみ/書きこみする。


この記事でやらないこと


  • Python の環境構築。

  • 細かいコードの説明とか。


背景

コンテンツの状態、ユーザの状態などによって UI を変更したいのです。クライアント(Web まわり)を作りながら、画面の状態やパラメータを追加・変更できるような、状態を返す JSON が欲しくなったので、簡単なものを作ってみました。自分のローカル環境で動かす程度の簡易なものです。(本番環境では専用のアプリケーションサーバなど使ったりするのを想定しています。)


API

JSON のファイル名を key、取り出すデータ(JSON)を value として、JSON を KVS ライクに扱う API です。ローカルで Flask を使って http://127.0.0.1:5000 を起動してこことやりとりします。


key を指定して values (JSON)を取得

<key>.json を取得する場合に使う。

$ curl http://127.0.0.1:5000/api/<key> -X GET

$.ajax({

type: 'GET'
url:'http://127.0.0.1:5000/api/<key>'
}).done(function(res){
// GET した後の処理
});


key を指定して values (JSON)を追加または更新

<key>.json に、例えば {"status": 0} を登録(もしくは上書き)する場合に使う。

$ curl http://127.0.0.1:5000/api/<key> -X POST\

--data '{"status": 0}' -H "Content-type: application/json"

$.ajax({

type: 'POST',
url:'http://127.0.0.1:5000/api/<key>',
data: '{"status": 0}',
headers: {
'Content-Type': 'application/json'
}
}).done(function(res){
// POST した後の処理
});


key に紐付いた values (JSON)内の パラメータ(json_key) を削除

<key>.json に、例えば {"<json_key>": <任意の値>} が含まれる場合、<key>.json から <json_key> の要素を削除する。

$ curl http://127.0.0.1:5000/api/<key>/<json_key> -X DELETE

$.ajax({

type: 'DELETE',
url:'http://127.0.0.1:5000/api/<key>/<json_key>'
}).done(function(res){
// DELETE した後の処理
});


書いた

まずは最小限、小さく作りました。

※ write 時に副作用あるので注意。


API 実装部分


api.py

# -*- coding: utf-8 -*-


import json

from flask import Flask, request, jsonify

app = Flask(__name__)

"""Routing: リクエストの URI とメソッドに応じた処理を呼び出し、結果を返す。"""
@app.route('/', methods=['GET'])
def hello():
return 'hello:)'

@app.route('/api/<key>', methods=['GET'])
def get(key):
model = get_model(key)
if model is None:
return "NOT FOUND"
else:
return jsonify(model)

@app.route('/api/<key>', methods=['POST'])
def post(key):
result = set_property(key, json.loads(request.data))
return jsonify(result)

@app.route('/api/<key>/<property_name>', methods=['DELETE'])
def delete(key, property_name):
result = delete_property(key, property_name)
if result is None:
return "NOT FOUND"
else:
return jsonify(result)

"""モデルに対する操作"""
def get_model(key):
return read_model(key)

def set_property(key, properties):
data = read_model(key)
if data is None:
data = {}
data.update(properties)
result = write_model(key, data)
return result

def delete_property(key, property_name):
data = read_model(key)
if data is None:
return None
if property_name not in data:
return None
del data[property_name]
result = write_model(key, data)
return result

"""永続化層アクセス"""
def read_model(key):
file_name = key + '.json'
try:
with open(file_name, 'r') as f:
return json.load(f)
except IOError as e:
print e
return None

def write_model(key, data):
file_name = key + '.json'
try:
with open(file_name, 'w') as f:
json.dump(data, f, sort_keys=True, indent=4)
return data
except IOError as e:
print e
return None

if __name__ == '__main__':
app.run(debug=True)



使い方

$ python api.py

Web サーバが起動するので、http://127.0.0.1:5000 にアクセスして使う。


リファクタして Github に置いた

一応、requests でテストを書いて Github に置きました。

https://github.com/naoiwata/simple-flask-api