LoginSignup
75
79

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-06-05

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

目的

クライアントから簡単に 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 に置きました。

75
79
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
75
79