Я хочу получить данные, отправленные в мое приложение 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, который заключается в получении необработанных данных, а не проанализированные данные.
Документы описывают атрибуты, доступные в запросе. В большинстве распространенных случаев request.data
будет пустым, поскольку он используется в качестве резервной копии:
request.data
Содержит входящие данные запроса как строку в случае, если он появился с типом mimetype, который не обрабатывает флажок.
request.args
: пары ключ/значение в строке запроса URLrequest.form
: пары ключ/значение в теле, из формы сообщения HTML или запрос JavaScript, который не кодируется JSONrequest.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
возвращает только первое значение.from flask import request
request.data
Это просто так:
Для параметра 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.datastrong >
# data in string format and you have to parse into dictionary
data = request.data
dataDict = json.loads(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-запроса вы можете увидеть мой ответ в нескольких параметрах в флажке
request.json
если вы все равно конвертируете его обратно с помощью json.dumps()
?
Флажок имеет еще один ярлык для JSON:
Заголовок:
{Content-Type: application/json}
@app.route("/something", methods=["POST"])
def do_something():
data = request.get_json()
если вы хотите, чтобы тело исходного сообщения было независимо от типа содержимого, вы должны использовать request.get_data()
, потому что request.form
преобразуется в формат werkzeug.ImmutableMultiDict
.
Проще говоря, вы можете получить данные ниже:
@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
~~
@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)
len = request.headers["Content-Length"]
data=request.stream.read()
Теперь данные являются телом запроса
length
len
.
Использование 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.
Если тип mime распознан, то как request.data
и request.get_data()
возвращают пустые строки.
Чтобы получить полное содержимое независимо, вам нужно вызвать request.get_data(as_text=True)
.
См. Http://flask.pocoo.org/docs/1.0/api/#flask.Request.get_data.
В 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()
Это своего рода грязный взлом, чтобы получить все данные запроса независимо от того, как он был отправлен, но я серьезно использую:
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. то это может быть зарегистрировано, возвращено в функции просмотра, независимо от того, и вы действительно можете увидеть весь запрос независимо от того, что он включает.
Для таких, как я, кто забыл (немного) о 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([])
!
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})
request.get_json()
.request.get_json(force=True)
. Из документации:force – if set to True the mimetype is ignored.
, поэтому он не вернетNone
для запросов, для которых не указаноapplication/json
в заголовкеcontentType
.