POSTed JSON Flask'ta nasıl edinilir?


326

Şimdi bazı POSTed JSON okumak istiyorum Flask kullanarak basit bir API oluşturmaya çalışıyorum. POST'u Postman Chrome uzantısıyla yapıyorum ve JSON I POST basitçe {"text":"lalala"}. Aşağıdaki yöntemi kullanarak JSON okumaya çalışın:

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

Tarayıcıda, GET'e koyduğum UUID'yi doğru bir şekilde döndürüyor, ancak konsolda, sadece yazdırıyor None(yazdırmayı beklediğim {"text":"lalala"}yer.) Flask yönteminden gönderilen JSON'u nasıl alabileceğimi bilen var mı?

Yanıtlar:


428

Her şeyden önce, .jsonöznitelik, request.get_json()yöntemiNone burada temsil eden ve burada neden gördüğünüzü belgeleyen bir özelliktir .

Sen istek içerik türünü ayarlamanız gerekir application/jsoniçin .jsonmülkiyet ve .get_json()ya üretecek şekilde çalışmaya (argüman olmadan) yöntemiyle Noneaksi. Flask Requestbelgelerine bakın :

Eğer mimetype JSON'u ( uygulama / json , bkz. is_json()) Gösteriyorsa , bu çözümlenmiş JSON verilerini içerecektir , aksi takdirde olacaktır None.

Anahtar kelime bağımsız değişkenini request.get_json()ileterek içerik türü gereksinimini atlamayı söyleyebilirsiniz force=True.

Bu noktada bir istisna ortaya çıkarsa (muhtemelen 400 Hatalı İstek yanıtıyla sonuçlanırsa), JSON verilerinizin geçersiz olduğunu unutmayın. Bir şekilde bozuktur; bir JSON doğrulayıcıyla kontrol etmek isteyebilirsiniz.


Bu noktada bir istisna ortaya çıktığında bunun 500 Dahili Hata yanıtıyla sonuçlanması gerektiğini düşündüm , değil mi?
iBug

100

Referans olarak, bir Python istemcisinden json'un nasıl gönderileceği ile ilgili tam kod:

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

"Json =" girişi, burada tartışıldığı gibi içerik türünü otomatik olarak ayarlayacaktır: Python İsteklerini kullanarak JSON yayınlayın

Ve yukarıdaki istemci bu sunucu tarafı koduyla çalışacaktır:

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

Bunu yapmamın yolu bu olmalı ve

@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

İle silent=Trueseti, get_jsonjson naaşı teslim almak çalışırken işlev sessizce başarısız olur. Varsayılan olarak bu, olarak ayarlanır False. Her zaman bir json gövdesi bekliyorsanız (isteğe bağlı olarak değil), olarak bırakın silent=False.

Ayar force=True, request.headers.get('Content-Type') == 'application/json'şişenin sizin için yaptığı kontrolü yoksayar . Varsayılan olarak bu da olarak ayarlanır False.

Şişe belgelerine bakın .

Ayrılmanızı force=Falseve istemcinin Content-Typedaha açık hale getirmek için başlığı göndermesini şiddetle tavsiye ederim .

Bu yardımcı olur umarım!


2
Json gövdesinin isteğe bağlı olup olmadığına bağlıdır, bu nedenle durumunuza bağlıdır
radtek

2
Bazı durumlarda geçerli json ve diğer zamanlarda geçersiz json göndermek mantıklı olurdu hiçbir durumda göremiyorum. İki farklı bitiş noktası gibi geliyor
vidstige

1
Dediğim gibi, bir uç nokta "isteğe bağlı" json gövdesi alırsa kullanabilirsiniz silent=True. Evet bu mümkün ve bunu kullanıyorum. Gerçekten, API'nızı tüketilmek üzere nasıl tasarladığınıza bağlıdır. Bitiş noktanız için böyle bir durum yoksa, kaldırın silent=Trueveya açıkça ayarlayın False.
radtek

Açıklık olması açısından, print(content)after content = request.get_json()nesnesini yazdırır ... ancak geçerli bir Python nesnesi olarak (ve geçerli bir JSON nesnesi olarak değil). Örneğin, JSON kesinlikle tek tırnak kullanır, JSON kesinlikle her iki anahtar değer (dize) için dize değeri olarak çift tırnak gerektirir. JSON temsilini istiyorsanız json.dumps(), nesneyle birlikte kullanın .
Jochem Schulenklopper

24

application/jsonİçerik türüyle geçerli bir JSON yayınladığınızı varsayarsak request.json, ayrıştırılmış JSON verilerine sahip olacaksınız.

from flask import Flask, request, jsonify

app = Flask(__name__)


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

3
Bu cevaba eklemek için bu uç noktaya gönderebileceğiniz istek olabilir response = request.post('http://127.0.0.1:5000/hello', json={"foo": "bar"}). Bu çalışmasını takiben response.json()dönmelidir{'foo': 'bar'}
ScottMcC

Yine de {'foo': 'bar'}geçerli bir JSON olmadığı belirtilebilir . JSON'a çok benzeyen geçerli bir Python nesne temsili olabilir, ancak geçerli JSON kesinlikle çift tırnak kullanır.
Jochem Schulenklopper

İstek @JochemSchulenklopper get_json()yöntem deşifre gelen JSON Python nesnelerine, evet. Nerede geçerli bir JSON belgesi oluşturmasını bekliyorsunuz?
Martijn Pieters

@MartijnPieters, sadece en az iki kez beni ısırdı bir tuhaflık hakkında bir açıklama yapıyordum :-) Ama evet, normalde Python dict değil, geçerli bir JSON nesne temsili çağırmak .json()veya .get_json()döndürmek için bir işlev bekliyorum . Sadece isme bakıyorum ve bundan ne çıkabileceğini çıkarıyorum.
Jochem Schulenklopper

5

Sayıları ajax çağrısından olanlar için, tam bir örnek:

Ajax çağrısı: Buradaki anahtar a dictve ardındanJSON.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",
    });

Ve sunucu tarafında:

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
Benim için işe yarayan şey bu, çok teşekkürler! :)
vjjj

1

Başka bir yaklaşım vermek.

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

Geçerli bir JSON gönderdiğinizi varsayarsak,

@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

Force parametresini kullanmaya çalışın ...

request.get_json(force = True)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.