Got Failed to decode JSON object when calling a POST request in flask python
Asked Answered
C

7

12

I have written a simple REST-ful web server in python with flask following steps in this tutorial; but I've got a problem calling POST request. The code is:

@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

I send a POST request using curl as the example in the above mentioned page:

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

But I get this error in response:

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>

I've tried to debug and I found out in the get_json method, the passed argument has been translated to '\\'{title:Read a book}\\'' as data and request_charset is None; but I have no idea for a solution. Any help?

EDIT 1:

I have tried @domoarrigato's answer and implemented the create_task method as the following:

@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

But this time I got the following error after calling POST via 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>

EDIT 2:

To clarify, I should mention that I'm working on a 64-bit version of Microsoft Windows 7 with Python version 2.7 and the latest version of Flask.

Congenital answered 30/5, 2016 at 10:30 Comment(0)
E
27

This works in 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

Back slashes and double quotes.

Efrenefron answered 25/11, 2016 at 13:56 Comment(3)
Worked for me! Using Windows 10 x64. Thank you!Middelburg
Thank you @dmitriy-bogdanov This worked for me in Windows 10 - 64bit version...Fleta
Using powershell you will need to use ` to escape the double quoteGenotype
H
4

I Managed to get it working using Anaconda cmd window, python3, using backslashes and double quotes around the whole expression! Works:

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

Does not work:

curl "localhost:5000/txion" -H "Content-Type: application/json" -d '{\"from\": \"akjflw\" ,\"`to\" : \"fjlakdj\", \"amount\": 4}'
Harber answered 9/8, 2018 at 15:40 Comment(0)
K
3

If you are using windows your json string in your request should look like:

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

I've got the same problem and it helped.

Kielty answered 28/5, 2017 at 22:54 Comment(1)
This is not a valid answer !Brisbane
F
1

Instead of using the request.json property, try using request.get_json(force=True) I would rewrite it:

@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})
Forethoughtful answered 30/5, 2016 at 10:42 Comment(1)
updated my answer - removed the , 201 in the return statement - i think you just need to return the serialized json.Forethoughtful
F
0

Just put " instead of ' around the JSON string, and \ before any " inside the JSON string.

Footpound answered 4/5, 2019 at 19:20 Comment(0)
G
0

If you're using powershell to use CURL, you need to use curl.exe specifically (not curl) add the 'dumb parsing' tag --%.

Then all you have to do is double quote it and escape the double quotes inside the JSON. Single quoting the outside doesn't appear to work.

"{\"title\":\"Read a book\"}"
Genotype answered 22/7, 2020 at 16:57 Comment(0)
H
-1
from flask import Flask, request, abort, jsonify

app = Flask(__name__)
tasks = [{'id': 0}]

@app.route('/todo/api/v1.0/tasks', methods=['POST'])
def create_task():
    if not request.json or 'title' not 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)
    response = {"task": task}
    return jsonify(response), 201

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

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

OP:

{
  "task": {
    "description": "", 
    "done": false, 
    "id": 1, 
    "title": "Read a book"
  }
}
Highup answered 30/5, 2016 at 11:47 Comment(5)
Your solution is totally identical to mine!Congenital
yea that's what! I was not able to reproduce the error!!Highup
@Amit Karnik This error comes when u run in windows because is is not able to understand that for what purpose that meta char ` " ` it has to use. So use ` \" ` instead of ` " ` will work perfectly.Rarefaction
everyone knows it... have anything diff??Highup
Tried this in linux running curl 7.68.0, does not work, still get same error.Elaterid

© 2022 - 2024 — McMap. All rights reserved.