Écrire des messages Pub/Sub et y répondre

ID de la région

Le REGION_ID est un code abrégé que Google attribue en fonction de la région que vous sélectionnez lors de la création de votre application. Le code ne correspond pas à un pays ou une province, même si certains ID de région peuvent ressembler aux codes de pays et de province couramment utilisés. L'ajout de REGION_ID.r dans les URL App Engine est facultatif pour les applications existantes. Il sera bientôt obligatoire pour toutes les applications nouvelles.

Pour assurer une transition en douceur, nous mettons lentement à jour App Engine afin d'utiliser les ID de région. Si nous n'avons pas encore mis à jour votre projet Google Cloud, vous ne verrez pas d'ID de région pour votre application. Étant donné que l'ID est facultatif pour les applications existantes, vous n'avez pas besoin de mettre à jour les URL ni d'effectuer d'autres modifications une fois l'ID de région disponible pour vos applications existantes.

En savoir plus sur les ID de région

Pub/Sub fournit une messagerie asynchrone fiable de type "plusieurs à plusieurs" entre applications. Les applications de type "éditeur" peuvent envoyer des messages à un sujet et d'autres applications peuvent s'abonner à ce sujet pour recevoir les messages.

Ce document explique comment utiliser la bibliothèque cliente Cloud pour envoyer et recevoir des messages Pub/Sub dans une application Python.

Prérequis

  • Suivez les instructions de la section "Hello, World!" pour Python sur App Engine pour configurer votre environnement et votre projet, et pour comprendre la structure des applications Python dans App Engine.
  • Notez et enregistrez l'ID de votre projet. Vous en aurez besoin pour exécuter l'exemple d'application décrit dans ce document.

Cloner l'exemple d'application

Copiez les exemples d'applications sur votre ordinateur local, puis accédez au répertoire pubsub :

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

Créer un sujet et un abonnement

Créez un sujet et un abonnement, pour lesquels vous devez spécifier le point de terminaison auquel le serveur Pub/Sub doit envoyer des requêtes :

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

Remplacez YOUR_TOKEN par un jeton secret aléatoire. Le point de terminaison push l'utilise pour valider les requêtes.

Définir des variables d'environnement

Modifiez le fichier app.yaml afin de définir les variables d'environnement pour l'ID de projet, le sujet et le jeton de validation :

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

Révision de code

L'exemple d'application utilise les bibliothèques clientes Cloud.

L'exemple d'application utilise les valeurs que vous avez définies dans le fichier app.yaml pour configurer les variables d'environnement. Le gestionnaire de requêtes push utilise ces valeurs pour confirmer que la requête provient de Pub/Sub et qu'une source de confiance en est à l'origine :

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

L'exemple d'application gère une liste globale pour stocker les messages reçus par cette instance :

MESSAGES = []
La méthode pubsub_push() reçoit les messages envoyés et les ajoute à la liste globale 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

La méthode index() interagit avec l'application Web App Engine pour publier de nouveaux messages et afficher les messages reçus :

@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

Exécuter l'exemple en local

Lorsque vous exécutez l'exemple en local, vous pouvez utiliser le SDK Cloud pour fournir l'authentification permettant d'utiliser les API Google Cloud. Si vous avez configuré votre environnement conformément à la procédure décrite dans la section Prérequis, vous avez d'ores et déjà exécuté la commande gcloud init, qui permet de fournir ce type d'authentification.

Installez les dépendances, de préférence dans un environnement virtuel.

macOS/Linux

  1. Créez un environnement Python isolé dans un répertoire externe à votre projet et activez-le :
    python3 -m venv env
    source env/bin/activate
  2. Accédez au répertoire de votre projet et installez des dépendances :
    cd YOUR_PROJECT
    pip install  -r requirements.txt

Windows

Exécutez les packages Python à l'aide de PowerShell.

  1. Localisez votre installation de PowerShell.
  2. Cliquez avec le bouton droit sur le raccourci PowerShell et démarrez une session en tant qu'administrateur.
  3. Créez un environnement Python isolé dans un répertoire externe à votre projet et activez-le :
    python -m venv env
    env\Scripts\activate
  4. Accédez au répertoire de votre projet et installez les dépendances :
    cd YOUR_PROJECT
    pip install -r requirements.txt

Définissez ensuite les variables d'environnement avant de démarrer votre application :

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

Simuler des notifications push

L'application peut envoyer des messages en local, mais ne peut pas recevoir de messages push en local. Vous pouvez toutefois simuler un message push en adressant une requête HTTP au point de terminaison de notification push local. L'exemple inclut le fichier sample_message.json.

Vous pouvez utiliser curl ou un client httpie pour envoyer une requête HTTP POST :

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

Ou

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

Réponse :

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

Une fois la requête terminée, vous pouvez actualiser localhost:8080 et afficher le message dans la liste des messages reçus.

Exécuter sur App Engine

Pour déployer l'application de démonstration sur App Engine en utilisant l'outil de ligne de commande gcloud, exécutez la commande suivante à partir du répertoire où se trouve votre fichier app.yaml :

gcloud app deploy

Vous pouvez désormais accéder à l'application à l'adresse https://PROJECT_ID.REGION_ID.r.appspot.com. Vous pouvez utiliser le formulaire pour envoyer de messages (mais vous ne pourrez pas forcément savoir quelle instance de votre application recevra la notification). Vous pouvez envoyer plusieurs messages et actualiser la page pour afficher le message reçu.