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
でデコードされたデータが得られる。