Rectangle 27 6

-d '{"Hello":"Karl"}' doesn't work from windows as its surrounded by single quotes. Use double quotes around and it will work for you.

-d "{\"Hello\":\"Karl\"}"

thank you! been expecting the problem to be god knows where, instead of using goodle with "curl json windows". again thx

python - Flask RESTful POST JSON fails - Stack Overflow

python json rest curl flask
Rectangle 27 2

Returning JSON, not str

It looks like your API routes are returning raw string casted versions of the resource objects. You instead want to return them as JSON, which flask can do for you with the jsonify method.

import flask

class New_Customer(Resource):
    def put(self):
        q = PHQuery()
        data = request.get_json()
        new_cust = q.create_cust(data)
        return flask.jsonify(new_cust)

Notice how in Python, the string representation of a native dictionary is not exactly equivalent to the JSON version:

>>> dct = {'Hey': 'some value'}
>>> print(dct)
{'Hey': 'some value'}
>>> print(json.dumps(dct))
{"Hey": "some value"}

When using the requests library to send a PUT/POST request, you are by default sending the body of the request in a form-encoded (application/x-www-form-urlencoded to be specific) format, which is explained here. This format is not great for nested structured data like what you are attempting to send. Instead, you can send the data JSON encoded (application/json) using the json keyword argument.

requests.put(url, json=data2)

Side note: If you are attempting to create a new customer, you may want to use POST instead as it may be considered more RESTful, as PUTs are generally for updating an existing resource, but this is up to you.

Since we are sending the body of the request as JSON now, we need to deserialize it as such in the API server. You can see this happening above in the following line:

data = request.get_json()

You can refer to this answer for more information about properly pulling data out of a HTTP request in Flask.

I tired that, in fact I even commented out the return line all together. I am still getting the same error. It seems like the problem is here put('localhost:5000/newcustomer';, data={'data':data2}) I HAVE UPDATED THE CODE:

@eleazarolivera When you call .json() on the requests Response object, it attempts to convert response.content into JSON, which would fail if the response was not valid JSON. Your server is likely returning an error string, in a 500 response, due to the put method signature.

the server is responding 500

>>> put('localhost:5000/newcustomer';, data={'data':data2}) returns : <Response [500]> AND >>> put('localhost:5000/newcustomer';, data={'data':data2}).json() returns: return self.scan_once(s, idx=_w(s, idx).end()) simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0) >>>

@eleazarolivera See my updates about the put method on your New_Customer resource class.

python - FLASK Restful API not able to add using PUT - Stack Overflow

python flask request put flask-restful
Rectangle 27 2

Just passing a content-type header of JSON doesn't actually make the data itself into JSON. You either need to do that yourself, or tell jQuery to do so.

$.ajax({
    url: 'http://127.0.0.1:5000/api/saveannotation',
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify({'sess_id' : $('#sessionid_area').val(),
        'annotations': JSON.parse(annotations)}),
    success: function(data) { alert(data.status); }
});

Now your data will be in JSON format and you can get it as a Python dict with request.get_json().

python - Flask receiving Post Json - Stack Overflow

python json flask
Rectangle 27 16

You are sending your data encoded as query string instead of JSON. Flask is capable of processing JSON encoded data, so it makes more sense to send it like that. Here's what you need to do on the client side:

$.ajax({
    type: 'POST',
    // Provide correct Content-Type, so that Flask will know how to process it.
    contentType: 'application/json',
    // Encode your data as JSON.
    data: JSON.stringify(post_obj),
    // This is the type of data you're expecting back from the server.
    dataType: 'json',
    url: '/some/url',
    success: function (e) {
        console.log(e);
    }
});

On the server side data is accessed via request.json (already decoded):

content = request.json['content']

python - How to post data structure like json to flask? - Stack Overfl...

python json post flask
Rectangle 27 196

You need to set the request content type to application/json for the .json property to work; it'll be None otherwise. See the Flask Request documentation:

If the mimetype is application/json this will contain the parsed JSON data. Otherwise this will be None.

Flask 0.10 added the request.get_json() method, and you should use that method instead of the .json property. You can tell the method to skip the content type requirement by setting force=True.

Note that if an exception is raised at this point (possibly resulting in a 400 Bad Request response), your JSON data is invalid. It is in some way malformed; you may want to check it with a JSON validator.

Alright. And would you have any idea how to do that?

requests
request.post(url, headers={'Content-Type': 'application/json'}, data=json.dumps({'text': 'lalala'})

Ah, now I understand. I had to set it at the sending party (i.e.: in PostMan). Okay, so I set that to json, but request.json is still a NoneType. ANy idea what else I could do wrong?

@kramer65: See the source code; Either the Content-Type header is wrong, or the JSON you sent was 'null', which translates to None. Everything else raises an exception or returns your dictionary. Try request.get_json(force=True); this will ignore the header requirement.

Okay! "I" fixed it! Using get_json(force=True) fixed it, but you were right all along; I set the content type in PostMan to JSON, but I didn't specifically set a header. So I now set the header and it all works fine. Thanks for the awesome help!

python - How to get POSTed json in Flask? - Stack Overflow

python json post flask
Rectangle 27 191

You need to set the request content type to application/json for the .json property to work; it'll be None otherwise. See the Flask Request documentation:

If the mimetype is application/json this will contain the parsed JSON data. Otherwise this will be None.

Flask 0.10 added the request.get_json() method, and you should use that method instead of the .json property. You can tell the method to skip the content type requirement by setting force=True.

Note that if an exception is raised at this point (possibly resulting in a 400 Bad Request response), your JSON data is invalid. It is in some way malformed; you may want to check it with a JSON validator.

Alright. And would you have any idea how to do that?

requests
request.post(url, headers={'Content-Type': 'application/json'}, data=json.dumps({'text': 'lalala'})

Ah, now I understand. I had to set it at the sending party (i.e.: in PostMan). Okay, so I set that to json, but request.json is still a NoneType. ANy idea what else I could do wrong?

@kramer65: See the source code; Either the Content-Type header is wrong, or the JSON you sent was 'null', which translates to None. Everything else raises an exception or returns your dictionary. Try request.get_json(force=True); this will ignore the header requirement.

Okay! "I" fixed it! Using get_json(force=True) fixed it, but you were right all along; I set the content type in PostMan to JSON, but I didn't specifically set a header. So I now set the header and it all works fine. Thanks for the awesome help!

python - How to get POSTed json in Flask? - Stack Overflow

python json post flask
Rectangle 27 9

Thanks to Audrius's comments I tracked a possible source of the problem to the interaction between uWSGI and nginx: apparently, if you receive POST data in a request you must read it before returning a response.

@app.route('/jsonpost', methods=['GET', 'POST'])
def json_post():
    if request.method == 'POST':
        dummy = request.form
    resp = make_response('{"test": "ok"}')
    resp.headers['Content-Type'] = "application/json"
    return resp
--post-buffering 1

I still don't understand why the problem does not present itself with Content-Type set to "text/html"

"if you POST, you must read the data". you my friend are a legend. apologies for posting this, but it has cost me several hours!!!!! +1 thanks bah humbug!!

python - No response with POST request and Content-Type "application/j...

python json post http-headers flask
Rectangle 27 26

This is the way I would do it and it should be

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.get_json(silent=True)
    print content
    return uuid

With silent=True set, the get_json function will fail silently when trying to retrieve the json body. By default this is set to False. Setting force=True will ignore the request.headers.get('Content-Type') == 'application/json' check that flask does for you. By default this is also set to False. See flask documentation.

I would strongly recommend leaving force=False and make the client send the Content-Type header to make it more explicit.

Depends if the json body is optional or not, so depends on your case

I cannot see any case where it would make sense to some times post valid json and other times invalid json. Sounds like two different end points

Like I said, if an endpoint takes "optional" json body, you can use silent=True. Yes this is possible, and I do use it. Its really based on how you design your API to be consumed. If there is no case like that for your endpoint, just remove silent=True or explicitly set it to False.

python - How to get POSTed json in Flask? - Stack Overflow

python json post flask
Rectangle 27 24

This is the way I would do it and it should be

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.get_json(silent=True)
    print content
    return uuid

With silent=True set, the get_json function will fail silently when trying to retrieve the json body. By default this is set to False. Setting force=True will ignore the request.headers.get('Content-Type') == 'application/json' check that flask does for you. By default this is also set to False. See flask documentation.

I would strongly recommend leaving force=False and make the client send the Content-Type header to make it more explicit.

Depends if the json body is optional or not, so depends on your case

I cannot see any case where it would make sense to some times post valid json and other times invalid json. Sounds like two different end points

Like I said, if an endpoint takes "optional" json body, you can use silent=True. Yes this is possible, and I do use it. Its really based on how you design your API to be consumed. If there is no case like that for your endpoint, just remove silent=True or explicitly set it to False.

python - How to get POSTed json in Flask? - Stack Overflow

python json post flask
Rectangle 27 23

import requests
res = requests.post('http://localhost:5000/api/add_message/1234', json={"mytext":"lalala"})
if res.ok:
    print res.json()

The "json=" input will automatically set the content-type, as discussed here: Post JSON using Python Requests

And the above client will work with this server-side code:

from flask import Flask, request, jsonify
app = Flask(__name__)

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print content['mytext']
    return jsonify({"uuid":uuid})

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

This actually didn't work for me. With python 2.7 if I specify the <uuid> argument the request gets denied with a 404. This is when sending a valid JSON POST with both Postman and a ReactJS application. If I omit the arg it works just fine.

This example definitely works with Python 2.7. Make sure you actually have the "<" and ">" in the app.route. The left/right carets are part of the required Flask syntax.

Yes, it does work. I was burying my request details in the JSON payload, not in the URI (as in: no arg supplied). Sorry for the static!

python - How to get POSTed json in Flask? - Stack Overflow

python json post flask
Rectangle 27 22

import requests
res = requests.post('http://localhost:5000/api/add_message/1234', json={"mytext":"lalala"})
if res.ok:
    print res.json()

The "json=" input will automatically set the content-type, as discussed here: Post JSON using Python Requests

And the above client will work with this server-side code:

from flask import Flask, request, jsonify
app = Flask(__name__)

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print content['mytext']
    return jsonify({"uuid":uuid})

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

This actually didn't work for me. With python 2.7 if I specify the <uuid> argument the request gets denied with a 404. This is when sending a valid JSON POST with both Postman and a ReactJS application. If I omit the arg it works just fine.

This example definitely works with Python 2.7. Make sure you actually have the "<" and ">" in the app.route. The left/right carets are part of the required Flask syntax.

Yes, it does work. I was burying my request details in the JSON payload, not in the URI (as in: no arg supplied). Sorry for the static!

python - How to get POSTed json in Flask? - Stack Overflow

python json post flask
Rectangle 27 34

request.args
request.form
application/x-www-form-urlencoded
multipart/form-data

When you use application/json, you are no longer POSTing form data. Use request.get_json() to access JSON POST data instead:

@app.route('/testpoint', methods = ['POST'])
def testpoint():
    name = request.get_json().get('name', '')
    return jsonify(name = name)

python - Flask request.args vs request.form - Stack Overflow

python rest curl post flask
Rectangle 27 32

request.args
request.form
application/x-www-form-urlencoded
multipart/form-data

When you use application/json, you are no longer POSTing form data. Use request.get_json() to access JSON POST data instead:

@app.route('/testpoint', methods = ['POST'])
def testpoint():
    name = request.get_json().get('name', '')
    return jsonify(name = name)

python - Flask request.args vs request.form - Stack Overflow

python rest curl post flask
Rectangle 27 2

If you inspect the POST being submitted by jQuery, you will most likely see that content is actually being passed as content[]. To access it from the Flask's request object, you would then need to use request.form.getlist('content[]').

If you would prefer to have it passed through as content, you can add traditional: true to your $.ajax() call.

More details about this can be found in the 'data' and 'traditional' sections of http://api.jquery.com/jQuery.ajax/.

when i set traditional: true to $.ajax. i received a string like [object Object] in server... but it's not what i want :(

Different server side technologies handle that differently. You may want to check out the answer about JSON provided by Audrius.

python - How to post data structure like json to flask? - Stack Overfl...

python json post flask
Rectangle 27 13

I just had this issue, and I think a few of you might be able to benefit from my solution. I created a WSGI middleware class that saves the raw POST body from the socket. I saved the value in the WSGI variable 'environ' so I could refer to it as request.environ['body_copy'] within my Flask app.

You need to be careful that the post data is not too large, or you might have memory issues on your server.

class WSGICopyBody(object):
    def __init__(self, application):
        self.application = application

    def __call__(self, environ, start_response):

        from cStringIO import StringIO
        length = environ.get('CONTENT_LENGTH', '0')
        length = 0 if length == '' else int(length)

        body = environ['wsgi.input'].read(length)
        environ['body_copy'] = body
        environ['wsgi.input'] = StringIO(body)

        # Call the wrapped application
        app_iter = self.application(environ, 
                                    self._sr_callback(start_response))

        # Return modified response
        return app_iter

    def _sr_callback(self, start_response):
        def callback(status, headers, exc_info=None):

            # Call upstream start_response
            start_response(status, headers, exc_info)
        return callback

app.wsgi_app = WSGICopyBody(app.wsgi_app)

request.environ['body_copy'] # This is the raw post body you can use in your flask app

This is only a good solution if you can't control the Content-Type header of the client. If you can change that, then the answer below is infinitely easier and simpler.

I'm working with a misbehaving client. (I have no control over the client.) Client sending Content-Type: application/x-www-form-urlencoded but the payload is raw XML. Flask is decoding it as a form but giving the key as '<?xml version'. This solution works for me to get the data without Flask trying to parse it.

Unfortunately Bottle consumes request stream and there is no concrete api to fix this unless you touch the source code. This is why I personally switched to Falcon.

Get raw POST body in Python Flask regardless of Content-Type header - ...

python flask
Rectangle 27 16

Parameters in a URL (e.g. key=listOfUsers/user1) are GET parameters and you shouldn't be using them for POST requests. A quick explanation of the difference between GET and POST can be found here.

In your case, to make use of REST principles, you should probably have:

http://ip:5000/users
http://ip:5000/users/<user_id>

Then, on each URL, you can define the behaviour of different HTTP methods (GET, POST, PUT, DELETE). For example, on /users/<user_id>, you want the following:

GET /users/<user_id> - return the information for <user_id>
POST /users/<user_id> - modify/update the information for <user_id> by providing the data
PUT - I will omit this for now as it is similar enough to `POST` at this level of depth
DELETE /users/<user_id> - delete user with ID <user_id>

So, in your example, you want do a POST to /users/user_1 with the POST data being "John". Then the XPath expression or whatever other way you want to access your data should be hidden from the user and not tightly couple to the URL. This way, if you decide to change the way you store and access data, instead of all your URL's changing, you will simply have to change the code on the server-side.

Now, the answer to your question: Below is a basic semi-pseudocode of how you can achieve what I mentioned above:

@app.route('/users/<user_id>', methods = ['GET', 'POST', 'DELETE'])
def user(user_id):
    if request.method == 'GET':
        """return the information for <user_id>"""
        .
        .
        .
    if request.method == 'POST':
        """modify/update the information for <user_id>"""
        # you can use <user_id>, which is a str but could
        # changed to be int or whatever you want, along
        # with your lxml knowledge to make the required
        # changes
        data = request.form # a multidict containing POST data
        .
        .
        .
    if request.method == 'DELETE':
        """delete user with ID <user_id>"""
        .
        .
        .
else:
    # POST Error 405 Method Not Allowed
    .
    .
    .

There are a lot of other things to consider like the POST request content-type but I think what I've said so far should be a reasonable starting point. I know I haven't directly answered the exact question you were asking but I hope this helps you. I will make some edits/additions later as well.

Thanks and I hope this is helpful. Please do let me know if I have gotten something wrong.

do you have to do something special for the POST to get routed back correctly? I have /competitions/<int: id> set up but when the POST occurs, it posts to /competitions instead so my post handling logic is never reached.

python - Flask example with POST - Stack Overflow

python rest flask lxml
Rectangle 27 2

If an external application is stubbornly POST-ing with an alternative mime-type, you can force Flask to treat the data as JSON anyway by using the request.get_json() method instead, setting the force argument to True:

data = request.get_json(force=True)

Don't try to treat a JSON payload as form data, that'll never work.

python - Flask or Werkzeug/0.9.4 breaking POST data - Stack Overflow

python json flask werkzeug flask-restful
Rectangle 27 4

You can use the builtin server during development, but you should use a full deployment option for production applications. (Do not use the builtin development server in production.)

As Marcus mentioned in the comments, another WSGI server like gunicorn or tornado would be much faster and more reliable, so definitely use one of those for deployment and benchmarking.

If you're worried about working quickly during development, you can use gunicorn in development just like you would in deployment. If you're deploying to heroku, for example, you can run "foreman start" and the gunicorn server will start right up.

python - Flask slow at retrieving post data from request? - Stack Over...

python json flask werkzeug
Rectangle 27 2

Your json data in curl is wrong, so Flask does not parse data to form.

'{"name":"Joe"}'
curl -X POST -d '{"name":"Joe"}' http://example.com:8080/testpoint --header "Content-Type:application/json"

The problem is that the OP is posting JSON in the first place.

python - Flask request.args vs request.form - Stack Overflow

python rest curl post flask
Rectangle 27 2

Your json data in curl is wrong, so Flask does not parse data to form.

'{"name":"Joe"}'
curl -X POST -d '{"name":"Joe"}' http://example.com:8080/testpoint --header "Content-Type:application/json"

The problem is that the OP is posting JSON in the first place.

python - Flask request.args vs request.form - Stack Overflow

python rest curl post flask