web-dev-qa-db-ja.com

POST request in flask python

私はpythonでflaskを使用して、この tutorial の手順に従ってシンプルなRESTフルWebサーバーを作成しましたが、POSTリクエストの呼び出しで問題が発生しました。コードは:

@app.route('/todo/api/v1.0/tasks', methods=['POST'])
def create_task():
    if not request.json or not 'title' in request.json:
        abort(400)
    task = {
        'id': tasks[-1]['id'] + 1,
        'title': request.json['title'],
        'description': request.json.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task}), 201

上記のページの例として、POSTを使用してcurlリクエストを送信します。

curl -i -H "Content-Type: application/json" -X POST -d '{"title":"Read a book"}' http://127.0.0.1:5000/todo/api/v1.0/tasks

しかし、私は応答でこのエラーを受け取ります:

HTTP/1.0 400 BAD REQUEST
Content-Type: text/html
Content-Length: 187
Server: Werkzeug/0.11.10 Python/2.7.9
Date: Mon, 30 May 2016 09:05:52 GMT

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)</p>

私はデバッグを試みましたが、get_jsonメソッドで、渡された引数がdataおよび'\\'{title:Read a book}\\''Noneであるため、request_charsetに変換されていることがわかりました。しかし、私には解決策がありません。何か助けは?

編集1:

@domoarrigatoの答えを試し、create_taskメソッドを次のように実装しました。

@app.route('/todo/api/v1.0/tasks', methods=['POST'])
def create_task():
    try:
        blob = request.get_json(force=True)
    except:
        abort(400)
    if not 'title' in blob:
        abort(400)
    task = {
        'id': tasks[-1]['id'] + 1,
        'title': blob['title'],
        'description': blob.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task}), 201

しかし、今回は、POSTを介してcurlを呼び出した後、次のエラーが発生しました。

HTTP/1.0 400 BAD REQUEST
Content-Type: text/html
Content-Length: 192
Server: Werkzeug/0.11.10 Python/2.7.9
Date: Mon, 30 May 2016 10:56:47 GMT

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>The browser (or proxy) sent a request that this server could not understand.</p>

編集2:

明確にするために、私は64ビットバージョンのMicrosoft Windows 7でPythonバージョン2.7と最新バージョンのFlaskを使用して作業していることを言及する必要があります。

10

これはWindows 7 64で機能します。

curl -i -H "Content-Type: application/json" -X POST -d "{\"title\":\"Read a book\"}" http://localhost:5000/todo/api/v1.0/tasks

バックスラッシュと二重引用符。

19

Windowsを使用している場合、リクエストのjson文字列は次のようになります。

"{\"title\":\"Read a boo\"}"

私は同じ問題を抱えており、それが助けになりました。

Anaconda cmdウィンドウpython3を使用して、式全体をバックスラッシュと二重引用符で囲み、なんとか動作させることができました!作品:

curl "localhost:5000/txion" -H "Content-Type: application/json" -d "{\"from\": \"akjflw\" ,\"to\" : \"fjlakdj\", \"amount\": 4}"

動作しません:

curl "localhost:5000/txion" -H "Content-Type: application/json" -d '{\"from\": \"akjflw\" ,\"`to\" : \"fjlakdj\", \"amount\": 4}'
3
user2062469

request.jsonプロパティを使用する代わりに、request.get_json(force=True)を使用してみてください。

@app.route('/todo/api/v1.0/tasks', methods=['POST'])
def create_task():
    try:
        blob = request.get_json(force=True)
    except:
        abort(400)
    if not 'title' in blob:
        abort(400)
    task = {
        'id': tasks[-1]['id'] + 1,
        'title': blob['title'],
        'description': blob.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task})
1
domoarigato

JSON文字列の前後に「の代わりに」を置き、JSON文字列の内側に\を置きます。

0
Yuri