[Boto3 Adv-Cal DAY8]SQSでQueueを作成してメッセージを送ってみた

[Boto3 Adv-Cal DAY8]SQSでQueueを作成してメッセージを送ってみた

boto3 で楽しむ AWS PythonLife 一人AdventCalendarです。

boto3のドキュメントを通して、サービス別にどういった事が出来るのかを理解したり、管理コンソールを通さずにTerminalだけで完結できるように検証していくことが目的になります。

8日目はAmazon SQSで、Queueを作成してメッセージを送信し、送信されたメッセージを受け取るロジックに挑戦してみました。

目次

boto3を通してSQSで出来ること

ドキュメントは下記リンク先です。

ざっくりと以下のことができます。

  • Queueの操作(作成・削除)
  • Queueのステータス取得
  • Queueへのメッセージ操作(送信・削除)
  • QueueのURL取得

今回の操作

Queueを作成して、メッセージを送信後に受信します。

  1. Queueの作成
  2. Queueへメッセージの送信
  3. Queueへ送信されたメッセージの取得
% python main.py
Input Profile name [default]>></p>
<p>Input queue_name >>test_queue</p>
<p>Input message >>test_message
{'Messages': [{'Body': 'test_message',
               'MD5OfBody': 'f0b75976f003b4690235c35d3a5d41c4',
               'MessageId': '92df211c-3bc1-4070-bfb2-e43128918a43',
               'ReceiptHandle': 'AQEBMmhRGJDTN6eol1mkbNM3rY+FhN2mYsdT5VOKSIoh2O0zrQwTmKAdlPbVL/BeYM8tkFurE7/lbDD3kMtossly4T/WTa7PYM9cAPT+FMERTnQAjZFSm+pQtvcV7Y2u4d2vUGG9G0VeXRBGqA1YSTRV1aIqNKI61SnLrGTSyGcKX8/wW7i0fEOESK4g84cFhDUTT2+7PR6LDpR8dGpoM+rUWQg40VB50K/i99vgNOQL/tjkQM0MFXRb4OtQOiHCxyC0WHKRDAchtRYaLjFtAv+hGwq/NW2Zmi3937l1GOrOwozcXUUveZEsTQTDHeTpfiwVBKrtd/N5AHgkqESdDQvVEtd6ybQHtoKuhLXsUS882t7sk2GoSqsl5vsx8vLzNcdjJBtnozoJ+Nh/Gnqy6xp3GV1uhdfBalP7MZhxmC5jbFE='}],
 'ResponseMetadata': {'HTTPHeaders': {'content-length': '883',
                                      'content-type': 'text/xml',
                                      'date': 'Wed, 05 Dec 2018 03:52:43 GMT',
                                      'x-amzn-requestid': '5a0f9a2c-cffd-5f48-ad9d-cead8236d469'},
                      'HTTPStatusCode': 200,
                      'RequestId': '5a0f9a2c-cffd-5f48-ad9d-cead8236d469',
                      'RetryAttempts': 0}}

main.py

import boto3
import os
import re
import argparse
from pprint import pprint

class SQSSimpleSendWizard:
    _client_name = 'sqs'
    _queue_prefix = 'adv_sample'
    _session = None
    _queue_name = None
    _queue_url = None
    _message = None

    def __init__(self, profile_name):
        self._session = boto3.Session(profile_name=profile_name)

    @property
    def session(self):
        return self._session

    def get_client(self, client_name=None):
        if not client_name:
            client_name = self._client_name
        return self.session.client(client_name)

    @property
    def queue_name(self):
        return self._queue_name

    @property
    def queue_url(self):
        return self._queue_url

    @property
    def message(self):
        return self._message

    @property
    def client_name(self):
        return self._client_name

    @property
    def queue_prefix(self):
        return self._queue_prefix

    def create_queue(self, queue_name=None):
        if not queue_name:
            queue_name = self.queue_name
        params = {}
        params['QueueName'] = "{prefix}-{name}".format(
            prefix=self.queue_prefix,
            name=queue_name)
        res = self.get_client().create_queue(**params)
        self._queue_url = res['QueueUrl']
        return res

    def send_message(self, message=None):
        if not message:
            message = self.message
        params = { 
            'QueueUrl': self.queue_url,
            'MessageBody': message
        }
        return self.get_client().send_message(**params)

    def receive_message(self, queue_url=None):
        if not queue_url:
            queue_url = self.queue_url
        params = { 
            'QueueUrl': queue_url
        }
        return self.get_client().receive_message(**params)

    def prompt_queue_name(self):
        queue_name = None
        while True:
            queue_name = input('\nInput queue_name >>')
            if queue_name and len(queue_name) != 0:
                break
        self._queue_name = queue_name
        return self.queue_name

    def prompt_message(self):
        message = None
        while True:
            message = input('\nInput message >>')
            if message and len(message) != 0:
                break
        self._message = message
        return self.message

    @staticmethod
    def prompt():
        default_profile_name = 'default'
        profile_name = input('Input Profile name [{}]>> '.format(default_profile_name))
        if len(profile_name) == 0:
            profile_name = default_profile_name
        wizard = SQSSimpleSendWizard(profile_name)

        wizard.prompt_queue_name()
        wizard.create_queue()
        wizard.prompt_message()
        wizard.send_message()
        message = wizard.receive_message()
        pprint(message)

if __name__ == '__main__':
    SQSSimpleSendWizard.prompt()

FIFOキュー

今回の検証には用いませんでしたが、FIFOキューを使った際は以下の要件が求められます。

対象リージョン

現時点では以下の4リージョンとなっています。

  • us-east-1
  • us-east-2
  • us-west-2
  • eu-west-1

via:AWSドキュメント - Amazon Simple Queue Serviceとは

FIFOのQueue名

suffixに.fifoと付ける必要があります。

まとめ

今回は一つのQueueで一つのメッセージ、一回だけの受信という構成のため、過程と結果も単純な構成になっています。

create_queue()に指定するパラメータを必須なものだけに留めましたが、負荷軽減等を検討する際に効果的なパラメータがオプションとして数多く存在します。未だ見たことがない方は目を通されることをオススメします。