Как получить данные, полученные в запросе Flask

428

Я хочу получить данные, отправленные в мое приложение Flask. Я попытался получить доступ к request.data, но это пустая строка. Как вы получаете доступ к данным запроса?

@app.route('/', methods=['GET', 'POST'])
def parse_request():
    data = request.data  # data is empty
    # need posted data here

Ответ на этот вопрос заставил меня спросить Получить необработанное тело POST в Python Flask независимо от заголовка Content-Type, который заключается в получении необработанных данных, а не проанализированные данные.

Теги:
flask

15 ответов

699
Лучший ответ

Документы описывают атрибуты, доступные в запросе. В большинстве распространенных случаев request.data будет пустым, поскольку он используется в качестве резервной копии:

request.data Содержит входящие данные запроса как строку в случае, если он появился с типом mimetype, который не обрабатывает флажок.

  • request.args: пары ключ/значение в строке запроса URL
  • request.form: пары ключ/значение в теле, из формы сообщения HTML или запрос JavaScript, который не кодируется JSON
  • request.files: файлы в теле, которые Flask хранятся отдельно от form. Формы HTML должны использовать enctype=multipart/form-data или файлы не будут загружены.
  • request.values: объединенные args и form, предпочитающие args если ключи перекрываются

Все это экземпляры MultiDict. Вы можете получить доступ к значениям, используя:

  • request.form['name']: используйте индексирование, если знаете ключ существует
  • request.form.get('name'): используйте get если ключ может не существовать
  • request.form.getlist('name'): используйте getlist если ключ отправляется несколько раз и вам нужен список значений. get возвращает только первое значение.
  • 142
    Примечание. Чтобы получить полезную нагрузку в формате JSON, вы можете использовать request.get_json() .
  • 26
    В дополнение к комментарию @ albert можно использовать request.get_json(force=True) . Из документации: force – if set to True the mimetype is ignored. , поэтому он не вернет None для запросов, для которых не указано application/json в заголовке contentType .
Показать ещё 5 комментариев
174
from flask import request
request.data
  • 13
    Для получения документации по этому вопросу см. Flask.pocoo.org/docs/quickstart/#accessing-request-data и flask.pocoo.org/docs/api/#incoming-request-data .
  • 3
    это работает, если вы указали contentType (например, 'Applications / JSON') в запросе
Показать ещё 1 комментарий
122

Это просто так:

Для параметра URL Query используйте request.args

search = request.args.get("search")
page = request.args.get("page")

Для ввода формы используйте request.form

email = request.form.get('email')
password = request.form.get('password')

Для приложения типа данных /json используйте request.data​​strong >

# data in string format and you have to parse into dictionary
data = request.data
dataDict = json.loads(data)
  • 37
    У Flask есть ярлык для JSON: request.get_json ()
  • 1
    если данные отправляются через POST, вы должны использовать request.form.get ('')
Показать ещё 1 комментарий
49

Я даю полный пример приложения /json:

from flask import Flask, abort, request 
import json

app = Flask(__name__)


@app.route('/foo', methods=['POST']) 
def foo():
    if not request.json:
        abort(400)
    print request.json
    return json.dumps(request.json)


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

использовать Почтальон для почтового запроса:

Изображение 2556

используйте команду curl:

curl -i -H "Content-Type: application/json" -X POST -d '{"userId":"1", "username": "fizz bizz"}' http://localhost:5000/foo

PS Для примера параметра URL-запроса вы можете увидеть мой ответ в нескольких параметрах в флажке

  • 0
    Зачем вам использовать request.json если вы все равно конвертируете его обратно с помощью json.dumps() ?
  • 2
    @ nyuszika7h, не для практического применения, а просто для показа результата.
25

Флажок имеет еще один ярлык для JSON:

Заголовок:

{Content-Type: application/json}

@app.route("/something", methods=["POST"])
def do_something():
    data = request.get_json()
  • 1
    Небольшое замечание: если конечная точка / что-то вызывается не в формате json, get_json () завершится ошибкой. Не забудьте обработать исключения.
17

если вы хотите, чтобы тело исходного сообщения было независимо от типа содержимого, вы должны использовать request.get_data(), потому что request.form преобразуется в формат werkzeug.ImmutableMultiDict.

7

Проще говоря, вы можете получить данные ниже:

@app.before_request
def before_request():
    g.data = request.get_json() or request.values

Теперь g.data является экземпляром werkzeug.ImmutableMultiDict. Затем вы можете использовать g.data, который может справиться с большинством ваших требований. Например, вы можете использовать его так:

@app.route("/something", methods=["POST"])
def do_something():
    result = handle(g.data)
    return jsonify(data=result)

Конечно, вы можете использовать blueprint вместо app ~~

6
@app.route('/', methods=['POST'])
def process_data():
    req_data = request.get_json(force=True) # force=True will make sure this works even if a client does not specify application/json
    language = req_data['language'] # or whatever key you have in your json

    return '''The language value is: {}'''.format(language)
  • 2
    Вы правы насчет документирования, я немного обновил свои комментарии. Почему мой ответ отличается от других? Просто потому, что дело доходит до сути. Я написал только то, что спросил ОП, и это работает без каких-либо дополнительных вопросов.
4
len = request.headers["Content-Length"]
data=request.stream.read()

Теперь данные являются телом запроса

  • 0
    Этот ответ хорош, но, пожалуйста, не используйте встроенные функции в качестве имен переменных, рассмотрите возможность изменения length len .
  • 0
    Спасибо за ваше предложение, я изменил его.
3

Использование request.form.

Вместо получения данных одной формы (request.form["field_name"]) вы можете получить все опубликованные данные, проанализировав ImmutableDict предоставленный объектом request.form, следующим образом:

Колба (маршрут)

@app.route('/data', methods=['POST'])                                           
def f_data():                                                                   
    if request.method == "POST":
        fields = [k for k in request.form]                                      
        values = [request.form[k] for k in request.form]
        data = dict(zip(fields, values))
    return jsonify(data) 

Ракушка

$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
  "name": "ivanleoncz", 
  "role": "Software Developer"
}

Для получения дополнительной информации, это Gist.

  • 1
    Я люблю это!
  • 0
    Спасибо :)! Я считаю, что это достаточно ясно, с некоторыми пониманиями и динамикой, для представления в виде JSON API (в зависимости от вашей необходимости) или наличия этого объекта для целей базы данных.
2

Если тип mime распознан, то как request.data и request.get_data() возвращают пустые строки.

Чтобы получить полное содержимое независимо, вам нужно вызвать request.get_data(as_text=True).

См. Http://flask.pocoo.org/docs/1.0/api/#flask.Request.get_data.

1

В javascript:

var value_data = [1,2,3,4];

$.ajax({
        type: 'POST',
        url: '/',
        data:JSON.stringify(value_data),
        success: function (response) {
            alert("Data added successfully");
         },    
});

В python:

client_data = request.get_data()
0

Это своего рода грязный взлом, чтобы получить все данные запроса независимо от того, как он был отправлен, но я серьезно использую:

def get_request_info():
    args = str(request.args)
    form = str(request.form)
    files = str(request.files)
    maybe_json = request.get_json(silent=True, cache=False)
    if maybe_json:
        thejson = json.dumps(maybe_json)
    else:
        thejson = "no json"
    return # whatever you want 

и тогда я просто возвращаю либо строку, которая объединяет их, либо, если я чувствую себя фантазией, я пропускаю строковые вызовы /json дамп и объединяю все dicts. то это может быть зарегистрировано, возвращено в функции просмотра, независимо от того, и вы действительно можете увидеть весь запрос независимо от того, что он включает.

0

Для таких, как я, кто забыл (немного) о HTML, убедитесь, что <input> в вашей <form> имеет атрибут name="" !

from flask import Flask, request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    print("Posted data : {}".format(request.form))

    return """
<form method="post">
    <input type="text">
    <input type="text" id="idtxt2">
    <input type="text" name="txt3" id="idtxt3">  
    <input type="submit" Value="Hopla!">
</form>
"""

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

Результат на консоли:

freezed@machine % python3 run.py
 * Serving Flask app "flaskstuff.views" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 268-634-781
127.0.0.1 - - [20/Aug/2018 16:52:59] "POST / HTTP/1.1" 200 -
Posted data : ImmutableMultiDict([('txt3', 'text 3')])

Нет атрибута name = нет данных в ImmutableMultiDict([]) !

0
from flask import Flask, request, jsonify

@app.route('/added', methods=['POST'])
def add():
    data = request.get_json(force=True)
    l = {'name': data['name']}
    lingual.append(l)

    return jsonify({'lang': lingual})
  • 0
    когда вы получаете необработанные данные методом post в колбе, используйте request.get_json (force = True)
  • 2
    Вы должны объяснить свой код и как он решает вопрос ОП.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню