Azure Eventhub Py
MicrosoftOfficialCreated by Microsoft
- Skill
- Tool integration
- Cloud and DevOps
- MIT
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The azure-eventhub-py skill provides the Python SDK for Azure Event Hubs. It enables developers to build producers and consumers for event streaming, manage partitions, and implement checkpointing using Azure Blob Storage. The skill includes guidance on authentication using DefaultAzureCredential, managing client lifecycles with context managers, and strategies for handling event batches and partition distribution.
What it does
- Provides clients for producing and consuming events from Azure Event Hubs
- Supports both synchronous and asynchronous programming models
- Enables checkpointing of consumer progress using Azure Blob Storage
- Facilitates partition management including direct, key-based, and round-robin routing
- Offers methods to retrieve Event Hub and partition metadata
- Integrates with Azure Identity for secure authentication
When to use it
- When integrating Python applications with Azure Event Hubs
- When building event-driven architectures requiring high-throughput ingestion
- When implementing reliable consumer patterns with stateful checkpointing
- When needing to distribute event processing across multiple consumers
Advantages
- Supports consistent authentication patterns across local and cloud environments
- Provides flexible partition selection strategies for ordered or distributed delivery
- Includes built-in support for checkpointing to track processing progress
- Offers consistent API design for both sync and async operations
Usage examples
- “How do I send events to an Azure Event Hub using Python?”
- The agent provides a code example using EventHubProducerClient, demonstrating how to create a batch, add events, and send them to the hub.
- “How can I implement a consumer that tracks progress with a checkpoint store?”
- The agent provides a code snippet using EventHubConsumerClient configured with a BlobCheckpointStore to update checkpoints after processing events.
- “How do I route events to a specific partition in Event Hubs?”
- The agent explains how to use partition_id or partition_key within the create_batch method to control event distribution.
- “What is the recommended way to authenticate with Azure Event Hubs?”
- The agent explains the use of DefaultAzureCredential to handle authentication across local development and production environments.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/microsoft/azure-eventhub-py/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip azure-eventhub-py.zip -d .agents/skills
Documentation by Microsoft
Azure Event Hubs SDK for Python
Big data streaming platform for high-throughput event ingestion.
Installation
pip install azure-eventhub azure-identity
# For checkpointing with blob storage
pip install azure-eventhub-checkpointstoreblob-aioEnvironment Variables
EVENT_HUB_FULLY_QUALIFIED_NAMESPACE=<namespace>.servicebus.windows.net # Required for all auth methods
EVENT_HUB_NAME=my-eventhub # Required for all auth methods
STORAGE_ACCOUNT_URL=https://<account>.blob.core.windows.net # Required for checkpoint storage
CHECKPOINT_CONTAINER=checkpoints # Required for checkpoint storage
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in productionAuthentication & Lifecycle
🔑 Two rules apply to every code sample below:
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:
DefaultAzureCredentialworks as-is.Production: set
AZURE_TOKEN_CREDENTIALS=prod(orAZURE_TOKEN_CREDENTIALS=<specific_credential>) to constrain the credential chain to production-safe credentials.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:andasync with DefaultAzureCredential() as credential:(fromazure.identity.aio)Snippets may abbreviate this setup, but production code should always follow both rules.
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential
from azure.eventhub import EventHubProducerClient, EventHubConsumerClient
# 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"
eventhub_name = "my-eventhub"
# Producer
with EventHubProducerClient(
fully_qualified_namespace=namespace,
eventhub_name=eventhub_name,
credential=credential
) as producer:
# Use producer here (see following sections for operations)
...
# Consumer
with EventHubConsumerClient(
fully_qualified_namespace=namespace,
eventhub_name=eventhub_name,
consumer_group="$Default",
credential=credential
) as consumer:
# Use consumer here (see following sections for operations)
...Client Types
| Client | Purpose |
|---|---|
EventHubProducerClient | Send events to Event Hub |
EventHubConsumerClient | Receive events from Event Hub |
BlobCheckpointStore | Track consumer progress |
Send Events
from azure.eventhub import EventHubProducerClient, EventData
from azure.identity import DefaultAzureCredential
with EventHubProducerClient(
fully_qualified_namespace="<namespace>.servicebus.windows.net",
eventhub_name="my-eventhub",
credential=DefaultAzureCredential()
) as producer:
# Create batch (handles size limits)
event_data_batch = producer.create_batch()
for i in range(10):
try:
event_data_batch.add(EventData(f"Event {i}"))
except ValueError:
# Batch is full, send and create new one
producer.send_batch(event_data_batch)
event_data_batch = producer.create_batch()
event_data_batch.add(EventData(f"Event {i}"))
# Send remaining
producer.send_batch(event_data_batch)Send to Specific Partition
# By partition ID
event_data_batch = producer.create_batch(partition_id="0")
# By partition key (consistent hashing)
event_data_batch = producer.create_batch(partition_key="user-123")Receive Events
Simple Receive
from azure.eventhub import EventHubConsumerClient
def on_event(partition_context, event):
print(f"Partition: {partition_context.partition_id}")
print(f"Data: {event.body_as_str()}")
partition_context.update_checkpoint(event)
with EventHubConsumerClient(
fully_qualified_namespace="<namespace>.servicebus.windows.net",
eventhub_name="my-eventhub",
consumer_group="$Default",
credential=DefaultAzureCredential()
) as consumer:
consumer.receive(
on_event=on_event,
starting_position="-1", # Beginning of stream
)With Blob Checkpoint Store (Production)
from azure.eventhub import EventHubConsumerClient
from azure.eventhub.extensions.checkpointstoreblob import BlobCheckpointStore
from azure.identity import DefaultAzureCredential
checkpoint_store = BlobCheckpointStore(
blob_account_url="https://<account>.blob.core.windows.net",
container_name="checkpoints",
credential=DefaultAzureCredential()
)
with EventHubConsumerClient(
fully_qualified_namespace="<namespace>.servicebus.windows.net",
eventhub_name="my-eventhub",
consumer_group="$Default",
credential=DefaultAzureCredential(),
checkpoint_store=checkpoint_store
) as consumer:
def on_event(partition_context, event):
print(f"Received: {event.body_as_str()}")
# Checkpoint after processing
partition_context.update_checkpoint(event)
consumer.receive(on_event=on_event)Async Client
from azure.eventhub.aio import EventHubProducerClient, EventHubConsumerClient
from azure.identity.aio import DefaultAzureCredential
import asyncio
async def send_events():
credential = DefaultAzureCredential()
async with EventHubProducerClient(
fully_qualified_namespace="<namespace>.servicebus.windows.net",
eventhub_name="my-eventhub",
credential=credential
) as producer:
batch = await producer.create_batch()
batch.add(EventData("Async event"))
await producer.send_batch(batch)
async def receive_events():
async def on_event(partition_context, event):
print(event.body_as_str())
await partition_context.update_checkpoint(event)
async with EventHubConsumerClient(
fully_qualified_namespace="<namespace>.servicebus.windows.net",
eventhub_name="my-eventhub",
consumer_group="$Default",
credential=DefaultAzureCredential()
) as consumer:
await consumer.receive(on_event=on_event)
asyncio.run(send_events())Event Properties
event = EventData("My event body")
# Set properties
event.properties = {"custom_property": "value"}
event.content_type = "application/json"
# Read properties (on receive)
print(event.body_as_str())
print(event.sequence_number)
print(event.offset)
print(event.enqueued_time)
print(event.partition_key)Get Event Hub Info
with producer:
info = producer.get_eventhub_properties()
print(f"Name: {info['name']}")
print(f"Partitions: {info['partition_ids']}")
for partition_id in info['partition_ids']:
partition_info = producer.get_partition_properties(partition_id)
print(f"Partition {partition_id}: {partition_info['last_enqueued_sequence_number']}")Best Practices
Pick sync OR async and stay consistent. Do not mix
azure.xxxsync clients withazure.xxx.aioasync clients in the same call path. Choose one mode per module.Always use context managers for clients and async credentials. Wrap every client in
with Client(...) as client:(sync) orasync with Client(...) as client:(async) for proper cleanup. For asyncDefaultAzureCredentialfromazure.identity.aio, also useasync with credential:so tokens and transports are cleaned up.Use
DefaultAzureCredentialfor portable auth across local dev and Azure (avoid connection strings / API keys when possible).Use batches for sending multiple events
Use checkpoint store in production for reliable processing
Use async client for high-throughput scenarios
Use partition keys for ordered delivery within a partition
Handle batch size limits — catch ValueError when batch is full
Set appropriate consumer groups for different applications
Reference Files
| File | Contents |
|---|---|
| references/checkpointing.md | Checkpoint store patterns, blob checkpointing, checkpoint strategies |
| references/partitions.md | Partition management, load balancing, starting positions |
| scripts/setup_consumer.py | CLI for Event Hub info, consumer setup, and event sending/receiving |
Files
- ATTRIBUTION.mdAdded by AutoGineer962 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md9.1 KiB
- references/checkpointing.md9.8 KiB
- references/partitions.md10.4 KiB
- scripts/setup_consumer.pyScript13.3 KiB
references/partitions.md
Partition Management with Azure Event Hubs
Patterns for working with partitions, load balancing, and event ordering.
Understanding Partitions
Partitions enable:
Parallel processing — Multiple consumers process different partitions
Ordered delivery — Events within a partition maintain order
Scalability — More partitions = higher throughput
Get Partition Information
from azure.eventhub import EventHubProducerClient
from azure.identity import DefaultAzureCredential
producer = EventHubProducerClient(
fully_qualified_namespace="<namespace>.servicebus.windows.net",
eventhub_name="my-eventhub",
credential=DefaultAzureCredential()
)
with producer:
# Get Event Hub properties
eh_props = producer.get_eventhub_properties()
print(f"Event Hub: {eh_props['name']}")
print(f"Partitions: {eh_props['partition_ids']}")
print(f"Created: {eh_props['created_at']}")
# Get individual partition properties
for partition_id in eh_props['partition_ids']:
props = producer.get_partition_properties(partition_id)
print(f"\nPartition {partition_id}:")
print(f" First sequence: {props['beginning_sequence_number']}")
print(f" Last sequence: {props['last_enqueued_sequence_number']}")
print(f" Last offset: {props['last_enqueued_offset']}")
print(f" Last enqueued: {props['last_enqueued_time_utc']}")
print(f" Is empty: {props['is_empty']}")Sending to Specific Partitions
By Partition ID (Direct)
# Send to specific partition
batch = producer.create_batch(partition_id="0")
batch.add(EventData("Goes to partition 0"))
producer.send_batch(batch)By Partition Key (Consistent Hashing)
# Same key always goes to same partition
batch = producer.create_batch(partition_key="user-123")
batch.add(EventData("All user-123 events in same partition"))
producer.send_batch(batch)
# Different keys may go to different partitions
for user_id in ["user-1", "user-2", "user-3"]:
batch = producer.create_batch(partition_key=user_id)
batch.add(EventData(f"Event for {user_id}"))
producer.send_batch(batch)Round-Robin (Default)
# No partition_id or partition_key = round-robin distribution
batch = producer.create_batch()
batch.add(EventData("Distributed across partitions"))
producer.send_batch(batch)Partition Selection Strategies
| Strategy | Use Case | Code |
|---|---|---|
| Round-robin | Even distribution, no ordering needs | create_batch() |
| Partition key | Related events in same partition | create_batch(partition_key="...") |
| Explicit partition | Direct control | create_batch(partition_id="0") |
Receiving from Partitions
All Partitions (Load Balanced)
from azure.eventhub import EventHubConsumerClient
from azure.eventhub.extensions.checkpointstoreblob import BlobCheckpointStore
checkpoint_store = BlobCheckpointStore(...)
consumer = EventHubConsumerClient(
fully_qualified_namespace="<namespace>.servicebus.windows.net",
eventhub_name="my-eventhub",
consumer_group="$Default",
credential=DefaultAzureCredential(),
checkpoint_store=checkpoint_store # Required for load balancing
)
async def on_event(partition_context, event):
print(f"Partition {partition_context.partition_id}: {event.body_as_str()}")
await partition_context.update_checkpoint(event)
async with consumer:
# Automatically distributes partitions across consumers
await consumer.receive(on_event=on_event)Specific Partition
async with consumer:
await consumer.receive(
on_event=on_event,
partition_id="0" # Only receive from partition 0
)Load Balancing Multiple Consumers
When multiple consumers share a consumer group with a checkpoint store, partitions are automatically distributed.
Example: 3 Consumers, 8 Partitions
Consumer 1: Partitions 0, 1, 2
Consumer 2: Partitions 3, 4, 5
Consumer 3: Partitions 6, 7Partition Ownership Events
async def on_partition_initialize(partition_context):
"""Called when consumer claims a partition."""
print(f"Initialized partition {partition_context.partition_id}")
async def on_partition_close(partition_context, reason):
"""Called when consumer releases a partition."""
print(f"Closed partition {partition_context.partition_id}: {reason}")
async with consumer:
await consumer.receive(
on_event=on_event,
on_partition_initialize=on_partition_initialize,
on_partition_close=on_partition_close
)Close Reasons
| Reason | Description |
|---|---|
SHUTDOWN | Consumer is closing normally |
OWNERSHIP_LOST | Another consumer claimed this partition |
Partition Context Properties
async def on_event(partition_context, event):
# Partition info
print(f"Partition ID: {partition_context.partition_id}")
print(f"Consumer Group: {partition_context.consumer_group}")
print(f"Event Hub: {partition_context.eventhub_name}")
print(f"Namespace: {partition_context.fully_qualified_namespace}")
# Last enqueued event (if tracking enabled)
if partition_context.last_enqueued_event_properties:
props = partition_context.last_enqueued_event_properties
print(f"Last sequence: {props.sequence_number}")
print(f"Last offset: {props.offset}")
print(f"Last enqueued: {props.enqueued_time}")Track Partition Health
async def on_event(partition_context, event):
props = partition_context.last_enqueued_event_properties
if props:
# Calculate lag
current_seq = event.sequence_number
last_seq = props.sequence_number
lag = last_seq - current_seq
if lag > 1000:
print(f"WARNING: Partition {partition_context.partition_id} lag: {lag}")Parallel Partition Processing
import asyncio
from azure.eventhub.aio import EventHubConsumerClient
async def process_partition(consumer, partition_id: str):
"""Process a single partition."""
async def on_event(partition_context, event):
await process_event(event)
await partition_context.update_checkpoint(event)
await consumer.receive(
on_event=on_event,
partition_id=partition_id
)
async def parallel_consume():
consumer = EventHubConsumerClient(...)
async with consumer:
# Get all partitions
props = await consumer.get_eventhub_properties()
# Start parallel tasks for each partition
tasks = [
process_partition(consumer, pid)
for pid in props['partition_ids']
]
await asyncio.gather(*tasks)Partition-Aware Batching
class PartitionBatcher:
"""Batch events by partition for efficient sending."""
def __init__(self, producer):
self.producer = producer
self.batches: dict[str, any] = {}
async def add(self, event: EventData, partition_key: str):
if partition_key not in self.batches:
self.batches[partition_key] = await self.producer.create_batch(
partition_key=partition_key
)
try:
self.batches[partition_key].add(event)
except ValueError:
# Batch full, send and create new
await self.producer.send_batch(self.batches[partition_key])
self.batches[partition_key] = await self.producer.create_batch(
partition_key=partition_key
)
self.batches[partition_key].add(event)
async def flush(self):
for batch in self.batches.values():
if batch:
await self.producer.send_batch(batch)
self.batches.clear()Starting Positions
from azure.eventhub import EventHubConsumerClient
# From beginning
await consumer.receive(
on_event=on_event,
starting_position="-1" # Beginning of stream
)
# From end (new events only)
await consumer.receive(
on_event=on_event,
starting_position="@latest"
)
# From specific offset
await consumer.receive(
on_event=on_event,
starting_position="12345" # Specific offset
)
# From specific time
from datetime import datetime, timezone
start_time = datetime(2024, 1, 1, tzinfo=timezone.utc)
await consumer.receive(
on_event=on_event,
starting_position=start_time
)
# Different positions per partition
await consumer.receive(
on_event=on_event,
starting_position={
"0": "-1", # Partition 0 from beginning
"1": "@latest", # Partition 1 from end
"2": "5000" # Partition 2 from offset 5000
}
)Monitoring Partition Distribution
class PartitionMonitor:
def __init__(self):
self.owned_partitions: set[str] = set()
self.event_counts: dict[str, int] = {}
async def on_partition_initialize(self, partition_context):
self.owned_partitions.add(partition_context.partition_id)
print(f"Now own partitions: {self.owned_partitions}")
async def on_partition_close(self, partition_context, reason):
self.owned_partitions.discard(partition_context.partition_id)
print(f"Released {partition_context.partition_id}: {reason}")
async def on_event(self, partition_context, event):
pid = partition_context.partition_id
self.event_counts[pid] = self.event_counts.get(pid, 0) + 1
# Log distribution every 1000 events
total = sum(self.event_counts.values())
if total % 1000 == 0:
print(f"Event distribution: {self.event_counts}")Best Practices
Use partition keys for related events that need ordering
Avoid explicit partition IDs unless you have a specific reason
Scale consumers with partitions — aim for 1 consumer per partition max
Monitor lag — track difference between enqueued and processed events
Handle ownership changes — design for partitions moving between consumers
Use checkpoint stores for automatic load balancing
Start from checkpoint — let checkpoint store manage starting position
Partition count is fixed — plan capacity upfront (cannot change after creation)
Partition Limits
| Limit | Value |
|---|---|
| Min partitions | 1 |
| Max partitions (Standard) | 32 |
| Max partitions (Premium/Dedicated) | 100+ |
| Max throughput per partition | ~1 MB/s or ~1000 events/s |
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an API key, Needs Python
Security
What our scanner noticed· Low risk
- Instructions that use the network
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Microsoft
- Publisher
- Microsoft (Official)
- Source
- microsoft/skills · .github/plugins/azure-sdk-python/skills/azure-eventhub-py · commit 0696600
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Microsoft.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download azure-eventhub-py.zip