es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo obtener una respuesta en la devolución de llamada de suscripción de Google Pubsub en un servidor Flask para el streaming.

Me gustaría tener un flujo a través de un punto final de Flask, pero los eventos se envían dentro de la devolución de llamada del suscriptor a un tema (Google Cloud PubSub). Consulta el código a continuación:

def a_stream():
    topic_name = 'projects/{project_id}/topics/{topic}'.format(
        project_id=os.getenv('GOOGLE_CLOUD_PROJECT'),
        topic="topic",
    )
    subscription_name = 'projects/{project_id}/subscriptions/{sub}'.format(
        project_id=os.getenv('GOOGLE_CLOUD_PROJECT'),
        sub="topic", 
    )
    def callback(message):
        print("imprimir")
        yield "reducir a la mitad"
        message.ack()

with pubsub_v1.SubscriberClient() as subscriber:
    try:
        subscriber.create_subscription(
        name=subscription_name, topic=topic_name)
    except:
        #no hacer nada ya que el tema existe
        pasar
    future = subscriber.subscribe(subscription_name, callback=callback)             
    future.result()

@orders_bp.route("/aStream", methods=['GET'])
def get_order_status():
    return Response(stream_with_context(a_stream()),
                          mimetype="text/event-stream")

Si ejecuto el código tal como está, no sucede nada. Si elimino el “reducir a la mitad” en la devolución de llamada, entonces puedo ver la “impresión” en la consola. Parece que el problema tiene que ver con el retorno, ¿hay alguna manera fácil de solucionar esto?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, el problema está en la función de “yielding”. Según la documentación de Flask, las respuestas de transmisión (stream responses) deben ser iterables de BYTES o TEXT. Sin embargo, la declaración yield en la función callback está devolviendo un objeto de tipo string que no es ni una secuencia de bytes ni un objeto de texto.

    Para solucionar esto, puedes codificar el objeto string en bytes antes de devolverlo. Modifica la función callback para codificar el objeto string antes de usar el yield, de esta manera:

    def callback(message):
        print("print")
        yield "data: {}\n\n".format("yield").encode('utf-8')
        message.ack()
    

    Al agregar .encode('utf-8') al string devuelto, se convertirá en un objeto de bytes que Flask puede transmitir.

Comments are closed.