Escribe y responde mensajes de Pub/Sub

ID de región

REGION_ID es un código abreviado que Google asigna en función de la región que seleccionas cuando creas la app. El código no corresponde a un país ni a una provincia, aunque algunos ID de región puedan parecer similares a los códigos de país y provincia que se suelen usar. En el caso de las apps creadas después de febrero de 2020, REGION_ID.r se incluye en las URL de App Engine. En el caso de las apps existentes creadas antes de esta fecha, el ID de región es opcional en la URL.

Obtén más información acerca de los ID de región.

Pub/Sub proporciona mensajería asíncrona, confiable y de varios a varios entre aplicaciones. Las aplicaciones de publicador pueden enviar mensajes a un tema, y otras aplicaciones pueden suscribirse a ese tema para recibir los mensajes.

En este documento, se describe cómo usar la biblioteca cliente de Cloud para enviar y recibir mensajes de Pub/Sub en una app de Python.

Requisitos previos

  • Sigue las instrucciones que se proporcionan en “Hello, World!” para Python en App Engine a fin de configurar el entorno y el proyecto, y entender cómo se estructuran las apps de Python en App Engine.
  • Anota y guarda el ID del proyecto porque lo necesitarás para ejecutar la aplicación de muestra que se describe en este documento.

    Clona la app de muestra

    Copia las apps de muestra en tu máquina local y navega hasta el directorio pubsub:

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples
    cd python-docs-samples/appengine/flexible/pubsub
    

    Crea un tema y una suscripción

    Crea un tema y una suscripción, lo que incluye especificar el extremo al que el servidor Pub/Sub debe enviar solicitudes:

    gcloud pubsub topics create YOUR_TOPIC_NAME
    gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
        --topic YOUR_TOPIC_NAME \
        --push-endpoint \
        https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/pubsub/push?token=YOUR_TOKEN \
        --ack-deadline 10
    

    Reemplaza YOUR_TOKEN con un token secreto aleatorio. El extremo lo utiliza para verificar las solicitudes.

    Configura variables de entorno

    Edita el archivo app.yaml a fin de establecer las variables de entorno para el ID del proyecto, el tema y el token de verificación:

    env_variables:
        PUBSUB_TOPIC: your-topic
        # This token is used to verify that requests originate from your
        # application. It can be any sufficiently random string.
        PUBSUB_VERIFICATION_TOKEN: 1234abc

    Revisión de código

    La app de muestra usa las bibliotecas cliente de Cloud.

    La app de muestra usa los valores que estableces en el archivo app.yaml para configurar las variables de entorno. El controlador de las solicitudes push usa estos valores para confirmar que la solicitud provenga de Pub/Sub y que se origine en una fuente confiable:

    app.config['PUBSUB_VERIFICATION_TOKEN'] = \
        os.environ['PUBSUB_VERIFICATION_TOKEN']
    app.config['PUBSUB_TOPIC'] = os.environ['PUBSUB_TOPIC']
    

    La app de muestra mantiene una lista global a fin de almacenar los mensajes que recibe esta instancia:

    MESSAGES = []
    
    El método pubsub_push() recibe mensajes enviados y los agrega a la lista global MESSAGES:

    @app.route('/pubsub/push', methods=['POST'])
    def pubsub_push():
        if (request.args.get('token', '') !=
                current_app.config['PUBSUB_VERIFICATION_TOKEN']):
            return 'Invalid request', 400
    
        envelope = json.loads(request.data.decode('utf-8'))
        payload = base64.b64decode(envelope['message']['data'])
    
        MESSAGES.append(payload)
    
        # Returning any 2xx status indicates successful receipt of the message.
        return 'OK', 200

    El método index() interactúa con la app web de App Engine para publicar mensajes nuevos y mostrar los mensajes recibidos:

    @app.route('/', methods=['GET', 'POST'])
    def index():
        if request.method == 'GET':
            return render_template('index.html', messages=MESSAGES)
    
        data = request.form.get('payload', 'Example payload').encode('utf-8')
    
        # publisher = pubsub_v1.PublisherClient()
        topic_path = publisher.topic_path(
            current_app.config['PROJECT'],
            current_app.config['PUBSUB_TOPIC'])
    
        publisher.publish(topic_path, data=data)
    
        return 'OK', 200

    Ejecuta la muestra de forma local

    En la ejecución local, puedes usar la CLI de Cloud para proporcionar autenticación a fin de emplear las API de Google Cloud. Si configuraste tu entorno como se describe en Requisitos, ya ejecutaste el comando gcloud init que proporciona esta autenticación.

    Instala dependencias; es preferible hacerlo en un entorno virtual.

    macOS/Linux

    1. Crea un entorno aislado de Python:
      python3 -m venv env
      source env/bin/activate
    2. Si no estás en el directorio que contiene el código de muestra, navega al directorio que contiene el código de muestra hello_world. Luego, instala las dependencias:
      cd YOUR_SAMPLE_CODE_DIR
      pip install -r requirements.txt

    Windows

    Usa PowerShell para ejecutar tus paquetes de Python.

    1. Ubica la instalación de PowerShell.
    2. Haz clic derecho en el acceso directo a PowerShell y, luego, inícialo como administrador.
    3. Crea un entorno de Python aislado.
      python -m venv env
      .\env\Scripts\activate
    4. Navegue al directorio del proyecto e instale las dependencias. Si no estás en el directorio que contiene el código de muestra, navega al directorio que contiene el código de muestra hello_world. Luego, instala las dependencias:
      cd YOUR_SAMPLE_CODE_DIR
      pip install -r requirements.txt

    A continuación, configura las variables de entorno antes de iniciar la aplicación:

    export GOOGLE_CLOUD_PROJECT=[your-project-id]
    export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
    export PUBSUB_TOPIC=[your-topic]
    python main.py
    

    Simular notificaciones push

    La aplicación puede enviar mensajes de forma local, pero no puede recibir mensajes push localmente. Sin embargo, puedes simular un mensaje push; para ello, envía una solicitud HTTP al extremo de notificación push local. La muestra incluye el archivo sample_message.json.

    Puedes usar curl o un cliente httpie para enviar una solicitud HTTP POST:

    curl -i --data @sample_message.json "localhost:8080/push-handlers/receive_messages?token=[your-token]"
    

    O

    http POST ":8080/push-handlers/receive_messages?token=[your-token]" < sample_message.json
    

    Respuesta:

    HTTP/1.0 200 OK
    Content-Length: 2
    Content-Type: text/html; charset=utf-8
    Date: Mon, 10 Aug 2015 17:52:03 GMT
    Server: Werkzeug/0.10.4 Python/2.7.10
    
    OK
    

    Una vez completada la solicitud, puedes actualizar localhost:8080 y ver el mensaje en la lista de mensajes recibidos.

    Ejecuta en App Engine

    Para implementar la app de demostración en App Engine mediante la herramienta de línea de comandos de gcloud, debes ejecutar el siguiente comando desde el directorio en el que se encuentra el archivo app.yaml:

    gcloud app deploy
    

    Ahora puedes acceder a la aplicación en https://PROJECT_ID.REGION_ID.r.appspot.com. Puedes usar el formulario para enviar mensajes, pero no hay forma de garantizar qué instancia de tu aplicación recibirá la notificación. Puedes enviar varios mensajes y actualizar la página para ver el mensaje recibido.