2013-11-15 2 views
139

Я пытаюсь создать простой API с помощью Flask, в котором теперь я хочу прочитать POSTed JSON. Я делаю сообщение с PostMan Chrome extension, а сообщение JSON I - это просто {"text":"lalala"}. Я стараюсь читать JSON, используя следующий метод:Как получить POSTed json в Flask?

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

В браузере это правильно возвращает UUID я помещал в ГЭТ, но на консоли, он просто печатает None (где я ожидаю его распечатать . {"text":"lalala"} кто-нибудь знает, как я могу получить размещенную JSON внутри методы Колбы

ответ

220

Вы должны установить тип содержимого запроса на application/json для .json собственности работать,? это будет None иначе См Flask Request documentation. :

Если mimetype равен application/json, это будет содержать проанализированные данные JSON. В противном случае это будет None.

Колба 0,10 добавили request.get_json() method, и вы должны использовать этот метод вместо .json свойства. Вы можете сообщить методу пропустить требование типа содержимого, установив force=True.

Обратите внимание, что если исключения поднимаются на данный момент (возможно, в результате чего в 400 Bad Request ответа), ваш JSON данные недействительно. Он каким-то образом искажен; вы можете проверить его с помощью проверки подлинности JSON.

+2

Хорошо. И у вас есть идея, как это сделать? – kramer65

+4

@ kramer65: Как вы отправляете запрос сейчас? Клиент должен установить заголовок; если вы используете 'запросы', это будет' 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, функция get_json не сможет бесшумно при попытке получить тело 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

Для справки, вот полный код, как отправить JSON от клиента Python:

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 с Postman и ReactJS-приложением. Если я опускаю arg, он работает отлично. – Omortis

+1

Этот пример определенно работает с Python 2.7. Убедитесь, что на самом деле у вас есть «<" and ">» в app.route. Левые/правые ролики являются частью требуемого синтаксиса Flask. – Luke

+0

Да, это действительно работает. Я собирал детали запроса в полезной нагрузке JSON, а не в URI (как в: без аргумента). Извините за статичность! – 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

Смежные вопросы