FlaskでJSONを受け取る

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-Typeapplication/json になってることで、Flask.request.json でデコードされたデータが得られる。