AWS Boto3 is the Python SDK for AWS. Boto3 can be used to directly interact with AWS resources from Python scripts. In this tutorial, we will look at how we can use the Boto3 library to perform various operations on AWS SNS. Simple Notification Service (SNS) enables message delivery from publishers to subscribers.

Table of contents

Prerequisites

  • Python3
  • Boto3: Boto3 can be installed using pip: pip install boto3
  • AWS Credentials: If you haven’t setup AWS credentials before, this resource from AWS is helpful.

How to create a new topic?

Publishers communicate asynchronously with consumers by sending messages to a topic. We will use the create_topic method to create a new SNS topic.

def create_topic(name):
    """
    Creates a notification topic.

    :param name: The name of the topic to create.
    :return: The newly created topic.
    """
    sns = boto3.resource("sns")
    topic = sns.create_topic(Name=name)
    return topic

The output of this function is:

create_topic("learnaws-boto3-sns")


sns.Topic(arn="arn:aws:sns:us-west-2:xxx:learnaws-boto3-sns")


How to list all topics?

Next, we will see how we can list of all the SNS topics within the AWS account.


def list_topics():
    """
    Lists topics for the current account.

    :return: An iterator that yields the topics.
    """
    sns = boto3.resource("sns")
    topics_iter = sns.topics.all()
    return topics_iter

Output would look something like this:

for topic in list_topics():
  print(topic)

...
sns.Topic(arn="arn:aws:sns:us-west-2:xxx:learnaws-boto3-sns")



How to subscribe to a topic?

Before we can send a message to a consumer, we need to subscribe an endpoint (phone number or email) to the topic.


def subscribe(topic, protocol, endpoint):
    """
    Subscribes an endpoint to the topic. Some endpoint types, such as email,
    must be confirmed before their subscriptions are active. When a subscription
    is not confirmed, its Amazon Resource Number (ARN) is set to
    'PendingConfirmation'.

    :param topic: The topic to subscribe to.
    :param protocol: The protocol of the endpoint, such as 'sms' or 'email'.
    :param endpoint: The endpoint that receives messages, such as a phone number
                      or an email address.
    :return: The newly added subscription.
    """
    subscription = topic.subscribe(Protocol=protocol, Endpoint=endpoint, ReturnSubscriptionArn=True)
    return subscription

The output of subscribing an email would be:


email = [email protected]
email_sub = subscribe(topic, "email", email)

# Emails need to be manually confirmed first
print(email_sub.attributes["PendingConfirmation"])
"false"

Phone numbers don’t need to be confirmed:


phone_number = "+123456789"
phone_sub = subscribe(topic, 'sms', phone_number)


How to send a text message?

We will use the publish method to send a text message to a phone number without needing


def publish_text_message(phone_number, message):
    """
    Publishes a text message directly to a phone number without need for a
    subscription.

    :param phone_number: The phone number that receives the message.
    :param message: The message to send.
    :return: The ID of the message.
    """
    response = sns.meta.client.publish(
        PhoneNumber=phone_number, Message=message)
    message_id = response['MessageId']
    return message_id

We can test this method as follows:


publish_text_message("+1234567890, "Testing sms 1234")


How to publish a message to a topic?

Next, we will look at how to publish a message to a topic that will then get delivered to all subscribers.


def publish_message(topic, message):
    """
    Publishes a message to a topic.

    :param topic: The topic to publish to.
    :param message: The message to publish.
    :return: The ID of the message.
    """
    response = topic.publish(Message=message)
    message_id = response['MessageId']
    return message_id

Let’s see how to use this method to publish a message:

publish_message(topic, "this is a test message on topic")

This should send a message to both the confirmed email address as well as the subscribed phone number.


How to publish a multi-format message to a topic?

There are times when we want to publish a message that looks different based on the protocol.


def publish_multi_message(topic, subject, default_message, sms_message, email_message):
    """
    Publishes a multi-format message to a topic. A multi-format message takes
    different forms based on the protocol of the subscriber.

    :param topic: The topic to publish to.
    :param subject: The subject of the message.
    :param default_message: The default version of the message. This version is
                            sent to subscribers that have protocols that are not
                            otherwise specified in the structured message.
    :param sms_message: The version of the message sent to SMS subscribers.
    :param email_message: The version of the message sent to email subscribers.
    :return: The ID of the message.
    """
    message = {
        'default': default_message,
        'sms': sms_message,
        'email': email_message
    }
    response = topic.publish(
        Message=json.dumps(message), Subject=subject, MessageStructure='json')
    message_id = response['MessageId']
    return message_id

We can use this method similar to the ones above:


publish_multi_message(topic, "Hello from Learn AWS", "This is the default message", "SMS message is different", "So is email message")

How to delete a subscription to a topic?

Deleting an existing subscription is pretty straightforward.

def delete_subscription(subscription):
    """
    Unsubscribes and deletes a subscription.
    """
    subscription.delete()

How to delete a topic?

We can delete a topic by using the delete method.


def delete_topic(topic):
    """
    Deletes a topic. All subscriptions to the topic are also deleted.
    """
    topic.delete()