Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Azure Service Bus SDK for Python messaging. Use for queues, topics, subscriptions, and enterprise messaging patterns. Triggers: "service bus", "ServiceBusClient", "queue", "topic", "subscription", "message broker".
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 60% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 178% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 92% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 215% | 0% |
| case-15 | ✗→✓ | ▲ Improved | -40% | 0% |
Enterprise messaging for reliable cloud communication with queues and pub/sub topics.
bashpip install azure-servicebus azure-identity
bashSERVICEBUS_FULLY_QUALIFIED_NAMESPACE=<namespace>.servicebus.windows.net # Required for all auth methods SERVICEBUS_QUEUE_NAME=myqueue # Required for queue operations SERVICEBUS_TOPIC_NAME=mytopic # Required for topic operations SERVICEBUS_SUBSCRIPTION_NAME=mysubscription # Required for subscription operations AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production
> 🔑 Two rules apply to every code sample below: > > 1. Prefer DefaultAzureCredential. It works locally (Azure CLI / VS Code / Developer CLI) and in Azure (managed identity, workload identity) with no code change. Avoid connection strings, account/API keys — they bypass Entra audit and rotation. > - Local dev: DefaultAzureCredential works as-is. > - Production: set AZURE_TOKEN_CREDENTIALS=prod (or AZURE_TOKEN_CREDENTIALS=<specific_credential>) to constrain the credential chain to production-safe credentials. > 2. Wrap every client in a context manager so HTTP transports, sockets, and token caches are released deterministically: > - Sync: with <Client>(...) as client: > - Async: async with <Client>(...) as client: and async with DefaultAzureCredential() as credential: (from azure.identity.aio) > > Snippets may abbreviate this setup, but production code should always follow both rules.
pythonfrom azure.identity import DefaultAzureCredential, ManagedIdentityCredential from azure.servicebus import ServiceBusClient # Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential> credential = DefaultAzureCredential(require_envvar=True) # Or use a specific credential directly in production: # See https://learn.microsoft.com/python/api/overview/azure/identity-readme?view=azure-python#credential-classes # credential = ManagedIdentityCredential() namespace = "<namespace>.servicebus.windows.net" with ServiceBusClient( fully_qualified_namespace=namespace, credential=credential ) as client: # Use client here (see following sections for operations) ...
| Client | Purpose | Get From | |--------|---------|----------| | ServiceBusClient | Connection management | Direct instantiation | | ServiceBusSender | Send messages | client.get_queue_sender() / get_topic_sender() | | ServiceBusReceiver | Receive messages | client.get_queue_receiver() / get_subscription_receiver() |
pythonimport asyncio from azure.servicebus.aio import ServiceBusClient from azure.servicebus import ServiceBusMessage from azure.identity.aio import DefaultAzureCredential async def send_messages(): credential = DefaultAzureCredential() async with ServiceBusClient( fully_qualified_namespace="<namespace>.servicebus.windows.net", credential=credential ) as client: sender = client.get_queue_sender(queue_name="myqueue") async with sender: # Single message message = ServiceBusMessage("Hello, Service Bus!") await sender.send_messages(message) # Batch of messages messages = [ServiceBusMessage(f"Message {i}") for i in range(10)] await sender.send_messages(messages) # Message batch (for size control) batch = await sender.create_message_batch() for i in range(100): try: batch.add_message(ServiceBusMessage(f"Batch message {i}")) except ValueError: # Batch full await sender.send_messages(batch) batch = await sender.create_message_batch() batch.add_message(ServiceBusMessage(f"Batch message {i}")) await sender.send_messages(batch) asyncio.run(send_messages())
pythonasync def receive_messages(): credential = DefaultAzureCredential() async with ServiceBusClient( fully_qualified_namespace="<namespace>.servicebus.windows.net", credential=credential ) as client: receiver = client.get_queue_receiver(queue_name="myqueue") async with receiver: # Receive batch messages = await receiver.receive_messages( max_message_count=10, max_wait_time=5 # seconds ) for msg in messages: print(f"Received: {str(msg)}") await receiver.complete_message(msg) # Remove from queue asyncio.run(receive_messages())
| Mode | Behavior | Use Case | |------|----------|----------| | PEEK_LOCK (default) | Message locked, must complete/abandon | Reliable processing | | RECEIVE_AND_DELETE | Removed immediately on receive | At-most-once delivery |
pythonfrom azure.servicebus import ServiceBusReceiveMode receiver = client.get_queue_receiver( queue_name="myqueue", receive_mode=ServiceBusReceiveMode.RECEIVE_AND_DELETE )
pythonasync with receiver: messages = await receiver.receive_messages(max_message_count=1) for msg in messages: try: # Process message... await receiver.complete_message(msg) # Success - remove from queue except ProcessingError: await receiver.abandon_message(msg) # Retry later except PermanentError: await receiver.dead_letter_message( msg, reason="ProcessingFailed", error_description="Could not process" )
| Action | Effect | |--------|--------| | complete_message() | Remove from queue (success) | | abandon_message() | Release lock, retry immediately | | dead_letter_message() | Move to dead-letter queue | | defer_message() | Set aside, receive by sequence number |
python# Send to topic sender = client.get_topic_sender(topic_name="mytopic") async with sender: await sender.send_messages(ServiceBusMessage("Topic message")) # Receive from subscription receiver = client.get_subscription_receiver( topic_name="mytopic", subscription_name="mysubscription" ) async with receiver: messages = await receiver.receive_messages(max_message_count=10)
python# Send with session message = ServiceBusMessage("Session message") message.session_id = "order-123" await sender.send_messages(message) # Receive from specific session receiver = client.get_queue_receiver( queue_name="session-queue", session_id="order-123" ) # Receive from next available session from azure.servicebus import NEXT_AVAILABLE_SESSION receiver = client.get_queue_receiver( queue_name="session-queue", session_id=NEXT_AVAILABLE_SESSION )
pythonfrom datetime import datetime, timedelta, timezone message = ServiceBusMessage("Scheduled message") scheduled_time = datetime.now(timezone.utc) + timedelta(minutes=10) # Schedule message sequence_number = await sender.schedule_messages(message, scheduled_time) # Cancel scheduled message await sender.cancel_scheduled_messages(sequence_number)
pythonfrom azure.servicebus import ServiceBusSubQueue # Receive from dead-letter queue dlq_receiver = client.get_queue_receiver( queue_name="myqueue", sub_queue=ServiceBusSubQueue.DEAD_LETTER ) async with dlq_receiver: messages = await dlq_receiver.receive_messages(max_message_count=10) for msg in messages: print(f"Dead-lettered: {msg.dead_letter_reason}") await dlq_receiver.complete_message(msg)
pythonfrom azure.servicebus import ServiceBusClient, ServiceBusMessage from azure.identity import DefaultAzureCredential with ServiceBusClient( fully_qualified_namespace="<namespace>.servicebus.windows.net", credential=DefaultAzureCredential() ) as client: with client.get_queue_sender("myqueue") as sender: sender.send_messages(ServiceBusMessage("Sync message")) with client.get_queue_receiver("myqueue") as receiver: for msg in receiver: print(str(msg)) receiver.complete_message(msg)
azure.xxx sync clients with azure.xxx.aio async clients in the same call path. Choose one mode per module.with Client(...) as client: (sync) or async with Client(...) as client: (async) for proper cleanup. For async DefaultAzureCredential from azure.identity.aio, also use async with credential: so tokens and transports are cleaned up.DefaultAzureCredential for portable auth across local dev and Azure (avoid connection strings / API keys when possible).max_wait_time to avoid infinite blocking| File | Contents | |------|----------| | references/patterns.md | Competing consumers, sessions, retry patterns, request-response, transactions | | references/dead-letter.md | DLQ handling, poison messages, reprocessing strategies | | scripts/setup_servicebus.py | CLI for queue/topic/subscription management and DLQ monitoring |
Other measured skills in the registry, with their headline benchmark lift.