2013-11-15 22 views
139

我正在嘗試使用Flask構建一個簡單的API,其中我現在想讀取一些POST JSON。我做了PostMan Chrome extension的帖子,JSON我的帖子只是{"text":"lalala"}。我嘗試使用以下方法來讀取JSON:如何在Flask中獲取發佈的json?

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

在它正確返回我放在GET的uuid的瀏覽器,但在控制檯上,它只是打印出None(在這裏我希望它打印出來。在{"text":"lalala"}是否有人知道我可以從燒瓶方法中得到張貼JSON

回答

220

您需要請求的內容類型設置爲application/json.json物業的工作;這將是None否則見Flask Request documentation。 :

如果mimetype是application/json,它將包含解析的JSON數據。否則,這將是None

Flask 0.10添加了request.get_json() method,您應該使用該方法而不是.json屬性。您可以通過設置force=True來告訴方法跳過內容類型要求。

注意的是,如果例外在這一點上升(可能導致400錯誤的請求響應),您的JSON 數據是無效的。它在某種程度上是畸形的;你可能想用JSON驗證器來檢查它。

+2

好的。你會有任何想法如何做到這一點? – kramer65

+4

@ kramer65:你現在怎麼發佈請求?客戶端必須設置標題;如果你使用'request',那就是'request.post(url,headers = {'Content-Type':'application/json'},data = json.dumps({'text':'lalala'} )'。 –

+1

啊,現在我明白了。我必須在發送方設置它(即:在PostMan中)。好的,所以我將它設置爲json,但'request.json'仍然是一個NoneType。任何想法我還能做什麼錯? – kramer65

33

這是我會做的方式,它應該是

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

隨着silent=True集,試圖取回JSON體時get_json功能將靜默失敗。默認情況下,它被設置爲False。設置force=True將忽略燒瓶爲您做的request.headers.get('Content-Type') == 'application/json'檢查。默認情況下,這也設置爲False。見flask documentation

我強烈建議離開force=False,並讓客戶端發送Content-Type標題,以使其更加明確。

希望這會有所幫助!

+3

錯誤失敗不是更好嗎? – vidstige

+0

取決於json主體是否可選,所以取決於你的情況 – radtek

+1

我看不到任何情況下,有時會發布有效的json和其他時間無效的json。聽起來像兩個不同的終點 – vidstige

31

爲了參考,以下是如何從一個Python客戶端發送JSON完整代碼:

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

的「JSON =」輸入將自動設定內容類型,如這裏討論:Post JSON using Python Requests

和上面的客戶端將與此服務器端代碼工作:

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

這實際上並不適用於我。如果使用python 2.7指定參數,則請求會被404拒絕。這是在發送有效的JSON POST和Postman和ReactJS應用程序時。如果我省略了參數,它就可以正常工作。 – Omortis

+1

這個例子絕對適用於Python 2.7。確保你實際上在app.route中有「<" and ">」。左/右括號是所需Flask語法的一部分。 – Luke

+0

是的,它確實有效。我正在將我的請求詳細信息埋入JSON有效內容中,而不是在URI中(如在:no arg provided中)。對不起靜態! – Omortis

0

此解決方案:

from flask import Flask, request, jsonify 

app = Flask(__name__) 


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

要添加到此答案,您可以發送到此端點的請求可能是'response = request.post('http://127.0.0.1:5000/hello',json = {「foo」:「bar」})'' 。在這個運行之後,response.json()應該返回'{'foo':'bar'}' – ScottMcC