Flask で POST された JSON を受け取るには request.json を使えばいい。
サーバー側(Flask)のコードはこんな感じ:
from flask import request, redirect, url_for, render_template, flash, json
(中略)
@app.route('/api/book/add/', methods=['POST'])
def api_book_add():
categ = Category.query.filter_by(name=request.json['category']).first()
fmt = Format.query.filter_by(name=request.json['format']).first()
book = Book(
title = request.json['title'],
volume = request.json['volume'],
series = request.json['series'],
series_volume = request.json['series_volume'],
author = request.json['author'],
translator = request.json['translator'],
publisher = request.json['publisher'],
category_id = categ.id,
format_id = fmt.id,
isbn = request.json['isbn'],
published_on = request.json['published_on'],
original_title = request.json['original_title'],
note = request.json['note'],
keyword = request.json['keyword'],
disk = request.json['disk']
)
if request.json['disposed'] == '1':
book.disposed = True
db.session.add(book)
db.session.commit()
return json.dumps({ "status": "OK", "books": [book.to_dictionary()]})
POST するクライアント側(こっちは Ruby)はこう:
#!/usr/bin/env ruby
# encoding: utf-8
require 'httpclient'
require 'yaml'
require 'csv'
require 'json'
require 'optparse'
def post_book(book)
post_url = "http://localhost:5000/api/book/add/"
post_data = {
"title" => book["title"],
"volume" => book["volume"] || "",
"series" => book["series"] || "",
"series_volume" => book["series_volume"] || "",
"author" => book["author"] || "",
"translator" => book["translator"] || "",
"publisher" => book["publisher"] || "",
"category" => book["category"] || "その他",
"format" => book["format"] || "その他",
"isbn" => book["isbn"] || "",
"published_on" => book["published_on"] || "",
"original_title" => book["original_title"] || "",
"note" => book["note"] || "",
"keyword" => book["keyword"] || "",
"disk" => book["disk"] || "",
"disposed" => book["disposed"] || "0"
}
json_data = post_data.to_json
res = @client.post_content(post_url, json_data, "Content-Type" => "application/json")
result = JSON.parse(res)
puts title_with_vol(result["books"].first)
end
def title_with_vol(book)
if book["volume"].nil? || book["volume"].empty?
book["title"]
else
book["title"] + " [" + book["volume"] + "]"
end
end
options = {}
opts = OptionParser.new
opts.banner = <<EOB
Options:
EOB
opts.on("--csv", "Input from CSV."){|v| options[:csv] = true }
opts.on_tail("--help", "-h", "Show this message"){|v|
puts opts.help
exit(0)
}
opts.parse!
@client = HTTPClient.new
inputfile = ARGV.shift
books = if options[:csv]
csvfile = File.open(inputfile, "r")
CSV.new(csvfile, headers: true)
else
YAML.load_file(inputfile)["books"]
end
books.each do |book|
post_book(book)
end
HTTPClient#post_content に JSON と "Content-Type" => "application/json" を渡してるのがミソ。Content-Type が application/json になってることで、Flask.request.json でデコードされたデータが得られる。