meaning python flask

python - meaning - Necesidad de ejecutar una función después de devolver la respuesta en Flask.



flask wikipedia (5)

No hay una forma nativa de matraz para lograr esto. after_request todavía se ejecutará antes de devolver la respuesta al cliente, no después.

Aquí hay una discusión del problema y algunas soluciones.

Solo para una solicitud, necesito ejecutar una función después de enviar la respuesta al cliente. Debido a que la función lleva tiempo y eso termina en el tiempo de espera de conexión. Socket error: [Errno 32] Broken pipe

¿Hay alguna forma en Flask para ejecutar la función después de devolver la solicitud?


Puede usar el decorador after_request o personalizarlo para crear una after_this_request que solo funciona para esa solicitud en particular.

Echa un vistazo a este fragmento de código http://flask.pocoo.org/snippets/53/


Puedes intentar usar el streaming. Vea el siguiente ejemplo:

import time from flask import Flask, Response app = Flask(__name__) @app.route(''/'') def main(): return ''''''<div>start</div> <script> var xhr = new XMLHttpRequest(); xhr.open(''GET'', ''/test'', true); xhr.onreadystatechange = function(e) { var div = document.createElement(''div''); div.innerHTML = '''' + this.readyState + '':'' + this.responseText; document.body.appendChild(div); }; xhr.send(); </script> '''''' @app.route(''/test'') def test(): def generate(): app.logger.info(''request started'') for i in range(5): time.sleep(1) yield str(i) app.logger.info(''request finished'') yield '''' return Response(generate(), mimetype=''text/plain'') if __name__ == ''__main__'': app.run(''0.0.0.0'', 8080, True)

Toda la magia en este ejemplo en genarator, donde puede iniciar los datos de respuesta, después de hacer algo de personal y generar datos vacíos para finalizar su flujo.

Para obtener más información, visite http://flask.pocoo.org/docs/patterns/streaming/ .


Una solución más general que la solución iterador de matraz es escribir un middleware WSGI que agregue una devolución de llamada al método de cierre de respuesta . Aquí utilizamos el ayudante ClosingIterator de ClosingIterator y una extensión de la aplicación de matraz para lograr esto:

import traceback from werkzeug.wsgi import ClosingIterator class AfterResponse: def __init__(self, app=None): self.callbacks = [] if app: self.init_app(app) def __call__(self, callback): self.callbacks.append(callback) return callback def init_app(self, app): # install extension app.after_response = self # install middleware app.wsgi_app = AfterResponseMiddleware(app.wsgi_app, self) def flush(self): for fn in self.callbacks: try: fn() except Exception: traceback.print_exc() class AfterResponseMiddleware: def __init__(self, application, after_response_ext): self.application = application self.after_response_ext = after_response_ext def __call__(self, environ, after_response): iterator = self.application(environ, after_response) try: return ClosingIterator(iterator, [self.after_response_ext.flush]) except Exception: traceback.print_exc() return iterator

Luego puedes usar tu decorador after_response esta manera:

import flask import time app = flask.Flask("after_response") AfterResponse(app) @app.after_response def after(): time.sleep(2) print("after_response") @app.route("/") def home(): return "Success!/n"

Cuando lo enrolle, verá que responde inmediatamente y se cierra, luego 2 segundos más tarde aparece el mensaje "después" en los registros:

127.0.0.1 - - [25/Jun/2018 15:41:51] "GET / HTTP/1.1" 200 - after_response

Esta respuesta se resume de mis respuestas here y here .


Voy a exponer mi solución.

Puede usar hilos para calcular cualquier cosa después de que se devuelva algo en su función llamado por una ruta de matraz.

import time from threading import Thread from flask import request, Flask app = Flask(__name__) class Compute(Thread): def __init__(self, request): Thread.__init__(self) self.request = request def run(self): print("start") time.sleep(5) print(self.request) print("done") @app.route(''/myfunc'', methods=["GET", "POST"]) def myfunc(): thread_a = Compute(request.__copy__()) thread_a.start() return "Processing in background", 200