

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Python 用の Amazon SNS 拡張クライアントライブラリ
<a name="extended-client-library-python"></a>

## 前提条件
<a name="prereqs-sns-extended-client-library-python"></a>

[Python 用 Amazon SNS 拡張クライアントライブラリ](https://github.com/awslabs/amazon-sns-python-extended-client-lib)を使用するための前提条件は以下のとおりです。
+  AWS SDK。このページの例では、Python SDK Boto3 AWS を使用しています。SDK をインストールして設定するには、[https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html) のドキュメントを参照してください。
+ 適切な認証情報 AWS アカウント を持つ 。を作成するには AWS アカウント、[AWS ホームページ](https://aws.amazon.com/)に移動し、** AWS アカウントの作成**を選択します。手順に従います。

  認証情報については、「*AWS SDK for Python デベロッパーガイド*」の「[認証情報](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html)」を参照してください。
+ Python 3.x (または以降) および pip。
+ Python 用 Amazon SNS 拡張クライアントライブラリ ([PyPI](https://pypi.org/project/amazon-sns-extended-client/) からも利用可能) 

## メッセージストレージの設定
<a name="large-message-configure-storage-python"></a>

Amazon S3 のメッセージ保存オプションを設定するには、Boto3 Amazon SNS の [Client](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sns.html#client)、[Topic](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sns/topic/index.html)、[PlatformEndpoint](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sns/platformendpoint/index.html) の各オブジェクトで以下の属性を使用できます。
+ **`large_payload_support`** – サイズの大きいメッセージを保存する Amazon S3 バケットの名前。
+ **`use_legacy_attribute`** – `True` の場合、すべての発行済みメッセージは、現在の予約済みメッセージ属性 (`ExtendedPayloadSize`) ではなく、レガシーの予約済みメッセージ属性 (`SQSLargePayloadSize`) を使用します。
+ **`message_size_threshold`** - メッセージを大きなメッセージバケットに保存するためのしきい値。`0` 未満または `262144` を超える値を指定することはできません。デフォルトは `262144` です。
+ **`always_through_s3`** – `True` の場合、すべてのメッセージは Amazon S3 に保存されます。デフォルトは `False` です。
+ **`s3_client`** – Amazon S3 にオブジェクトを保存するために使用する Boto3 Amazon S3 の `client` オブジェクト。Amazon S3 クライアント (Amazon S3 のカスタム設定や認証情報など) を制御する場合に使用します。以前に設定していない場合は、最初の使用時にデフォルトで `boto3.client("s3")` に設定されます。

## 例: Amazon S3 にペイロードが保存されている Amazon SNS にメッセージを発行する
<a name="example-s3-large-payloads-python"></a>

次のコード例は、以下の操作方法を示しています。
+ Amazon SNS トピックと Amazon SQS キューを作成します。
+ ポリシーを Amazon SQS キューにアタッチして、Amazon SNS トピックからメッセージを受信します。
+ トピックからメッセージを受信するためにキューをサブスクライブします。
+ Amazon SNS 拡張クライアント、トピックリソース、および PlatformEndpoint リソースを使用してテストメッセージを発行します。
+ メッセージペイロードは Amazon S3 に保存され、その参照が発行されます。
+ キューから発行したメッセージと、Amazon S3 から取得した元のメッセージを印刷します。

容量の大きなメッセージを発行するには、Java 用 Amazon SNS 拡張クライアントライブラリを使用します。送信するメッセージは、実際のメッセージコンテンツが含まれている Amazon S3 オブジェクトを参照します。

```
import boto3
from sns_extended_client import SNSExtendedClientSession
from json import loads

s3_extended_payload_bucket = "extended-client-bucket-store"  # S3 bucket with the given bucket name is a resource which is created and accessible with the given AWS credentials
TOPIC_NAME = "---TOPIC-NAME---"
QUEUE_NAME = "---QUEUE-NAME---"

def allow_sns_to_write_to_sqs(topicarn, queuearn):
    policy_document = """{{
        "Version": "2012-10-17",		 	 	 
        "Statement":[
            {{
            "Sid":"MyPolicy",
            "Effect":"Allow",
            "Principal" : {{"AWS" : "*"}},
            "Action":"SQS:SendMessage",
            "Resource": "{}",
            "Condition":{{
                "ArnEquals":{{
                "aws:SourceArn": "{}"
                }}
            }}
            }}
        ]
        }}""".format(queuearn, topicarn)

    return policy_document

def get_msg_from_s3(body,sns_extended_client):
    """Handy Helper to fetch message from S3"""
    json_msg = loads(body)
    s3_object = sns_extended_client.s3_client.get_object(
        Bucket=json_msg[1].get("s3BucketName"), Key=json_msg[1].get("s3Key")
    )
    msg = s3_object.get("Body").read().decode()
    return msg


def fetch_and_print_from_sqs(sqs, queue_url,sns_extended_client):
    sqs_msg = sqs.receive_message(
        QueueUrl=queue_url,
        AttributeNames=['All'],
        MessageAttributeNames=['All'],
        VisibilityTimeout=0,
        WaitTimeSeconds=0,
        MaxNumberOfMessages=1
    ).get("Messages")[0]
    
    message_body = sqs_msg.get("Body")
    print("Published Message: {}".format(message_body))
    print("Message Stored in S3 Bucket is: {}\n".format(get_msg_from_s3(message_body,sns_extended_client)))

    # Delete the Processed Message
    sqs.delete_message(
        QueueUrl=queue_url,
        ReceiptHandle=sqs_msg['ReceiptHandle']
    )


sns_extended_client = boto3.client("sns", region_name="us-east-1")
create_topic_response = sns_extended_client.create_topic(Name=TOPIC_NAME)
sns_topic_arn = create_topic_response.get("TopicArn")

# create and subscribe an sqs queue to the sns client
sqs = boto3.client("sqs",region_name="us-east-1")
demo_queue_url = sqs.create_queue(QueueName=QUEUE_NAME).get("QueueUrl")
sqs_queue_arn = sqs.get_queue_attributes(
    QueueUrl=demo_queue_url, AttributeNames=["QueueArn"]
)["Attributes"].get("QueueArn")

# Adding policy to SQS queue such that SNS topic can send msg to SQS queue
policy_json = allow_sns_to_write_to_sqs(sns_topic_arn, sqs_queue_arn)
response = sqs.set_queue_attributes(
    QueueUrl = demo_queue_url,
    Attributes = {
        'Policy' : policy_json
    }
)

# Set the RawMessageDelivery subscription attribute to TRUE if you want to use
# SQSExtendedClient to help with retrieving msg from S3
sns_extended_client.subscribe(TopicArn=sns_topic_arn, Protocol="sqs", 
Endpoint=sqs_queue_arn
, Attributes={"RawMessageDelivery":"true"}
)

sns_extended_client.large_payload_support = s3_extended_payload_bucket

# Change default s3_client attribute of sns_extended_client to use 'us-east-1' region
sns_extended_client.s3_client = boto3.client("s3", region_name="us-east-1")


# Below is the example that all the messages will be sent to the S3 bucket
sns_extended_client.always_through_s3 = True
sns_extended_client.publish(
    TopicArn=sns_topic_arn, Message="This message should be published to S3"
)
print("\n\nPublished using SNS extended client:")
fetch_and_print_from_sqs(sqs, demo_queue_url,sns_extended_client)  # Prints message stored in s3

# Below is the example that all the messages larger than 32 bytes will be sent to the S3 bucket
print("\nUsing decreased message size threshold:")

sns_extended_client.always_through_s3 = False
sns_extended_client.message_size_threshold = 32
sns_extended_client.publish(
    TopicArn=sns_topic_arn,
    Message="This message should be published to S3 as it exceeds the limit of the 32 bytes",
)

fetch_and_print_from_sqs(sqs, demo_queue_url,sns_extended_client)  # Prints message stored in s3


# Below is the example to publish message using the SNS.Topic resource
sns_extended_client_resource = SNSExtendedClientSession().resource(
    "sns", region_name="us-east-1"
)

topic = sns_extended_client_resource.Topic(sns_topic_arn)
topic.large_payload_support = s3_extended_payload_bucket

# Change default s3_client attribute of topic to use 'us-east-1' region
topic.s3_client = boto3.client("s3", region_name="us-east-1")

topic.always_through_s3 = True
# Can Set custom S3 Keys to be used to store objects in S3
topic.publish(
    Message="This message should be published to S3 using the topic resource",
    MessageAttributes={
        "S3Key": {
            "DataType": "String",
            "StringValue": "347c11c4-a22c-42e4-a6a2-9b5af5b76587",
        }
    },
)
print("\nPublished using Topic Resource:")
fetch_and_print_from_sqs(sqs, demo_queue_url,topic)

# Below is the example to publish message using the SNS.PlatformEndpoint resource
sns_extended_client_resource = SNSExtendedClientSession().resource(
    "sns", region_name="us-east-1"
)

platform_endpoint = sns_extended_client_resource.PlatformEndpoint(sns_topic_arn)
platform_endpoint.large_payload_support = s3_extended_payload_bucket

# Change default s3_client attribute of platform_endpoint to use 'us-east-1' region
platform_endpoint.s3_client = boto3.client("s3", region_name="us-east-1")

platform_endpoint.always_through_s3 = True
# Can Set custom S3 Keys to be used to store objects in S3
platform_endpoint.publish(
    Message="This message should be published to S3 using the PlatformEndpoint resource",
    MessageAttributes={
        "S3Key": {
            "DataType": "String",
            "StringValue": "247c11c4-a22c-42e4-a6a2-9b5af5b76587",
        }
    },
)
print("\nPublished using PlatformEndpoint Resource:")
fetch_and_print_from_sqs(sqs, demo_queue_url,platform_endpoint)
```

**出力**

```
Published using SNS extended client:
Published Message: ["software.amazon.payloadoffloading.PayloadS3Pointer", {"s3BucketName": "extended-client-bucket-store", "s3Key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}]
Message Stored in S3 Bucket is: This message should be published to S3

Using decreased message size threshold:
Published Message: ["software.amazon.payloadoffloading.PayloadS3Pointer", {"s3BucketName": "extended-client-bucket-store", "s3Key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}]
Message Stored in S3 Bucket is: This message should be published to S3 as it exceeds the limit of the 32 bytes

Published using Topic Resource:
Published Message: ["software.amazon.payloadoffloading.PayloadS3Pointer", {"s3BucketName": "extended-client-bucket-store", "s3Key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}]
Message Stored in S3 Bucket is: This message should be published to S3 using the topic resource

Published using PlatformEndpoint Resource:
Published Message: ["software.amazon.payloadoffloading.PayloadS3Pointer", {"s3BucketName": "extended-client-bucket-store", "s3Key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}]
Message Stored in S3 Bucket is: This message should be published to S3 using the PlatformEndpoint resource
```