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

737

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

from flask import request

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

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

ddinchev
источник

Ответы:

1270

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

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

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

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

  • request.form['name']: используйте индексацию, если вы знаете, что ключ существует
  • request.form.get('name'): используйте, getесли ключ может не существовать
  • request.form.getlist('name'): используйте, getlistесли ключ отправляется несколько раз, и вам нужен список значений. getвозвращает только первое значение.
Роберт
источник
205

Чтобы получить необработанные данные, используйте request.data. Это работает, только если он не может быть проанализирован как данные формы, иначе он будет пустым и request.formбудет иметь проанализированные данные.

from flask import request
request.data
clyfish
источник
179

Для параметров запроса URL используйте 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, размещенного с типом контента application/json, используйте request.get_json().

data = request.get_json()
Физер Хан
источник
98

Вот пример анализа опубликованных данных JSON и их повторного отображения.

from flask import Flask, request, jsonify

app = Flask(__name__)

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

Чтобы опубликовать JSON с curl:

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

Или использовать Почтальон:

используя почтальон для публикации JSON

Литл Ройс
источник
36

Если вы публикуете JSON с типом контента application/json, используйте его, request.get_json()чтобы получить его во Flask. Если тип содержимого не правильный, Noneвозвращается. Если данные не в формате JSON, возникает ошибка.

@app.route("/something", methods=["POST"])
def do_something():
    data = request.get_json()
Амит Карник
источник
31

Чтобы получить необработанное тело сообщения независимо от типа содержимого, используйте request.get_data(). Если вы используете request.data, он вызывает request.get_data(parse_form_data=True), который заполнит request.form MultiDictи оставит dataпустым.

Xiao
источник
19

Чтобы получить request.formкак обычный словарь, используйте request.form.to_dict(flat=False).

Чтобы вернуть данные JSON для API, передайте их jsonify .

Этот пример возвращает данные формы в виде данных JSON.

@app.route('/form_to_json', methods=['POST'])
def form_to_json():
    data = request.form.to_dict(flat=False)
    return jsonify(data)

Вот пример данных формы POST с curl, возвращающимся как JSON:

$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
  "name": "ivanleoncz", 
  "role": "Software Developer"
}
ivanleoncz
источник
12

Используйте request.get_json()для публикации данных JSON.

data = request.get_json()
name = data.get('name', '')

Используется request.formдля получения данных при отправке формы методом POST.

name = request.form.get('name', '')

Используется request.argsдля получения данных, переданных в строке запроса URL-адреса, как при отправке формы методом GET.

request.args.get("name", "")

request.formи т. д. похожи на dict, используйте getметод для получения значения по умолчанию, если оно не было передано.

Равин Гупта
источник
10

Чтобы опубликовать JSON без application/jsonтипа контента, используйте request.get_json(force=True).

@app.route('/process_data', methods=['POST'])
def process_data():
    req_data = request.get_json(force=True)
    language = req_data['language']
    return 'The language value is: {}'.format(language)
Тарик Фойница
источник
10

Необработанные данные передаются в приложение Flask с сервера WSGI как request.stream. Длина потока указана в Content-Lengthзаголовке.

length = request.headers["Content-Length"]
data = request.stream.read(length)

Обычно безопаснее использовать request.get_data()вместо этого.

Даниил
источник
9

Чтобы опубликовать JSON с jQuery в JavaScript, используйте JSON.stringifyдля сброса данных и установите тип содержимого на application/json.

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

$.ajax({
    type: 'POST',
    url: '/process',
    data: JSON.stringify(value_data),
    contentType: 'application/json',
    success: function (response_data) {
        alert("success");
    }   
});

Разобрать его во Flask с request.get_json().

data = request.get_json()
Вайшали Чаудхари
источник
8

Для разбора JSON используйте request.get_json().

@app.route("/something", methods=["POST"])
def do_something():
    result = handle(request.get_json())
    return jsonify(data=result)
zhangqy
источник
5

Вот пример размещения данных формы для добавления пользователя в базу данных. Проверьте, request.method == "POST"чтобы проверить, была ли отправлена ​​форма. Используйте ключи от, request.formчтобы получить данные формы. Визуализируйте HTML-шаблон с помощью <form>иного. Поля в форме должны иметь nameатрибуты, соответствующие ключам в request.form.

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route("/user/add", methods=["GET", "POST"])
def add_user():
    if request.method == "POST":
        user = User(
            username=request.form["username"],
            email=request.form["email"],
        )
        db.session.add(user)
        db.session.commit()
        return redirect(url_for("index"))

    return render_template("add_user.html")
<form method="post">
    <label for="username">Username</label>
    <input type="text" name="username" id="username">
    <label for="email">Email</label>
    <input type="email" name="email" id="email">
    <input type="submit">
</form>
Dulangi_Kanchana
источник
4

Если тип содержимого распознается как данные формы, он request.dataбудет проанализирован вrequest.form и вернет пустую строку.

Чтобы получить необработанные данные независимо от типа контента, позвоните request.get_data(). request.dataзвонки get_data(parse_form_data=True), в то время как по умолчанию, Falseесли вы звоните прямо.

Zavec
источник
4

Если тело распознается как данные формы, оно будет в request.form. Если это JSON, он будет в request.get_json(). В противном случае исходные данные будут в request.data. Если вы не уверены, как будут представлены данные, вы можете использовать orцепочку, чтобы получить первую с данными.

def get_request_data():
    return (
        request.args
        or request.form
        or request.get_json(force=True, silent=True)
        or request.data
    )

request.argsсодержит аргументы, проанализированные из строки запроса, независимо от того, что было в теле, так что вы удалили бы это из, get_request_data()если и оно, и тело должны передавать данные одновременно.

Пол Гоудер
источник
2

При публикации данных формы в форме HTML убедитесь, что inputтеги имеют nameатрибуты, иначе они не будут присутствовать в request.form.

@app.route('/', methods=['GET', 'POST'])
def index():
    print(request.form)
    return """
<form method="post">
    <input type="text">
    <input type="text" id="txt2">
    <input type="text" name="txt3" id="txt3">  
    <input type="submit">
</form>
"""
ImmutableMultiDict([('txt3', 'text 3')])

Только txt3вход имел name, так что это единственный ключ, присутствующий в request.form.

замороженная
источник