Подтвердить что ты не робот

Колба разбитая труба с запросами

Я хочу отправить локальный запрос REST в флеш-приложение, например:

from flask import Flask, url_for, request
import requests

app = Flask(__name__)

@app.route("/<name>/hi", methods=["POST"])
def hi_person(name):
    form = {"name": name}
    return requests.post(url_for("hi", _external=True), data=form)

@app.route("/hi", methods=["POST"])
def hi():
    return 'Hi, %s!' % request.form["name"]

Отправка curl -X POST http://localhost:5000/john/hi приводит к зависанию приложения всей флэшки. Когда я посылаю сигнал об ударе, я получаю сообщение об ошибке сбойной трубы. Есть ли способ предотвратить замораживание колбы?

4b9b3361

Ответ 1

Запустите ваше приложение фляги на соответствующем сервере WSGI, способном обрабатывать параллельные запросы (возможно, gunicorn или uWSGI), и это будет работать. Во время разработки включите потоки на сервере, поставляемом Flask, с помощью:

app.run(threaded=True)

но учтите, что сервер Flask не рекомендуется для производственного использования. Начиная с Flask 1.0, threaded включен по умолчанию, и вы действительно хотите использовать команду flask в командной строке для запуска приложения.

Случается, что при использовании запросов вы делаете второй запрос к вашему приложению-колбе, но поскольку он все еще занят обработкой первого, он не будет отвечать на этот второй запрос, пока не выполнит этот первый запрос.

Кстати, в Python 3 реализация socketserver обрабатывает разъединение более изящно и продолжает обслуживать, а не аварийно завершать работу.

Ответ 2

Здесь есть несколько вещей, и я постараюсь обратиться к ним один раз в день.

Во-первых, вы, вероятно, используете сервер разработки игрушек. Этот сервер имеет множество ограничений; главным образом среди этих ограничений, состоит в том, что он может обрабатывать только один запрос за раз. Когда вы создаете второй запрос во время вашего первого запроса, вы блокируете свое приложение: функция requests.post() ожидает, пока Flask ответит, но сама фляжка ждет возврата post()! Решение этой конкретной проблемы заключается в том, чтобы запустить приложение WSGI в многопоточной или многопроцессорной среде. Я предпочитаю http://twistedmatrix.com/trac/wiki/TwistedWeb, но есть несколько других опций.

С этим в сторону... Это антипаттерн. Вы почти наверняка не хотите вызывать все накладные расходы HTTP-запроса, чтобы разделить некоторые функции между двумя представлениями. Правильная вещь - реорганизовать, чтобы иметь отдельную функцию, которая выполняет эту совместную работу. Я не могу реорганизовать ваш конкретный пример, потому что то, что у вас есть, очень простое и на самом деле даже не заслуживает двух видов. Что именно вы хотели построить?

Изменить: комментарий спрашивает, будет ли многопоточный режим на сервере игрушек stdlib достаточным для предотвращения возникновения тупика. Я скажу "может быть". Да, если нет каких-либо зависимостей, позволяющих обеим потокам добиться прогресса, и оба потока достигнут достаточного прогресса для завершения своих сетевых задач, то запросы будут выполнены правильно. Тем не менее, определение того, будут ли два потока взаимоблокировать друг друга, неразрешимы (доказательство опущено как тупое), и я не хочу точно сказать, что сервер stdlib может сделать это правильно.

Ответ 3

Ошибка, вызвавшая сбой, была исправлена ​​в версии 0.12, выпущена 21 декабря 2016 года. Да! Это важное решение, которое многие ждали.

Из журнала изменений флагов:

  • Отмените изменение поведения, которое привело к сбою сервера dev вместо возврата внутренней ошибки сервера (запрос на переноС# 2006).

Ответ 4

У меня была такая же проблема с методом записи, в общем, мой пост метод ничего не делал, вот почему возникли эти проблемы

return _socket.socket.send(self._sock, data, flags) urllib3.exceptions.ProtocolError:
('Connection aborted.', BrokenPipeError(32, 'Broken pipe'))

if request.method == 'POST':
    print(len(request.data))
return 'dummy'

это print сделал свое дело