I'm using the latest Python Azure SDK

azure-mgmt-servicebus==6.0.0
azure-servicebus==7.0.0

I get a reference to a ServiceBusManagementClient like so ...

def _get_sb_client(self):
    credential = ClientSecretCredential(
       tenant_id=self._tenant,
        client_id=self._client_id,
        client_secret=self._client_secret
    )

    return ServiceBusManagementClient(
        credential, self._subscription)

However, according to this -- https://learn.microsoft.com/en-us/python/api/overview/azure/servicebus?view=azure-python#service-bus-topics-and-subscriptions, in order to send a message on a topic,

topic_client = sb_client.get_topic("MyTopic")

I need a reference to a azure.servicebus.ServiceBusClient object. However, the docs don't give any explanations about how to generate such an instance, other than through a connection string, which we are not using. How can I get an instance of ServiceBusClient using ClientSecretCredential or ServiceBusManagementClient instances?

1

There are 1 best solutions below

2
On BEST ANSWER

I'd respond with few things, do let me know if any of this needs clarification or is off-base:

  1. The doc you linked is not for 7.0.0, but for 0.50.3, which might explain some of the confusion. I would advise using the docs rooted in the readme for which one of the comparable docs to the one you referenced is here. (The process of replacing the historical docs is a known issue and being addressed, full disclosure speaking as a maintainer of the python SDK component)
  2. I would call out that you initialized a ServiceBusManagementClient (which would be used for creating/deleting topics) and not the ServiceBusClient (which would be used for sending and receiving.) kindly see the document I listed above for an example of how to send to the topic. I'll paste a comprehensive example from that link at the bottom of this post for posterity in case anything shifts in the future, that this post is still relevant for version 7.0.0
  3. For authenticating using an Azure Identity credential, I would point you at the documentation in the readme here and the sample linked therein, and pasted below.

Example of sending and receiving to a topic/subscription

from azure.servicebus import ServiceBusClient, ServiceBusMessage

CONNECTION_STR = "<NAMESPACE CONNECTION STRING>"
TOPIC_NAME = "<TOPIC NAME>"
SUBSCRIPTION_NAME = "<SUBSCRIPTION NAME>"

def send_single_message(sender):
    message = ServiceBusMessage("Single Message")
    sender.send_messages(message)
    print("Sent a single message")

def send_a_list_of_messages(sender):
    messages = [ServiceBusMessage("Message in list") for _ in range(5)]
    sender.send_messages(messages)
    print("Sent a list of 5 messages")

def send_batch_message(sender):
    batch_message = sender.create_message_batch()
    for _ in range(10):
        try:
            batch_message.add_message(ServiceBusMessage("Message inside a ServiceBusMessageBatch"))
        except ValueError:
            # ServiceBusMessageBatch object reaches max_size.
            # New ServiceBusMessageBatch object can be created here to send more data.
            break
    sender.send_messages(batch_message)
    print("Sent a batch of 10 messages")

servicebus_client = ServiceBusClient.from_connection_string(conn_str=CONNECTION_STR, logging_enable=True)

with servicebus_client:
    sender = servicebus_client.get_topic_sender(topic_name=TOPIC_NAME)
    with sender:
        send_single_message(sender)
        send_a_list_of_messages(sender)
        send_batch_message(sender)

print("Done sending messages")
print("-----------------------")

with servicebus_client:
    receiver = servicebus_client.get_subscription_receiver(topic_name=TOPIC_NAME, subscription_name=SUBSCRIPTION_NAME, max_wait_time=5)
    with receiver:
        for msg in receiver:
            print("Received: " + str(msg))
            receiver.complete_message(msg)

Example of authenticating with Azure Identity

import os
from azure.servicebus import ServiceBusClient, ServiceBusMessage
from azure.identity import EnvironmentCredential

FULLY_QUALIFIED_NAMESPACE = os.environ['SERVICE_BUS_NAMESPACE']
QUEUE_NAME = os.environ["SERVICE_BUS_QUEUE_NAME"]

credential = EnvironmentCredential()

servicebus_client = ServiceBusClient(FULLY_QUALIFIED_NAMESPACE, credential)
with servicebus_client:
    sender = servicebus_client.get_queue_sender(queue_name=QUEUE_NAME)
    with sender:
        sender.send_messages(ServiceBusMessage('Single Message'))