Как получить доступ к данным POST в формате json в приложении Flask RESTful API

#python-3.x #python-requests #flask-restful

#python-3.x #python-запросы #flask-restful

Вопрос:

В настоящее время я застрял, пытаясь получить доступ к данным POST json в приложении flask RESTful API. Данные POST — это просто фрейм данных Pandas, преобразованный в объект json с помощью pandas.to_json() метода.

 import pandas as pd
from flask import Flask, request, jsonify
from flask_restful import Resource, Api


app = Flask(__name__)
api = Api(app)

# Creation Of Main Endpoint Classes
class Test(Resource):
    def post(self):

        # Get POST data as json amp; read it as a DataFrame
        new_x = request.get_json()

        current_data = pd.read_json(new_x)
        return {'message': 'POST data read successfully'}

# Addition of the Endpoint Classes As Endpoints For The RESTFul API
api.add_resource(Test, '/api/v1')


if __name__ == '__main__':
    app.run(debug=True)
  

После отправки запроса POST к этой тестовой конечной точке я получаю JSONDecodeError: Expecting value ошибку. Публикация создается с использованием библиотеки requests python в виде:

 import requests
new_json = df.to_json()
post_url = 'http://127.0.0.1:5000/api/v1'
post_r = requests.post(url=post_url, data=new_json_orient)
print(post_r.json())
  

Трассировка стека, похоже, указывает на то, что request.get_json() возвращает значение None с <class 'NoneType'> . В результате Pandas не может прочитать None. Pandas и мне не хватает местоположения данных POST.

 127.0.0.1 - - [08/Mar/2019 13:06:56] "POST /api/v1 HTTP/1.1" 500 -
Traceback (most recent call last):
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflaskapp.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflaskapp.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflask_restful__init__.py", line 273, in error_router
    return original_handler(e)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflaskapp.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflask_compat.py", line 34, in reraise
    raise value.with_traceback(tb)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflaskapp.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflaskapp.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflask_restful__init__.py", line 273, in error_router
    return original_handler(e)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflaskapp.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflask_compat.py", line 34, in reraise
    raise value.with_traceback(tb)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflaskapp.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflaskapp.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflask_restful__init__.py", line 480, in wrapper
    resp = resource(*args, **kwargs)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflaskviews.py", line 88, in view
    return self.dispatch_request(*args, **kwargs)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagesflask_restful__init__.py", line 595, in dispatch_request
    resp = meth(*args, **kwargs)
  File "C:Users..Documents..app.py", line 35, in post
    current_data = pd.read_json(new_x)
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagespandasiojsonjson.py", line 413, in read_json
    path_or_buf, encoding=encoding, compression=compression,
  File "C:Users..AppDataLocalContinuumanaconda3envs..libsite-packagespandasiocommon.py", line 232, in get_filepath_or_buffer
    raise ValueError(msg.format(_type=type(filepath_or_buffer)))
ValueError: Invalid file path or buffer object type: <class 'NoneType'>
  

Что я делаю не так? Как я могу получить доступ к данным POST new_json? Заранее спасибо.

Комментарии:

1. В какой момент вы получаете эту ошибку? При разборе ответа ( post_r.json() ) или преобразовании запроса в json ( request.get_json() )? Действительно, полная трассировка стека не оставила бы места для этого комментария.

2. @vahdet Я отредактирую вопрос с помощью трассировки. Я получаю это на request.get_json() .

Ответ №1:

Это, скорее всего, потому, что POST метод не содержит никакой информации о Content-Type нем.

  1. Если requests версия новее 2.4.2, вы можете использовать json вместо data для тела сообщения (смотрите подробности документа здесь). Это автоматически установит заголовок 'Content-Type': 'application/json' :
 post_r = requests.post(url=post_url, json=new_json_orient)
  
  1. Если используемые вами запросы старше, вы можете явно задать значение заголовка как:
 headers = {'Content-type': 'application/json'}
post_r = requests.post(url=post_url, data=new_json_orient, headers=headers)
  

P.S. Для получения дополнительной информации о Content-Type заголовке, о котором так много говорилось в этом сообщении, вот ссылка на MDN docs.

Комментарии:

1. Это работает! Переключение с data на json сделало свое дело. Я у тебя в долгу!