Newtuple
Back to Blog
Data Engineering

Master the Art of Data Streamlining with Pub/Sub Pipelines

Data pipeline

Rahul KumarJune 13, 20243 min readUpdated November 24, 2025
Master the Art of Data Streamlining with Pub/Sub Pipelines

Creating a pipeline that requires sending some events to be processed in the background keeping scalability in mind is one of the key requirements for building applications today. In order to process heavy/time consuming jobs in your current application it’s generally better to separate it from your core application, and one way to achieve is to use a pub/sub architecture.

The idea here is as follows:

  • Maintain a queue of messages

  • A publisher pushes messages to the queue under a topic namespace

  • A subscriber subscribes to a one or more topic & all subscribers receives it whenever a message is published to that particular topic

The most popular services in this are Apache Kafka, Google’s pub/sub, AWS SQS/AppSync etc. In this article we will demonstrate using Azure’s pub/sub service which is service bus

  1. Login to azure portal and search for service bus

Service bus namespaceService bus namespace

Service bus namespace

2. Create a service bus namespace under standard pricing tier (allows us to create topics in the queue)

3. After that create a topic inside the service bus namespace

TopicTopic

Topic

4. Now all that is left to do is create a subscription for the previously create topic

Subscription for the topicSubscription for the topic

Subscription for the topic

Optionally we can set the message lock duration or the maximum amount of time the message can be held by subscriber before lock on the message expires to 5 minutes (max for azure)

5. Now we are all set to publish messages to the topic and having a subscriber process/consume it. To do that we can use the Azure SDK

6. Obtain the access key from the portal to authenticate to the service

Access keyAccess key

Access key

7. Create a publisher script which will publish messages to the topic

from azure.servicebus import ServiceBusMessage, ServiceBusClient, ServiceBusSender
import traceback

NAMESPACE_CONNECTION_STR = "YOUR_CONN_STRING"
TOPIC_NAME = "YOUR_TOPIC_NAME"

def send_a_list_of_messages(sender: ServiceBusSender, *msgs):
    """Send list of msgs using the sender client

    Args:
        sender (ServiceBusSender): ServiceBusSender client
        msgs (tuple): List of msgs
    """
    # Create a list of messages
    messages = [ServiceBusMessage(str(msg)) for msg in msgs]
    # send the list of messages to the topic
    sender.send_messages(messages)

def send_messages_to_queue(*msgs , topic_name):
    """ Send a list of msgs to azure queue

    Args:
        msgs(tuple) : Tuple of msgs
    """
    try:
        servicebus_client = ServiceBusClient.from_connection_string(conn_str=NAMESPACE_CONNECTION_STR)
        with servicebus_client:
            # Get a Topic Sender object to send messages to the topic
            sender = servicebus_client.get_topic_sender(topic_name=topic_name)
            with sender:
                # Send a list of messages
                send_a_list_of_messages(sender, *msgs)

    except Exception as e:
        error_msg = f"Some error occured in the azure pub queue worker..{e} with stack trace \n {traceback.format_exc()}"

if __name__ == '__main__':
    message = {
        'job_id' : 1234,
        "process": 'some_text_that_needs_processing'
    }

    send_messages_to_queue(message, TOPIC_NAME)

View the original GitHub Gist

8. Create a subscriber that will keep listening to topic for a new message and process them as they arrive, that will keep processing long running jobs

from azure.servicebus import ServiceBusClient, exceptions
import traceback

NAMESPACE_CONNECTION_STR = "YOUR_CONN_STRING"
TOPIC_NAME = "YOUR_TOPIC_NAME"
SUBSCRIPTION_NAME = "YOUR_SUBS_NAME"

def recieve_topic_msgs():
    """Recieve and process the azure queue msgs sychronously"""
    # Create a ServiceBusClient object.
    try:
        with ServiceBusClient.from_connection_string(NAMESPACE_CONNECTION_STR) as client:

            # Create a receiver for the queue.
            with client.get_subscription_receiver(TOPIC_NAME,subscription_name=SUBSCRIPTION_NAME) as receiver:
                while True:
                    # Fetch new messages.
                    # Note: This call is blocking, but will timeout after max_wait_time if no messages are available, which allows for graceful shutdown.
                    for msg in receiver.receive_messages():
                        try:
                            # Process each message.
                            receiver.complete_message(msg)
                        except ValueError as e:
                            print(f"Msg consumption failed enqueing back to queue..{e}" , exc_info=1)
                            receiver.abandon_message(msg)
                        except exceptions.MessageLockLostError as e:
                            print(f"Msg consumption failed skipping..{e}")
                            continue
    except Exception as e:
        error_msg = f"Some error occured in the azure subs queue worker..{e}"
        print(error_msg)

if __name__ == '__main__':
  recieve_topic_msgs()

View the original GitHub Gist

And voilà, you have successfully created a pub/sub based data pipeline !

The messages that exceed the lock time period can optionally be sent back the queue or send to dead letter queue.

The messages will tried max delivery number of times before they are taken away or sent to dead letters if configured.

References:

https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-quickstart-topics-subscriptions-portal

Stay in the loop

Get new posts, product updates, and research notes once a week.

By subscribing you agree to receive updates from Newtuple. You can unsubscribe anytime.

Ready to build production AI?

Talk to our team about AI agents, data platforms, and GenAI accelerators.

Get in Touch