फ्लास्क में पोस्टेड JSON कैसे प्राप्त करें?


326

मैं फ्लास्क का उपयोग करके एक साधारण एपीआई बनाने की कोशिश कर रहा हूं, जिसमें मैं अब कुछ पोस्ट किए गए JSON को पढ़ना चाहता हूं। मैं पोस्टमैन क्रोम एक्सटेंशन के साथ POST करता हूं, और JSON I POST बस है {"text":"lalala"}। मैं निम्नलिखित विधि का उपयोग करके JSON पढ़ने की कोशिश करता हूं:

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

ब्राउज़र पर यह सही ढंग से UUID I GET में देता है, लेकिन कंसोल पर, यह बस प्रिंट करता है None(जहां मैं उम्मीद करता हूं कि यह प्रिंट आउट होगा {"text":"lalala"}। क्या किसी को पता है कि मैं फ्लास्क विधि से पोस्ट किए गए JSON को कैसे प्राप्त कर सकता हूं?

जवाबों:


427

सबसे पहले, .jsonविशेषता एक संपत्ति है जो request.get_json()विधि को सौंपती है , जो दस्तावेजों को आप Noneयहां देखते हैं।

आपको संपत्ति और विधि के application/jsonलिए अनुरोध सामग्री प्रकार सेट करने की आवश्यकता है (कोई तर्क के साथ) काम करने के लिए या तो अन्यथा उत्पादन होगा । फ्लास्क प्रलेखन देखें :.json.get_json()NoneRequest

इसमें पार्स किया गया JSON डेटा होगा यदि mimetype JSON ( एप्लिकेशन / json , देखें is_json()) को इंगित करता है , अन्यथा यह होगा None

आप कीवर्ड तर्क request.get_json()को पास करके सामग्री प्रकार की आवश्यकता को छोड़ना बता सकते हैं force=True

ध्यान दें कि यदि इस बिंदु पर एक अपवाद उठाया गया है (संभवतः 400 खराब अनुरोध प्रतिक्रिया के परिणामस्वरूप), तो आपका JSON डेटा अमान्य है। यह किसी तरह से विकृत है; आप इसे JSON सत्यापनकर्ता के साथ जांचना चाह सकते हैं।


मैंने सोचा कि जब इस बिंदु पर एक अपवाद उठाया जाता है, तो यह 500 आंतरिक त्रुटि प्रतिक्रिया में अधिक संभावित परिणाम होना चाहिए, है न?
iBug

100

संदर्भ के लिए, पायथन क्लाइंट से json भेजने के तरीके के लिए यहां पूरा कोड:

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

"Json =" इनपुट स्वचालित रूप से सामग्री-प्रकार सेट करेगा, जैसा कि यहाँ पर चर्चा की गई है: पायथन अनुरोधों का उपयोग करते हुए पोस्ट JSON

और उपरोक्त क्लाइंट इस सर्वर-साइड कोड के साथ काम करेगा:

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)

71

यह तरीका है कि मैं इसे करूंगा और यह होना चाहिए

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

silent=Trueसेट के साथ , get_jsonसमारोह चुपचाप विफल हो जाएगा जब जसन बॉडी को पुनः प्राप्त करने की कोशिश की जाएगी। डिफ़ॉल्ट रूप से यह करने के लिए सेट है False। यदि आप हमेशा एक जैसन बॉडी की उम्मीद कर रहे हैं (वैकल्पिक रूप से नहीं), तो इसे छोड़ दें silent=False

सेटिंग force=Trueउस request.headers.get('Content-Type') == 'application/json'चेक को अनदेखा कर देगी जो फ्लास्क आपके लिए करता है। डिफ़ॉल्ट रूप से यह भी सेट है False

फ्लास्क प्रलेखन देखें ।

मैं दृढ़ता से छोड़ने की सिफारिश करूंगा force=Falseऔर ग्राहक Content-Typeको अधिक स्पष्ट बनाने के लिए हेडर भेजूंगा ।

उम्मीद है की यह मदद करेगा!


2
निर्भर करता है कि क्या
जैसन

2
मैं ऐसा कोई मामला नहीं देख सकता जहाँ यह कुछ समय के लिए वैध जोंस और अन्य समय में अमान्य जोंस के लिए समझ में आता हो। दो अलग अंत बिंदुओं की तरह लगता है
vidstige

1
जैसा कि मैंने कहा, अगर कोई समापन बिंदु "वैकल्पिक" json बॉडी लेता है, तो आप उपयोग कर सकते हैं silent=True। हां यह संभव है, और मैं इसका उपयोग करता हूं। यह वास्तव में इस बात पर आधारित है कि आप अपने एपीआई का उपभोग कैसे करते हैं। यदि आपके एंडपॉइंट के लिए ऐसा कोई मामला नहीं है, तो बस निकालें silent=Trueया स्पष्ट रूप से इसे सेट करें False
राडेक 18

स्पष्टता के लिए, वस्तु के प्रिंट के print(content)बाद content = request.get_json()... लेकिन एक वैध पायथन ऑब्जेक्ट के रूप में (और एक वैध JSON ऑब्जेक्ट के रूप में नहीं)। उदाहरण के लिए, यह एकल उद्धरणों का उपयोग करता है जबकि JSON को कड़े मूल्यों के रूप में दोनों प्रमुख मूल्यों (स्ट्रिंग्स) के लिए दोहरे उद्धरण चिह्नों की आवश्यकता होती है। यदि आप JSON प्रतिनिधित्व चाहते हैं, json.dumps()तो ऑब्जेक्ट के साथ उपयोग करें ।
जोकेम शुल्नेक्लोपर

24

मान लें कि आपने JSON को application/jsonसामग्री प्रकार के साथ पोस्ट किया है , request.jsonतो पार्स किया गया JSON डेटा होगा।

from flask import Flask, request, jsonify

app = Flask(__name__)


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

3
इस उत्तर को जोड़ने के लिए आप इस अंतिम बिंदु पर भेज सकते हैं response = request.post('http://127.0.0.1:5000/hello', json={"foo": "bar"})। इस रनिंग के बाद response.json()वापसी होनी चाहिए{'foo': 'bar'}
ScottMcC

यह ध्यान दिया जा सकता है कि {'foo': 'bar'}मान्य JSON नहीं है। यह वैध पायथन ऑब्जेक्ट प्रतिनिधित्व हो सकता है जो JSON की तरह दिखता है, लेकिन वैध JSON सख्ती से दोहरे उद्धरण चिह्नों का उपयोग करता है।
जोकेम शुल्नेक्लोपर 12-1218

@JochemSchulenklopper अनुरोध get_json()विधि JSON से पायथन ऑब्जेक्ट्स के लिए डिकोड करता है , हाँ। जहाँ आप यह उम्मीद कर रहे हैं कि यह वैध JSON डॉक्यूमेंट तैयार करेगा?
मार्टिन पीटर्स

@MartijnPieters, मैं सिर्फ एक विशेष लक्षण है कि मुझे कम से कम दो बार थोड़ा :-) लेकिन हाँ, सामान्य रूप से मैं एक समारोह कहा जाता है की उम्मीद के बारे में एक बयान कर रहा था .json()या .get_json()एक मान्य JSON वस्तु प्रतिनिधित्व, नहीं एक अजगर dict वापस जाने के लिए। मैं सिर्फ नाम देख रहा हूं, और यह पता लगा सकता हूं कि इसमें से क्या निकल सकता है।
जोकेम शुल्नेक्लोपर

5

उन सभी के लिए जिनका मुद्दा अजाक्स कॉल से था, यहाँ एक पूर्ण उदाहरण है:

अजाक्स कॉल: यहाँ कुंजी एक dictऔर फिर का उपयोग करने के लिए हैJSON.stringify

    var dict = {username : "username" , password:"password"};

    $.ajax({
        type: "POST", 
        url: "http://127.0.0.1:5000/", //localhost Flask
        data : JSON.stringify(dict),
        contentType: "application/json",
    });

और सर्वर साइड पर:

from flask import Flask
from flask import request
import json

app = Flask(__name__)

@app.route("/",  methods = ['POST'])
def hello():
    print(request.get_json())
    return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 

if __name__ == "__main__":
    app.run()

1
यह वह चीज है जिसने मेरे लिए काम किया, बहुत बहुत धन्यवाद! :)
vjjj

1

एक और दृष्टिकोण देने के लिए।

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

@app.route('/service', methods=['POST'])
def service():
    data = json.loads(request.data)
    text = data.get("text",None)
    if text is None:
        return jsonify({"message":"text not found"})
    else:
        return jsonify(data)

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

0

यह मानते हुए कि आपने वैध JSON पोस्ट किया है,

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

0

बल पैरामीटर का उपयोग करने का प्रयास करें ...

request.get_json(force = True)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.