2013-11-15 12 views
139

Sto provando a creare una semplice API utilizzando Flask, in cui ora desidero leggere alcuni JSON POSTed. Faccio il post con lo PostMan Chrome extension e il post JSON I è semplicemente {"text":"lalala"}. Cerco di leggere il JSON utilizzando il seguente metodo:Come ottenere POSTed json in Flask?

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

Nel browser restituisce correttamente l'uuid ho messo nel GET, ma sulla console, si limita a stampare fuori None (dove mi aspetto che stampare . il {"text":"lalala"} qualcuno sa come posso ottenere il JSON inviato dal all'interno del metodo Flask

risposta

220

è necessario impostare il tipo di richiesta di contenuti per application/json per la proprietà .json al lavoro;? sarà None altrimenti Vedere la Flask Request documentation. :

Se il tipo MIME è application/json, questo conterrà i dati JSON analizzati. Altrimenti sarà None.

Flask 0.10 aggiunto il request.get_json() method, e si dovrebbe utilizzare questo metodo al posto della proprietà .json. È possibile indicare al metodo di saltare il requisito relativo al tipo di contenuto impostando force=True.

Nota che se un'eccezioneè sollevata a questo punto (possono dare luogo a Bad risposta 400 Request), il vostro JSON dati non è valido. È in qualche modo malformato; potresti volerlo controllare con un validatore JSON.

+2

OK. E avresti qualche idea su come farlo? – kramer65

+4

@ kramer65: come stai postando la richiesta ora? Il client deve impostare l'intestazione; se stai usando 'requests', sarebbe' request.post (url, headers = {'Content-Type': 'application/json'}, data = json.dumps ({'text': 'lalala'}) '. –

+1

Ah, ora capisco. Ho dovuto impostarlo alla festa di invio (cioè in PostMan). Ok, l'ho impostato su json, ma 'request.json' è ancora un NoneType. Qualche altra idea che potrei fare di sbagliato? – kramer65

33

Questo è il modo in cui vorrei farlo e dovrebbe essere

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

Con silent=True set, la funzione get_json fallirà silenziosamente quando si cerca di recuperare il corpo JSON. Per impostazione predefinita questo è impostato su False. L'impostazione force=True ignorerà il controllo request.headers.get('Content-Type') == 'application/json' che il pallone fa per te. Di default questo è anche impostato su False. Vedi flask documentation.

Si consiglia vivamente di lasciare force=False e fare in modo che il client invii l'intestazione Content-Type per renderlo più esplicito.

Spero che questo aiuti!

+3

Non è meglio fallire sugli errori ?? – vidstige

+0

Dipende se il corpo di JSON è facoltativo o meno, quindi dipende dal tuo caso – radtek

+1

Non riesco a vedere alcun caso in cui avrebbe senso alcune volte post json valido e altre volte json non valido. Sembra due punti finali diversi – vidstige

31

Per riferimento, ecco il codice completo per come inviare JSON da un client Python:

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

Il "json =" input imposta automaticamente il tipo di contenuto, come discusso qui: Post JSON using Python Requests

e quanto sopra client funziona con questo codice lato server:

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) 
+0

Questo in realtà non ha funzionato per me. Con python 2.7 se si specifica l'argomento la richiesta viene negata con un 404. Questo è quando si invia un POST JSON valido sia con Postman sia con un'applicazione ReactJS. Se ometto l'arg, funziona bene. – Omortis

+1

Questo esempio funziona sicuramente con Python 2.7. Assicurati di avere effettivamente il "<" and ">" nell'app.route. I trattini sinistra/destra fanno parte della sintassi del pallone richiesta. – Luke

+0

Sì, funziona. Stavo seppellendo i dettagli della mia richiesta nel payload JSON, non nell'URI (come in: no arg fornito). Scusa per la statica! – Omortis

0

questa soluzione funziona:

from flask import Flask, request, jsonify 

app = Flask(__name__) 


@app.route('/hello', methods=['POST']) 
def hello(): 
    return jsonify(request.json) 
+1

Per aggiungere a questa risposta la richiesta che è possibile inviare a questo endpoint potrebbe essere 'response = request.post ('http://127.0.0.1:5000/hello', json = {" foo ":" bar "})' . Seguendo questo comando 'response.json()' dovrebbe restituire '{'foo': 'bar'}' – ScottMcC

Problemi correlati