Сбой запроса Flask (400) при изменении * другой * конечной точки

#python #reactjs #flask

#python #reactjs #flask

Вопрос:

У меня это приложение работало нормально, а затем я начал перерабатывать свой класс обработчика redis, и я получаю ошибку 400 в моем клиенте React с моей robot конечной точки, когда я вношу изменения в свою state конечную точку.

У меня есть очень простой API для robot/start/ и robot/stop/ конечных точек:

 def create_robot_api(api: Api, db: AsyncGetSetDatabase):
    robot_endpoint = api.namespace('robot')

    robot_model = api.model('Start/Stop', { 'counter': fields.Integer })

    def set_counter(action):
        counter = request.get_json()['counter']
        run(db.set_and_publish(f'{action}_request_counter', counter))
        return {'message': f'{action} request counter set to {counter}'}, 200
        
    @robot_endpoint.route('/start/')
    class StartRobot(Resource):
        @robot_endpoint.expect(robot_model, validate=True)
        def post(self):
            return set_counter('start')

    @robot_endpoint.route('/stop/')
    class StopRobot(Resource):
        @robot_endpoint.expect(robot_model, validate=True)
        def post(self):
            return set_counter('stop')
  

Моя state конечная точка извлекает соответствующие фрагменты состояния из моей базы данных:

 def create_state_api(api: Api, db: AsyncGetSetDatabase):
    state_endpoint = api.namespace('state')

    @state_endpoint.route('/')
    class SystemState(Resource):
        def get(self):
            state = {}
            props = [ ... ]

            # this is old API and won't work.
            async def action(_db):
                for prop in props:
                    state[prop] = await _db.get(prop) or 0

            # run(db.execute(action))   # 1

            # return state              # 2 

            # THIS does the state correctly but causes post not to work!
            return run(db.get_keys(props)) #3
  

Мое приложение React вызывает get /state/ при запуске и имеет кнопку, которая вызывает post /robot/start/ (а также некоторые кнопки get /config/ и post /config/ , которые оба работают нормально)

Когда строки 1 и 2 раскомментированы, и я обновляю приложение React, state сама конечная точка вызывает ошибку в Flask — TypeError, что имеет смысл, потому что db на самом деле имеет новый API, который учитывает строка 3, — а также ошибку CORS в Chrome:

Доступ к XMLHttpRequest в ‘http://localhost:5000/state /’ из источника ‘http://localhost:3000 ‘ заблокирован политикой CORS: заголовок ‘Access-Control-Allow-Origin’ отсутствует в запрошенном ресурсе.

Если я прокомментирую строки 1 и 2 и раскомментирую строку 3, state конечная точка возвращается так, как должна, работает абсолютно корректно. Однако затем, когда я нажимаю кнопку запуска моего пользовательского интерфейса для post robot/start/ m, я получаю сообщение об ошибке:

СООБЩЕНИЕ http://localhost:5000/robot/start / 400 (НЕВЕРНЫЙ ЗАПРОС)

Также странно, что вызов post /start/ из моего пользовательского интерфейса Swagger не вызывает проблем. Это только из приложения React. FWIW, вывод Flask всегда показывает OPTIONS и POST из React, в хороших и плохих случаях. Развязность всегда справедлива POST . Я также попытался удалить get /state/ из пользовательского интерфейса, затем загрузить пользовательский интерфейс, а затем вызвать get /state/ из Swagger: запуск / остановка в пользовательском интерфейсе в порядке.

Итак, похоже, что есть что-то в том, чтобы выполнить это get /state/ без ошибки, вызываемой из пользовательского интерфейса, которая вызывает это. Только в приложении React. Эта проблема возникает, даже если я заменяю всю get функцию state конечной точки на return {} . Я также пробовал, чтобы robot методы просто возвращали 200.

И я клянусь, что все это работало раньше. В моей оболочке redis было много изменений, но они не должны влиять на это!

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

1. вероятно, у меня это плохо получается, но вы пробовали использовать функцию try and catch вокруг нее и распечатать точное сообщение об ошибке, которое вызывает ответ 400?

2. Я думаю, что 400 означает, что он даже не попадает в мой код flask.