Getting Started#
This guide will help you quickly set up and start using the Notifications Service to publish and consume events.
Prerequisites#
Access to a deployed Notifications Service (Event Aggregation and Event Consumer services)
Authentication credentials (JWT token or similar)
For gRPC: Protocol Buffer compiler and gRPC libraries for your language
For REST: HTTP client library (or just curl for testing)
Authentication#
Both services require authentication. Include your bearer token in requests:
REST: Include the Authorization header:
Authorization: Bearer YOUR_TOKEN_HERE
gRPC: Include the token in metadata:
# Python example
metadata = [('authorization', f'Bearer {YOUR_TOKEN}')]
Quick Example: Publish and Consume an Event#
Let’s walk through a complete example of publishing an event and consuming it.
Step 1: Publish an Event (REST)#
curl -X POST https://your-aggregation-service.example.com/api/v1beta/events \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"event": {
"event_type": "myapp.user.created",
"message": {
"user_id": "12345",
"username": "john_doe",
"email": "john@example.com"
},
"occurred_at": "2024-10-16T14:30:00Z",
"resource": {
"resource_id": "/users/12345"
}
}
}'
Response:
{
"result": {
"event": {
"event_type": "myapp.user.created",
"message": {
"user_id": "12345",
"username": "john_doe",
"email": "john@example.com"
},
"occurred_at": "2024-10-16T14:30:00Z",
"resource": {
"resource_id": "/users/12345"
}
},
"success": true
}
}
Step 2: Consume Events (REST with SSE)#
Open a streaming connection to receive events:
curl -N https://your-consumer-service.example.com/api/v1beta/events/stream \
-H "Authorization: Bearer YOUR_TOKEN" \
-G --data-urlencode 'filter_groups=[{
"event_type": "myapp.user.created",
"filters": []
}]'
You’ll receive Server-Sent Events as they occur:
event: event
data: {
"event_type": "myapp.user.created",
"principal_identity": "publisher@example.com",
"occurred_at": "2024-10-16T14:30:00Z",
"published_at": "2024-10-16T14:30:01Z",
"message": {
"user_id": "12345",
"username": "john_doe",
"email": "john@example.com"
}
}
Quick Example: gRPC#
Step 1: Generate Client Code#
First, obtain the proto files from the released archive or protobuf registry.
Generate client code for your language:
# Python example
python -m grpc_tools.protoc \
-I./protos \
--python_out=. \
--grpc_python_out=. \
nvidia/omniverse/notifications/publisher/v1beta/event_publisher.proto \
nvidia/omniverse/notifications/consumer/v1beta/event_consumer.proto
Step 2: Publish an Event (gRPC)#
import grpc
from google.protobuf.timestamp_pb2 import Timestamp
from google.protobuf.struct_pb2 import Struct
from nvidia.omniverse.notifications.publisher.v1beta import event_publisher_pb2
from nvidia.omniverse.notifications.publisher.v1beta import event_publisher_pb2_grpc
# Create channel with credentials
credentials = grpc.ssl_channel_credentials()
channel = grpc.secure_channel(
'your-aggregation-service.example.com:50051',
credentials
)
stub = event_publisher_pb2_grpc.EventPublishingServiceStub(channel)
# Create event
message = Struct()
message.update({
'user_id': '12345',
'username': 'john_doe',
'email': 'john@example.com'
})
timestamp = Timestamp()
timestamp.GetCurrentTime()
event = event_publisher_pb2.Event(
event_type='myapp.user.created',
message=message,
occurred_at=timestamp,
resource=event_publisher_pb2.EventResource(
resource_id='/users/12345'
)
)
# Publish event
request = event_publisher_pb2.PublishEventRequest(event=event)
metadata = [('authorization', f'Bearer {YOUR_TOKEN}')]
response = stub.PublishEvent(request, metadata=metadata)
print(f"Published successfully: {response.result.success}")
Step 3: Consume Events (gRPC)#
import grpc
from nvidia.omniverse.notifications.consumer.v1beta import event_consumer_pb2
from nvidia.omniverse.notifications.consumer.v1beta import event_consumer_pb2_grpc
# Create channel with credentials
credentials = grpc.ssl_channel_credentials()
channel = grpc.secure_channel(
'your-consumer-service.example.com:50052',
credentials
)
stub = event_consumer_pb2_grpc.EventConsumerServiceStub(channel)
# Create filter groups
filter_group = event_consumer_pb2.FilterGroup(
event_type='myapp.user.created'
)
# No filters added - receive all events of this type
# Create request stream
def request_stream():
request = event_consumer_pb2.ConsumeNonDurableEventsRequest()
request.filter_groups.append(filter_group)
yield request
# Consume events
metadata = [('authorization', f'Bearer {YOUR_TOKEN}')]
responses = stub.ConsumeNonDurableEvents(request_stream(), metadata=metadata)
for response in responses:
# Process each batch of events
for event in response.events:
print(f"Received event: {event.event_type}")
print(f"Message: {event.message}")
print(f"Occurred at: {event.occurred_at}")
Common Patterns#
1. Define Your Event Types#
Before implementing, define your event type naming convention:
# Example event type definitions
USER_CREATED = "myapp.user.created"
USER_UPDATED = "myapp.user.updated"
USER_DELETED = "myapp.user.deleted"
FILE_UPLOADED = "myapp.file.uploaded"
WORKFLOW_COMPLETED = "myapp.workflow.completed"
2. Define Your Message Schemas#
Document the structure of messages for each event type:
# Example: myapp.user.created message schema
{
"user_id": str, # Required: Unique user identifier
"username": str, # Required: User's username
"email": str, # Required: User's email
"created_by": str, # Optional: Who created this user
"metadata": dict # Optional: Additional metadata
}
3. Handle Errors#
Both publishing and consuming can fail. Always handle errors appropriately:
# Publishing with error handling
try:
response = stub.PublishEvent(request, metadata=metadata)
if response.result.success:
print("Event published successfully")
else:
print(f"Failed to publish: {response.result.failure_reason}")
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.RESOURCE_EXHAUSTED:
# Retry with exponential backoff
print("Service temporarily unavailable, retrying...")
elif e.code() == grpc.StatusCode.PERMISSION_DENIED:
print("Permission denied - check your authorization")
else:
print(f"Unexpected error: {e.details()}")
Next Steps#
Now that you’ve published and consumed your first events:
Learn more about Publishing Events including batch publishing
Explore Consuming Events including durable queues and filtering
Understand Permissions & Authorization to secure your events
Review the API Reference for complete API documentation
Troubleshooting#
“Permission denied” errors#
Make sure you have the appropriate permissions configured. See the Permissions guide.
Events not being received#
Check that your filter groups match the event types being published
Verify your authentication token is valid
Ensure the publisher is successfully publishing events
Connection drops#
For non-durable queues, use the reconnect_token to reconnect to the same queue. For durable queues, just reconnect with the same queue_id.