From eb2b0415b4472cda57d1bcbbd777ec89a8dd7a60 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Wed, 24 Feb 2021 11:38:23 -0800 Subject: [PATCH 1/6] intital --- sdk/eventgrid/azure-eventgrid/README.md | 29 +++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 8702858a8ed6..9db41f4f802f 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -2,7 +2,7 @@ Azure Event Grid is a fully-managed intelligent event routing service that allows for uniform event consumption using a publish-subscribe model. -[Source code][python-eg-src] | [Package (PyPI)][python-eg-pypi] | [API reference documentation][python-eg-ref-docs]| [Product documentation][python-eg-product-docs] | [Samples][python-eg-samples]| [Changelog][python-eg-changelog] +[Source code][python-eg-src] | [Package (PyPI)][python-eg-pypi] | [API reference documentation][python-eg-ref-docs] | [Product documentation][python-eg-product-docs] | [Samples][python-eg-samples] | [Changelog][python-eg-changelog] ## Getting started @@ -38,30 +38,48 @@ In order to interact with the Event Grid service, you will need to create an ins An **endpoint** and **credential** are necessary to instantiate the client object. #### Looking up the endpoint -You can find the endpoint and the hostname on the Azure portal. +You can find the topic endpoint within the Event Grid Topic resource on the Azure portal. This will look like: +`"https://..eventgrid.azure.net/api/events"` +The topic hostname is the URL host component of this endpoint, which will be in the format: +`"https://..eventgrid.azure.net"` #### Create the client with AzureKeyCredential -To use an API key as the `credential` parameter, +To use an Access key as the `credential` parameter, pass the key as a string into an instance of [AzureKeyCredential][azure-key-credential]. +> **Note:** The Access Key may be found in the azure portal in the "Access Keys" menu of the Event Grid Topic resource. They may also be obtained via the azure CLI, or the `azure-mgmt-eventgrid` library. A guide for getting access keys can be found [here](https://docs.microsoft.com/azure/event-grid/get-access-keys). + ```python from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridPublisherClient endpoint = "https://..eventgrid.azure.net" -credential = AzureKeyCredential("") +credential = AzureKeyCredential("") eg_publisher_client = EventGridPublisherClient(endpoint, credential) ``` +> **Note:** A client may also be authenticated via SAS signature, using the `AzureSasCredential`. A sample demonstrating this, is available [here][python-eg-sample-publish-sas-signature] ([async_version][python-eg-sample-publish-sas-signature-async]). + +> **Note:** The `generate_sas` method can be used to generate a shared access signature. A sample demonstrating this can be seen [here][python-eg-generate-sas]. ## Key concepts Information about the key concepts on Event Grid, see [Concepts in Azure Event Grid][publisher-service-doc] +### Topic +A channel within the EventGrid service to send events. Event must be of [CloudEvent](https://docs.microsoft.com/azure/event-grid/cloud-event-schema) or [EventGridEvent](https://docs.microsoft.com/azure/event-grid/event-schema) schema which is decided at creation time. In the case of wrong event type being used, errors will be raised. + +### Domain +An event domain is a management tool for large numbers of Event Grid topics related to the same application. They allow you to publish events to thousands of topics. Domains also give you authorization and authentication control over each topic. For more explanation, visit [Event domain overview](https://docs.microsoft.com/azure/event-grid/event-domains). + +When you create an event domain, you're given a publishing endpoint similar to if you had created a topic in Event Grid. The only difference is that you must specify the topic you'd like the event to be delivered to. + ### EventGridPublisherClient `EventGridPublisherClient` provides operations to send event data to topic hostname specified during client initialization. CloudEvents and EventGridEvents can be sent either as a single event or a list of respective typed objects or their equivalent dict representations. To send a custom schema, a dict representation can be used. Please have a look at the [samples](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventgrid/azure-eventgrid/samples) for detailed examples. + **Note:** It is important to know if your topic supports Cloud or EventGrid events before publishing. If you send to a topic that does not support the schema of the event you are sending, send() will throw an exception. + ## Examples The following sections provide several code snippets covering some of the most common Event Grid tasks, including: @@ -180,6 +198,9 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con [azure_core_ref_docs]: https://aka.ms/azsdk/python/core/docs [azure_subscription]: https://azure.microsoft.com/free/ +[python-eg-sample-publish-sas-signature]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py +[python-eg-sample-publish-sas-signature-async]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py +[python-eg-generate-sas]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_generate_sas.py [python-eg-sample-egevent]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py [python-eg-sample-egevent-to-domain]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py [python-eg-sample-send-cloudevent]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py From 23f6619d739a2070f328bc8073833d51fe1bd847 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Sun, 28 Feb 2021 18:54:17 -0800 Subject: [PATCH 2/6] read me improvements --- sdk/eventgrid/azure-eventgrid/README.md | 176 ++++++++++++++++-- .../azure-eventgrid/samples/README.md | 2 + ...le_publish_cloud_event_using_dict_async.py | 2 +- ...nts_using_cloud_events_1.0_schema_async.py | 2 +- ...consume_cloud_events_from_storage_queue.py | 2 +- ...eventgrid_events_from_service_bus_queue.py | 2 +- 6 files changed, 170 insertions(+), 16 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 9db41f4f802f..100c57569c9d 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -8,7 +8,8 @@ Azure Event Grid is a fully-managed intelligent event routing service that allow ### Prerequisites * Python 2.7, or 3.5 or later is required to use this package. -* You must have an [Azure subscription][azure_subscription] and an Event Grid Topic resource to use this package. +* You must have an [Azure subscription][azure_subscription] and an Event Grid Topic resource to use this package. Follow this [step-by-step tutorial](https://docs.microsoft.com/azure/event-grid/custom-event-quickstart-portal) to register the Event Grid resource provider and create Event Grid topics using the [Azure portal](https://portal.azure.com/). There is a [similar tutorial](https://docs.microsoft.com/azure/event-grid/custom-event-quickstart) using [Azure CLI](https://docs.microsoft.com/cli/azure). + ### Install the package Install the Azure Event Grid client library for Python with [pip][pip]: @@ -74,9 +75,30 @@ An event domain is a management tool for large numbers of Event Grid topics rela When you create an event domain, you're given a publishing endpoint similar to if you had created a topic in Event Grid. The only difference is that you must specify the topic you'd like the event to be delivered to. +### Event schemas +An **event** is the smallest amount of information that fully describes something that happened in the system. Event Grid supports multiple schemas for encoding events. When a custom topic or domain is created, you specify the schema that will be used when publishing events. + +#### Event Grid schema +While you may configure your topic to use a custom schema, it is more common to use the already-defined Event Grid schema. See the specifications and requirements [here](https://docs.microsoft.com/azure/event-grid/event-schema). + +#### CloudEvents v1.0 schema +Another option is to use the CloudEvents v1.0 schema. [CloudEvents](https://cloudevents.io/) is a Cloud Native Computing Foundation project which produces a specification for describing event data in a common way. The service summary of CloudEvents can be found [here](https://docs.microsoft.com/azure/event-grid/cloud-event-schema). + ### EventGridPublisherClient -`EventGridPublisherClient` provides operations to send event data to topic hostname specified during client initialization. -CloudEvents and EventGridEvents can be sent either as a single event or a list of respective typed objects or their equivalent dict representations. To send a custom schema, a dict representation can be used. Please have a look at the [samples](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventgrid/azure-eventgrid/samples) for detailed examples. +`EventGridPublisherClient` provides operations to send event data to a topic hostname specified during client initialization. + +Regardless of what schema your topic or domain is configured to use, `EventGridPublisherClient` will be used to publish events to it. Use the `send` method publishing events. + +The following formats of events are allowed to be sent: +- A list or a single instance of strongly typed EventGridEvents. +- A dict representation of a serialized EventGridEvent object. +- A list or a single instance of strongly typed CloudEvents. +- A dict representation of a serialized CloudEvent object. + +- A dict representation of any Custom Schema. + +Please have a look at the [samples](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventgrid/azure-eventgrid/samples) for detailed examples. + **Note:** It is important to know if your topic supports Cloud or EventGrid events before publishing. If you send to a topic that does not support the schema of the event you are sending, send() will throw an exception. @@ -86,6 +108,8 @@ The following sections provide several code snippets covering some of the most c * [Send an Event Grid Event](#send-an-event-grid-event) * [Send a Cloud Event](#send-a-cloud-event) +* [Consume a payload from storage queue](#consume-from-storage-queue) +* [Consume from ServiceBus](#consume-from-servicebus) ### Send an Event Grid Event @@ -135,6 +159,103 @@ client = EventGridPublisherClient(endpoint, credential) client.send(event) ``` +### Consume from storage queue + +This example consumes a message received from storage queue and deserializes it to a CloudEvent object. + +```Python +from azure.eventgrid import CloudEvent +from azure.storage.queue import QueueServiceClient, BinaryBase64DecodePolicy +import os +import json + +# all types of CloudEvents below produce same DeserializedEvent +connection_str = os.environ['STORAGE_QUEUE_CONN_STR'] +queue_name = os.environ['STORAGE_QUEUE_NAME'] + +with QueueServiceClient.from_connection_string(connection_str) as qsc: + payload = qsc.get_queue_client( + queue=queue_name, + message_decode_policy=BinaryBase64DecodePolicy() + ).peek_messages() + + ## deserialize payload into a list of typed Events + events = [CloudEvent.from_dict(json.loads(msg.content)) for msg in payload] +``` + +### Consume from storage queue + +This example consumes a payload message received from ServiceBus and deserializes it to an EventGridEvent object. + +```Python +from azure.eventgrid import EventGridEvent +from azure.servicebus import ServiceBusClient +import os +import json + +# all types of EventGridEvents below produce same DeserializedEvent +connection_str = os.environ['SERVICE_BUS_CONN_STR'] +queue_name = os.environ['SERVICE_BUS_QUEUE_NAME'] + +with ServiceBusClient.from_connection_string(connection_str) as sb_client: + payload = sb_client.get_queue_receiver(queue_name).receive_messages() + + ## deserialize payload into a list of typed Events + events = [EventGridEvent.from_dict(json.loads(next(msg.body).decode('utf-8'))) for msg in payload] +``` + +## Distributed Tracing with EventGrid + +You can use opentelemetry for Python as usual with EventGrid since it's compatible with azure-core tracing integration. + +Here is an example of how you would use Opentelemetry to send a CloudEvent. + +First, OpenTelemetry as enabled tracing plugin for EventGrid. + +```python +from azure.core.settings import settings +from azure.core.tracing.ext.opentelemetry_span import OpenTelemetrySpan + +settings.tracing_implementation = OpenTelemetrySpan +``` + +Regular open telemetry usage from here. See [Opentelemetry](https://github.com/open-telemetry/opentelemetry-python) for details. +This example uses a simple console exporter to export the traces. Any exporter can be used here including `azure-monitor-opentelemetry-exporter`, `jaeger`, `zipkin` etc. + +```python +from opentelemetry import trace +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import ConsoleSpanExporter +from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor + +# Simple console exporter +exporter = ConsoleSpanExporter() + +trace.set_tracer_provider(TracerProvider()) +tracer = trace.get_tracer(__name__) +trace.get_tracer_provider().add_span_processor( + SimpleExportSpanProcessor(exporter) +) +``` + +Once the `tracer` and `exporter` are set, please follow the example below to start collecting traces while sending a Cloud Event object using the `send` method from the `EventGridPublosherClient`. + +```python +import os +from azure.eventgrid import EventGridPublisherClient, CloudEvent +from azure.core.credentials import AzureKeyCredential + +hostname = os.environ['CLOUD_TOPIC_HOSTNAME'] +key = AzureKeyCredential(os.environ['CLOUD_ACCESS_KEY']) +cloud_event = CloudEvent( + source = 'demo', + type = 'sdk.demo', + data = {'test': 'hello'}, +) +with tracer.start_as_current_span(name="MyApplication"): + client = EventGridPublisherClient(hostname, key) + client.send(cloud_event) +``` ## Troubleshooting @@ -163,12 +284,28 @@ The following section provides several code snippets illustrating common pattern These code samples show common champion scenario operations with the Azure Event Grid client library. -* Publish EventGrid Events to a topic: [sample_publish_eg_events_to_a_topic.py][python-eg-sample-egevent] -* Publish EventGrid Events to a domain: [sample_publish_eg_events_to_a_domain.py][python-eg-sample-egevent-to-domain] -* Publish a Cloud Event: [sample_publish_events_using_cloud_events_1.0_schema.py][python-eg-sample-send-cloudevent] +* Generate Shared Access Signature: [sample_generate_sas.py][python-eg-generate-sas] + +* Authenticate the client: [sample_authentication.py][python-eg-auth] ([async_version][python-eg-auth-async]) + +* Publish events to a topic using SAS: [sample_publish_events_to_a_topic_using_sas_credential_async.py][python-eg-sample-send-using-sas] ([async_version][python-eg-sample-send-using-sas-async]) +* Publish Event Grid Events to a topic: [sample_publish_eg_events_to_a_topic.py][python-eg-sample-eg-event] ([async_version][python-eg-sample-eg-event-async]) +* Publish EventGrid Events to a domain topic: [sample_publish_eg_events_to_a_domain_topic.py][python-eg-sample-eg-event-to-domain] ([async_version][python-eg-sample-eg-event-to-domain-async]) +* Publish a Cloud Event: [sample_publish_events_using_cloud_events_1.0_schema.py][python-eg-sample-send-cloudevent] ([async_version][python-eg-sample-send-cloudevent-async]) +* Publish a Custom Schema: [sample_publish_custom_schema_to_a_topic.py][python-eg-publish-custom-schema] ([async_version][python-eg-publish-custom-schema-async]) + +To publish events, dict representation of the models could also be used as follows: +* Publish EventGridEvent as dict like representation: [sample_publish_eg_event_using_dict.py][python-eg-sample-send-eg-as-dict] ([async_version][python-eg-sample-send-eg-as-dict-async]) + +* Publish CloudEvent as dict like representation: [sample_publish_cloud_event_using_dict.py][python-eg-sample-send-cloudevent-as-dict] ([async_version][python-eg-sample-send-cloudevent-as-dict-async]) + +* Consume a Custom Payload of raw cloudevent data: [sample_consume_custom_payload.py][python-eg-sample-consume-custom-payload] More samples can be found [here][python-eg-samples]. +* More samples related to the send scenario can be seen [here][python-eg-publish-samples]. +* To see more samples related to consuming a payload from different messaging services as a typed object, please visit [Consume Samples][python-eg-consume-samples] + ### Additional documentation For more extensive documentation on Azure Event Grid, see the [Event Grid documentation][python-eg-product-docs] on docs.microsoft.com. @@ -198,13 +335,28 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con [azure_core_ref_docs]: https://aka.ms/azsdk/python/core/docs [azure_subscription]: https://azure.microsoft.com/free/ -[python-eg-sample-publish-sas-signature]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py -[python-eg-sample-publish-sas-signature-async]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py -[python-eg-generate-sas]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_generate_sas.py -[python-eg-sample-egevent]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py -[python-eg-sample-egevent-to-domain]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py +[python-eg-auth]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py +[python-eg-generate-sas]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_generate_sas.py +[python-eg-sample-send-using-sas]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py +[python-eg-sample-eg-event]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py +[python-eg-sample-eg-event-to-domain]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py [python-eg-sample-send-cloudevent]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py -[publisher-service-doc]: https://docs.microsoft.com/azure/event-grid/concepts +[python-eg-publish-custom-schema]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py +[python-eg-sample-send-eg-as-dict]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py +[python-eg-sample-send-cloudevent-as-dict]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py + +[python-eg-auth-async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py +[python-eg-sample-send-using-sas-async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py +[python-eg-sample-eg-event-async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py +[python-eg-sample-eg-event-to-domain-async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py +[python-eg-sample-send-cloudevent-async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py +[python-eg-publish-custom-schema-async]:https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py +[python-eg-sample-send-eg-as-dict-async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py +[python-eg-sample-send-cloudevent-as-dict-async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py + +[python-eg-publish-samples]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/publish_samples +[python-eg-consume-samples]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/consume_samples +[python-eg-sample-consume-custom-payload]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py [cla]: https://cla.microsoft.com [code_of_conduct]: https://opensource.microsoft.com/codeofconduct/ diff --git a/sdk/eventgrid/azure-eventgrid/samples/README.md b/sdk/eventgrid/azure-eventgrid/samples/README.md index 7d6b396200ab..68ebc6dfb929 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/README.md +++ b/sdk/eventgrid/azure-eventgrid/samples/README.md @@ -71,4 +71,6 @@ To publish events, dict representation of the models could also be used as follo [python-eg-publish-samples]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/publish_samples [python-eg-consume-samples]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/consume_samples +[python-eg-sample-consume-custom-payload]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py + [publisher-service-doc]: https://docs.microsoft.com/azure/event-grid/concepts diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py index 41e6af899021..db958983fb53 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py @@ -30,7 +30,7 @@ async def publish(): # [START publish_cloud_event_dict_async] async with client: - client.send([ + await client.send([ { "type": "Contoso.Items.ItemReceived", "source": "/contoso/items", diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py index a957db463337..24a881e51eb5 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py @@ -28,7 +28,7 @@ async def publish(): credential = AzureKeyCredential(topic_key) client = EventGridPublisherClient(endpoint, credential) - client.send([ + await client.send([ CloudEvent( type="Contoso.Items.ItemReceived", source="/contoso/items", diff --git a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py index 68a7b6e4a56b..919183405d4d 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py +++ b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py @@ -29,7 +29,7 @@ message_decode_policy=BinaryBase64DecodePolicy() ).peek_messages() - ## deserialize payload into a lost of typed Events + ## deserialize payload into a list of typed Events events = [CloudEvent.from_dict(json.loads(msg.content)) for msg in payload] for event in events: diff --git a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_eventgrid_events_from_service_bus_queue.py b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_eventgrid_events_from_service_bus_queue.py index 6ea2c8c694a8..a99f98f4fb7f 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_eventgrid_events_from_service_bus_queue.py +++ b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_eventgrid_events_from_service_bus_queue.py @@ -25,7 +25,7 @@ with ServiceBusClient.from_connection_string(connection_str) as sb_client: payload = sb_client.get_queue_receiver(queue_name).receive_messages() - ## deserialize payload into a lost of typed Events + ## deserialize payload into a list of typed Events events = [EventGridEvent.from_dict(json.loads(next(msg.body).decode('utf-8'))) for msg in payload] for event in events: From ec1897bd9b61a66ee1aee6c54e4bdfa7ecd70712 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Sun, 28 Feb 2021 19:02:54 -0800 Subject: [PATCH 3/6] migration guide --- sdk/eventgrid/azure-eventgrid/README.md | 2 +- .../azure-eventgrid/migration_guide.md | 25 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 100c57569c9d..082b748b99e4 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -183,7 +183,7 @@ with QueueServiceClient.from_connection_string(connection_str) as qsc: events = [CloudEvent.from_dict(json.loads(msg.content)) for msg in payload] ``` -### Consume from storage queue +### Consume from servicebus This example consumes a payload message received from ServiceBus and deserializes it to an EventGridEvent object. diff --git a/sdk/eventgrid/azure-eventgrid/migration_guide.md b/sdk/eventgrid/azure-eventgrid/migration_guide.md index 82df62e6f7e9..cedaa9067263 100644 --- a/sdk/eventgrid/azure-eventgrid/migration_guide.md +++ b/sdk/eventgrid/azure-eventgrid/migration_guide.md @@ -36,7 +36,7 @@ The modern Event Grid client library also provides the ability to share in some The v2.x major version comes with support for [CloudEvents](https://github.com/cloudevents/spec). Now the cloud native Cloud Events can be directly published using the `CloudEvent` constructor or as a dictionary as follows: ```Python -from azure.eventgrid import CloudEvent +from azure.core.messaging import CloudEvent cloud_event = CloudEvent( type="Contoso.Items.ItemReceived", @@ -73,6 +73,29 @@ The `publish_events` API is replaced with `send` in v2.0. Additionally, `send` A |---|---|---| |`EventGridClient(credentials).publish_events(topic_hostname, events)`|`EventGridPublisherClient(endpoint, credential).send(events)`|[Sample for client construction](https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py)| +### Consuming Events + +The v2.x major version supports deserializing dictionaries into strongly typed objects. The `from_dict` methods in the `CloudEvent` and `EventGridEvent` models can be used for the same. + +This example consumes a payload message received from ServiceBus and deserializes it to an EventGridEvent object. + +```Python +from azure.eventgrid import EventGridEvent +from azure.servicebus import ServiceBusClient +import os +import json + +# all types of EventGridEvents below produce same DeserializedEvent +connection_str = os.environ['SERVICE_BUS_CONN_STR'] +queue_name = os.environ['SERVICE_BUS_QUEUE_NAME'] + +with ServiceBusClient.from_connection_string(connection_str) as sb_client: + payload = sb_client.get_queue_receiver(queue_name).receive_messages() + + ## deserialize payload into a list of typed Events + events = [EventGridEvent.from_dict(json.loads(next(msg.body).decode('utf-8'))) for msg in payload] +``` + ## Additional samples More examples can be found at [here](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventgrid/azure-eventgrid/samples) From ae06cbe49d13640e6ae30e1707aa330522eff7d4 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Sun, 28 Feb 2021 19:16:17 -0800 Subject: [PATCH 4/6] blundera --- sdk/eventgrid/azure-eventgrid/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 082b748b99e4..d2f85afbd9c2 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -208,9 +208,9 @@ with ServiceBusClient.from_connection_string(connection_str) as sb_client: You can use opentelemetry for Python as usual with EventGrid since it's compatible with azure-core tracing integration. -Here is an example of how you would use Opentelemetry to send a CloudEvent. +Here is an example of how you would use Opentelemetry to trace sending a CloudEvent. -First, OpenTelemetry as enabled tracing plugin for EventGrid. +First, set OpenTelemetry as enabled tracing plugin for EventGrid. ```python from azure.core.settings import settings From 3413a64395b1227e9a77f0f652aadc6b1cf3c68a Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Sun, 28 Feb 2021 19:27:32 -0800 Subject: [PATCH 5/6] nit --- sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py index c886e78553a6..b1c68a24d5f2 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py @@ -166,7 +166,7 @@ class EventGridEvent(InternalEventGridEvent, EventMixin): If not provided, will be stamped with an empty value. :type data_version: str :keyword topic: Optional. The resource path of the event source. If not provided, Event Grid will - stamp onto the event. + stamp onto the event. This is required when sending event(s) to a domain. :type topic: str :keyword metadata_version: Optional. The schema version of the event metadata. If provided, must match Event Grid Schema exactly. If not provided, EventGrid will stamp onto event. From 1d4955e6ccef8a6b5589a3581ebb2e76d3766c3b Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Mon, 1 Mar 2021 13:19:00 -0800 Subject: [PATCH 6/6] Apply suggestions from code review Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> --- sdk/eventgrid/azure-eventgrid/README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index d2f85afbd9c2..9629b210e18b 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -68,18 +68,20 @@ eg_publisher_client = EventGridPublisherClient(endpoint, credential) Information about the key concepts on Event Grid, see [Concepts in Azure Event Grid][publisher-service-doc] ### Topic -A channel within the EventGrid service to send events. Event must be of [CloudEvent](https://docs.microsoft.com/azure/event-grid/cloud-event-schema) or [EventGridEvent](https://docs.microsoft.com/azure/event-grid/event-schema) schema which is decided at creation time. In the case of wrong event type being used, errors will be raised. +A [topic](https://docs.microsoft.com/azure/event-grid/concepts#topics) is a channel within the EventGrid service to send events. The event schema that a topic accepts is decided at topic creation time. If events of a schema type are sent to a topic that requires a different schema type, errors will be raised. ### Domain -An event domain is a management tool for large numbers of Event Grid topics related to the same application. They allow you to publish events to thousands of topics. Domains also give you authorization and authentication control over each topic. For more explanation, visit [Event domain overview](https://docs.microsoft.com/azure/event-grid/event-domains). +An event [domain](https://docs.microsoft.com/azure/event-grid/event-domains) is a management tool for large numbers of Event Grid topics related to the same application. They allow you to publish events to thousands of topics. Domains also give you authorization and authentication control over each topic. For more information, visit [Event domain overview](https://docs.microsoft.com/azure/event-grid/event-domains). -When you create an event domain, you're given a publishing endpoint similar to if you had created a topic in Event Grid. The only difference is that you must specify the topic you'd like the event to be delivered to. +When you create an event domain, a publishing endpoint for this domain is made available to you. This process is similar to creating an Event Grid Topic. The only difference is that, when publishing to a domain, you must specify the topic within the domain that you'd like the event to be delivered to. ### Event schemas -An **event** is the smallest amount of information that fully describes something that happened in the system. Event Grid supports multiple schemas for encoding events. When a custom topic or domain is created, you specify the schema that will be used when publishing events. +An [**event**](https://docs.microsoft.com/azure/event-grid/concepts#events) is the smallest amount of information that fully describes something that happened in the system. When a custom topic or domain is created, you must specify the schema that will be used when publishing events. + +Event Grid supports multiple schemas for encoding events. #### Event Grid schema -While you may configure your topic to use a custom schema, it is more common to use the already-defined Event Grid schema. See the specifications and requirements [here](https://docs.microsoft.com/azure/event-grid/event-schema). +While you may configure your topic to use a [custom schema](https://docs.microsoft.com/azure/event-grid/input-mappings), it is more common to use the already-defined Event Grid schema. See the specifications and requirements [here](https://docs.microsoft.com/azure/event-grid/event-schema). #### CloudEvents v1.0 schema Another option is to use the CloudEvents v1.0 schema. [CloudEvents](https://cloudevents.io/) is a Cloud Native Computing Foundation project which produces a specification for describing event data in a common way. The service summary of CloudEvents can be found [here](https://docs.microsoft.com/azure/event-grid/cloud-event-schema). @@ -87,7 +89,7 @@ Another option is to use the CloudEvents v1.0 schema. [CloudEvents](https://clou ### EventGridPublisherClient `EventGridPublisherClient` provides operations to send event data to a topic hostname specified during client initialization. -Regardless of what schema your topic or domain is configured to use, `EventGridPublisherClient` will be used to publish events to it. Use the `send` method publishing events. +Regardless of the schema that your topic or domain is configured to use, `EventGridPublisherClient` will be used to publish events to it. Use the `send` method publishing events. The following formats of events are allowed to be sent: - A list or a single instance of strongly typed EventGridEvents. @@ -208,7 +210,7 @@ with ServiceBusClient.from_connection_string(connection_str) as sb_client: You can use opentelemetry for Python as usual with EventGrid since it's compatible with azure-core tracing integration. -Here is an example of how you would use Opentelemetry to trace sending a CloudEvent. +Here is an example of using OpenTelemetry to trace sending a CloudEvent. First, set OpenTelemetry as enabled tracing plugin for EventGrid. @@ -219,7 +221,7 @@ from azure.core.tracing.ext.opentelemetry_span import OpenTelemetrySpan settings.tracing_implementation = OpenTelemetrySpan ``` -Regular open telemetry usage from here. See [Opentelemetry](https://github.com/open-telemetry/opentelemetry-python) for details. +Regular open telemetry usage from here. See [OpenTelemetry](https://github.com/open-telemetry/opentelemetry-python) for details. This example uses a simple console exporter to export the traces. Any exporter can be used here including `azure-monitor-opentelemetry-exporter`, `jaeger`, `zipkin` etc. ```python @@ -238,7 +240,7 @@ trace.get_tracer_provider().add_span_processor( ) ``` -Once the `tracer` and `exporter` are set, please follow the example below to start collecting traces while sending a Cloud Event object using the `send` method from the `EventGridPublosherClient`. +Once the `tracer` and `exporter` are set, please follow the example below to start collecting traces while using the `send` method from the `EventGridPublisherClient` to send a CloudEvent object. ```python import os @@ -294,7 +296,7 @@ These code samples show common champion scenario operations with the Azure Event * Publish a Cloud Event: [sample_publish_events_using_cloud_events_1.0_schema.py][python-eg-sample-send-cloudevent] ([async_version][python-eg-sample-send-cloudevent-async]) * Publish a Custom Schema: [sample_publish_custom_schema_to_a_topic.py][python-eg-publish-custom-schema] ([async_version][python-eg-publish-custom-schema-async]) -To publish events, dict representation of the models could also be used as follows: +The following samples cover publishing and consuming `dict` representations of EventGridEvents and CloudEvents. * Publish EventGridEvent as dict like representation: [sample_publish_eg_event_using_dict.py][python-eg-sample-send-eg-as-dict] ([async_version][python-eg-sample-send-eg-as-dict-async]) * Publish CloudEvent as dict like representation: [sample_publish_cloud_event_using_dict.py][python-eg-sample-send-cloudevent-as-dict] ([async_version][python-eg-sample-send-cloudevent-as-dict-async])