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

Я хочу получать данные, отправленные в мое приложение 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, который касается получения необработанных данных, а не проанализированных данных.

26 ответов

Решение

Документы описывают атрибуты, доступные по запросу. В большинстве распространенных случаев 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 если ключи перекрываются

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

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

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

Для параметра 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')

Для типа данных application/json используйте request.data

# data in string format and you have to parse into dictionary
data = request.data
dataDict = json.loads(data)
from flask import request
request.data

Я привожу полный пример приложения / 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)

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

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

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

PS Для примера параметра URL Query вы можете увидеть мой ответ в разделе Несколько параметров в приложении Flask.

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

У Flask есть еще один ярлык для JSON:

Заголовок:

{Content-Type: application/json}

@app.route("/something", methods=["POST"])
def do_something():
    data = request.get_json()

С помощью 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. request.formдля данных формы это включает данные формы и файла,
  2. request.jsonа также request.get_jsonдля данных JSON
  3. request.headersдля заголовков
  4. request.argsчтобы получить параметры запроса

Кроме того, они все как словарь, но тогда они не словари, поэтому лучше не делать request.form['name']и вместо этого сделать request.form.get('name').

from flask import request

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

получить данные, если запрос типа JSON, и вы также можете упомянуть параметры по умолчанию вместе с ним

from flask import request

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

получить данные, если форма запроса

from flask import request

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

получить параметры из URL с помощью запроса GET

Запрос на импорт:

      from flask import request

Параметры URL-запроса:

      name = request.args.get("name")
age = request.args.get("age")

Ввод формы:

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

ИЛИ (используйте индексацию, если знаете, что ключ существует, укажите имя полей ввода )

      name = request.form['name']
age = request.form['age']

Данные JSON (для типа контента application / json)

      data = request.get_json()
@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)

В JavaScript:

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

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

В питоне:

client_data = request.get_data()

Вот пример публикации данных формы для добавления пользователя в базу данных. Проверьте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>
len = request.headers["Content-Length"]
data=request.stream.read()

Теперь данные - это тело запроса

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

@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~~

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

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 dump, и объединяю все разногласия. затем это может быть зарегистрировано, возвращено в функции представления, что угодно, и вы можете фактически увидеть весь запрос, независимо от того, что он включает.

Моя проблема была похожей. Я получил payload POST-запрос, когда пользователь щелкнул buttonиз моего слэк-бота. В Content-Type было application/x-www-form-urlencoded. Я использовал Flask, Python3.

Я попробовал это решение, но оно не сработало

@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)

Мое решение 1 было:

from urllib.parse import parse_qs
# Some code
@ app.route('/slack/request_handler', methods=['POST'])
def request_handler():    
    # request.get_data() returned a bytestring
    # parse_qs() returned a dict from a bytestring. This dict has 1 pair
    # I tried payload_dict.keys() to see what keys in the dict and it had one key only
    payload_dict = parse_qs(request.get_data())

    # Get the value of the key from payload_dict
    # Value of the key from payload_dict is an array, length = 1
    payload_dict_value_arr = payload_dict[b'payload']

    # Get data from the index[0] of the array payload_dict_value_arr
    data = payload_dict_value_arr[0]   

    # convert a string (representation of a Dict)) to a Dict
    # Note that if you have single quotes as a part of your keys or values this will
    # fail due to improper character replacement.
    # This solution is only recommended if you have a strong aversion 
    # to the eval solution.
    datajson = json.loads(data)

    # get value of key "channel"
    channel = datajson["channel"]
    print(channel) {'id': 'D01ACC2E8S3', 'name': 'directmessage'}

Мое решение 2, немного короче:

@ app.route('/slack/request_handler', methods=['POST'])
def request_handler():
   payload = request.form  # return an ImmutableMultiDict with 1 pair

   a1 = payload['payload']  # get value of key 'payload'

   # Note that if you have single quotes as a part of your keys or values this will
   # fail due to improper character replacement.
   # convert a string (representation of a Dict)) to a Dict
   a2 = json.loads(a1)

   # get value of key "channel"
   channel = a2["channel"] 
   print(channel) # {'id': 'D01ACC2E8S3', 'name': 'directmessage'}

flask.Request.get_data, Юникод в Flask

Если тип пантомимы распознан, то оба request.data а также request.get_data() вернет пустые строки.

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

См. http://flask.pocoo.org/docs/1.0/api/.

@app.route('/addData', methods=['POST'])
def add_data():
     data_in = mongo.db.Data
     id = request.values.get("id")
     name = request.values.get("name")
     newuser = {'id' : id, 'name' : name}
     if voter.find({'id' : id, 'name' : name}).count() > 0:
            return "Data Exists"
     else:
            data_in.insert(newuser)
            return "Data Added"

Для таких как я, кто забыл (немного) о 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')])

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

Чтобы получить данные формы, попробуйте следующее. Объект запроса позволяет нам получить доступ к данным, полученным из запроса. это также может помочь нам получить доступ к другой информации о запросе. Надеюсь, это поможет. :)

      from flask import Flask, request


app = Flask(__name__)

@app.get('/')
def index():
  json_data = request.get_json() #this will get the json data and return a dictionary containing the data sent
  
  form_data = request.form #this will get the form data return a dictionary of the data submitted in a form


  #such can be accessed in the following way
   username = json_data.get('username')
   email = form_data.get('email') # this will be value from the email input
  ....

Попробуй это

       json_data = request.form or request.get_json()
 data = dict(json_data)

Он соберет форму и данные JSON и преобразует их в словарь.

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})

Я просто столкнулся с такой же необходимостью. Я должен сохранить информацию на случай любой неожиданной ситуации. Итак, я использую следующую формулу:

      Info = "%s/%s/%s" % (request.remote_addr, repr(request), repr(session))

repr(request) даст строковое представление основной информации. Вы можете добавить данные пользовательского агента с помощью:request.headers.get('User-Agent')

Я также сохраняю континент сеанса, так как он может содержать ценную информацию.

Попробуйте ->

      from flask import request

@app.route('/', methods=['GET', 'POST'])
def parse_request():
    if request.method == 'POST':
       data = request.form.get('data')
request.data

Это удобно использовать, но помните, что он поступает в виде строки и требует повторения.

Другие вопросы по тегам