Help us understand the problem. What is going on with this article?

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

naoiwata
hachidoriinc
「すべての人に、価値ある仕事を」先端技術と上手く共存し、すべての人が、人間にしかできない「価値ある」仕事に集中できる世界を作りたい。そんな思いでhachidoriはサービスを提供しています。
https://hachidoriinc.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away