Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/eventgrid/azure-eventgrid/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- `EventGridConsumer` is now renamed to `EventGridDeserializer`.
- `decode_cloud_event` is renamed to `deserialize_cloud_events`.
- `decode_eventgrid_event` is renamed to `deserialize_eventgrid_events`.
- `topic_hostname` is renamed to `endpoint` in the `EVentGridPublisherClient`.

**Bug Fixes**
- `EventGridEvent` has two additional required positional parameters namely, `data` and `data_version`.
Expand Down
16 changes: 8 additions & 8 deletions sdk/eventgrid/azure-eventgrid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ az eventgrid domain --create --location <location> --resource-group <resource-gr

### Authenticate the client
In order to interact with the Event Grid service, you will need to create an instance of a client.
A **topic_hostname** and **credential** are necessary to instantiate the client object.
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.
Expand All @@ -49,9 +49,9 @@ pass the key as a string into an instance of [AzureKeyCredential][azure-key-cred
from azure.core.credentials import AzureKeyCredential
from azure.eventgrid import EventGridPublisherClient

topic_hostname = "https://<name>.<region>.eventgrid.azure.net"
endpoint = "https://<name>.<region>.eventgrid.azure.net"
credential = AzureKeyCredential("<api_key>")
eg_publisher_client = EventGridPublisherClient(topic_hostname, credential)
eg_publisher_client = EventGridPublisherClient(endpoint, credential)
```

## Key concepts
Expand Down Expand Up @@ -84,17 +84,17 @@ from azure.core.credentials import AzureKeyCredential
from azure.eventgrid import EventGridPublisherClient, EventGridEvent

key = os.environ["EG_ACCESS_KEY"]
topic_hostname = os.environ["EG_TOPIC_HOSTNAME"]
endpoint = os.environ["EG_TOPIC_HOSTNAME"]

event = EventGridEvent(
subject="Door1",
data={"team": "azure-sdk"},
subject="Door1",
event_type="Azure.Sdk.Demo",
data_version="2.0"
)

credential = AzureKeyCredential(key)
client = EventGridPublisherClient(topic_hostname, credential)
client = EventGridPublisherClient(endpoint, credential)

client.send(event)
```
Expand All @@ -109,7 +109,7 @@ from azure.core.credentials import AzureKeyCredential
from azure.eventgrid import EventGridPublisherClient, CloudEvent

key = os.environ["CLOUD_ACCESS_KEY"]
topic_hostname = os.environ["CLOUD_TOPIC_HOSTNAME"]
endpoint = os.environ["CLOUD_TOPIC_HOSTNAME"]

event = CloudEvent(
type="Azure.Sdk.Sample",
Expand All @@ -118,7 +118,7 @@ event = CloudEvent(
)

credential = AzureKeyCredential(key)
client = EventGridPublisherClient(topic_hostname, credential)
client = EventGridPublisherClient(endpoint, credential)

client.send(event)
```
Expand Down
40 changes: 20 additions & 20 deletions sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
if TYPE_CHECKING:
from datetime import datetime

def generate_shared_access_signature(topic_hostname, shared_access_key, expiration_date_utc, **kwargs):
def generate_shared_access_signature(endpoint, shared_access_key, expiration_date_utc, **kwargs):
# type: (str, str, datetime, Any) -> str
""" Helper method to generate shared access signature given hostname, key, and expiration date.
:param str topic_hostname: The topic endpoint to send the events to.
:param str endpoint: The topic endpoint to send the events to.
Similar to <YOUR-TOPIC-NAME>.<YOUR-REGION-NAME>-1.eventgrid.azure.net
:param str shared_access_key: The shared access key to be used for generating the token
:param datetime.datetime expiration_date_utc: The expiration datetime in UTC for the signature.
Expand All @@ -32,39 +32,39 @@ def generate_shared_access_signature(topic_hostname, shared_access_key, expirati
:rtype: str
"""

full_topic_hostname = _get_full_topic_hostname(topic_hostname)
full_endpoint = _get_full_endpoint(endpoint)

full_topic_hostname = "{}?apiVersion={}".format(
full_topic_hostname,
full_endpoint = "{}?apiVersion={}".format(
full_endpoint,
kwargs.get('api_version', None) or constants.DEFAULT_API_VERSION
)
encoded_resource = quote(full_topic_hostname, safe=constants.SAFE_ENCODE)
encoded_resource = quote(full_endpoint, safe=constants.SAFE_ENCODE)
encoded_expiration_utc = quote(str(expiration_date_utc), safe=constants.SAFE_ENCODE)

unsigned_sas = "r={}&e={}".format(encoded_resource, encoded_expiration_utc)
signature = quote(_generate_hmac(shared_access_key, unsigned_sas), safe=constants.SAFE_ENCODE)
signed_sas = "{}&s={}".format(unsigned_sas, signature)
return signed_sas

def _get_topic_hostname_only_fqdn(topic_hostname):
if topic_hostname.startswith('http://'):
def _get_endpoint_only_fqdn(endpoint):
if endpoint.startswith('http://'):
raise ValueError("HTTP is not supported. Only HTTPS is supported.")
if topic_hostname.startswith('https://'):
topic_hostname = topic_hostname.replace("https://", "")
if topic_hostname.endswith("/api/events"):
topic_hostname = topic_hostname.replace("/api/events", "")
if endpoint.startswith('https://'):
endpoint = endpoint.replace("https://", "")
if endpoint.endswith("/api/events"):
endpoint = endpoint.replace("/api/events", "")

return topic_hostname
return endpoint

def _get_full_topic_hostname(topic_hostname):
if topic_hostname.startswith('http://'):
def _get_full_endpoint(endpoint):
if endpoint.startswith('http://'):
raise ValueError("HTTP is not supported. Only HTTPS is supported.")
if not topic_hostname.startswith('https://'):
topic_hostname = "https://{}".format(topic_hostname)
if not topic_hostname.endswith("/api/events"):
topic_hostname = "{}/api/events".format(topic_hostname)
if not endpoint.startswith('https://'):
endpoint = "https://{}".format(endpoint)
if not endpoint.endswith("/api/events"):
endpoint = "{}/api/events".format(endpoint)

return topic_hostname
return endpoint

def _generate_hmac(key, message):
decoded_key = base64.b64decode(key)
Expand Down
4 changes: 2 additions & 2 deletions sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ class EventGridEvent(InternalEventGridEvent, EventMixin):
'data_version': {'key': 'dataVersion', 'type': 'str'},
}

def __init__(self, subject, event_type, data, data_version, **kwargs):
# type: (str, str, object, str, Any) -> None
def __init__(self, data, subject, event_type, data_version, **kwargs):
# type: (object, str, str, str, Any) -> None
kwargs.setdefault('id', uuid.uuid4())
kwargs.setdefault('subject', subject)
kwargs.setdefault("event_type", event_type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

from ._models import CloudEvent, EventGridEvent, CustomEvent
from ._helpers import (
_get_topic_hostname_only_fqdn,
_get_endpoint_only_fqdn,
_get_authentication_policy,
_is_cloud_event,
_eventgrid_data_typecheck
Expand Down Expand Up @@ -59,17 +59,17 @@
class EventGridPublisherClient(object):
"""EventGrid Python Publisher Client.

:param str topic_hostname: The topic endpoint to send the events to.
:param str endpoint: The topic endpoint to send the events to.
:param credential: The credential object used for authentication which
implements SAS key authentication or SAS token authentication.
:type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential
"""

def __init__(self, topic_hostname, credential, **kwargs):
def __init__(self, endpoint, credential, **kwargs):
# type: (str, Union[AzureKeyCredential, AzureSasCredential], Any) -> None
topic_hostname = _get_topic_hostname_only_fqdn(topic_hostname)
endpoint = _get_endpoint_only_fqdn(endpoint)

self._topic_hostname = topic_hostname
self._endpoint = endpoint
self._client = EventGridPublisherClientImpl(
policies=EventGridPublisherClient._policies(credential, **kwargs),
**kwargs
Expand Down Expand Up @@ -120,17 +120,17 @@ def send(self, events, **kwargs):
pass # means it's a dictionary
kwargs.setdefault("content_type", "application/cloudevents-batch+json; charset=utf-8")
self._client.publish_cloud_event_events(
self._topic_hostname,
self._endpoint,
cast(List[InternalCloudEvent], events),
**kwargs
)
elif all(isinstance(e, EventGridEvent) for e in events) or all(isinstance(e, dict) for e in events):
kwargs.setdefault("content_type", "application/json; charset=utf-8")
for event in events:
_eventgrid_data_typecheck(event)
self._client.publish_events(self._topic_hostname, cast(List[InternalEventGridEvent], events), **kwargs)
self._client.publish_events(self._endpoint, cast(List[InternalEventGridEvent], events), **kwargs)
elif all(isinstance(e, CustomEvent) for e in events):
serialized_events = [dict(e) for e in events] # type: ignore
self._client.publish_custom_event_events(self._topic_hostname, cast(List, serialized_events), **kwargs)
self._client.publish_custom_event_events(self._endpoint, cast(List, serialized_events), **kwargs)
else:
raise ValueError("Event schema is not correct.")
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from .._policies import CloudEventDistributedTracingPolicy
from .._models import CloudEvent, EventGridEvent, CustomEvent
from .._helpers import (
_get_topic_hostname_only_fqdn,
_get_endpoint_only_fqdn,
_get_authentication_policy,
_is_cloud_event,
_eventgrid_data_typecheck
Expand Down Expand Up @@ -55,23 +55,23 @@
class EventGridPublisherClient():
"""Asynchronous EventGrid Python Publisher Client.

:param str topic_hostname: The topic endpoint to send the events to.
:param str endpoint: The topic endpoint to send the events to.
:param credential: The credential object used for authentication which implements
SAS key authentication or SAS token authentication.
:type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential
"""

def __init__(
self,
topic_hostname: str,
endpoint: str,
credential: Union[AzureKeyCredential, AzureSasCredential],
**kwargs: Any) -> None:
self._client = EventGridPublisherClientAsync(
policies=EventGridPublisherClient._policies(credential, **kwargs),
**kwargs
)
topic_hostname = _get_topic_hostname_only_fqdn(topic_hostname)
self._topic_hostname = topic_hostname
endpoint = _get_endpoint_only_fqdn(endpoint)
self._endpoint = endpoint

@staticmethod
def _policies(
Expand Down Expand Up @@ -124,7 +124,7 @@ async def send(
pass # means it's a dictionary
kwargs.setdefault("content_type", "application/cloudevents-batch+json; charset=utf-8")
await self._client.publish_cloud_event_events(
self._topic_hostname,
self._endpoint,
cast(List[InternalCloudEvent], events),
**kwargs
)
Expand All @@ -133,14 +133,14 @@ async def send(
for event in events:
_eventgrid_data_typecheck(event)
await self._client.publish_events(
self._topic_hostname,
self._endpoint,
cast(List[InternalEventGridEvent], events),
**kwargs
)
elif all(isinstance(e, CustomEvent) for e in events):
serialized_events = [dict(e) for e in events] # type: ignore
await self._client.publish_custom_event_events(
self._topic_hostname,
self._endpoint,
cast(List, serialized_events),
**kwargs
)
Expand Down
4 changes: 2 additions & 2 deletions sdk/eventgrid/azure-eventgrid/migration_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ cloud_event = {

| In v1.3 | Equivalent in v2.0 | Sample |
|---|---|---|
|`EventGridClient(credentials)`|`EventGridPublisherClient(topic_hostname, credential)`|[Sample for client construction](https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/champion_scenarios/cs5_publish_events_using_cloud_events_1.0_schema.py)|
|`EventGridClient(credentials)`|`EventGridPublisherClient(endpoint, credential)`|[Sample for client construction](https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/champion_scenarios/cs5_publish_events_using_cloud_events_1.0_schema.py)|

* Additionally, we now have an `EventGridDeserializer` that should be used to deserialize the events. This class is used only to decode data into a `CloudEvent` or an `EventGridEvent`. Hence, there are no credentials required to construct this as shown below.

Expand All @@ -79,7 +79,7 @@ The `publish_events` API is replaced with `send` in v2.0. Additionally, `send` A

| In v1.3 | Equivalent in v2.0 | Sample |
|---|---|---|
|`EventGridClient(credentials).publish_events(topic_hostname, events)`|`EventGridPublisherClient(topic_hostname, credential).send(events)`|[Sample for client construction](https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/champion_scenarios/cs5_publish_events_using_cloud_events_1.0_schema.py)|
|`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/champion_scenarios/cs5_publish_events_using_cloud_events_1.0_schema.py)|

### Consuming Events

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
from azure.core.credentials import AzureKeyCredential

topic_key = os.environ["EG_ACCESS_KEY"]
topic_hostname = os.environ["EG_TOPIC_HOSTNAME"]
endpoint = os.environ["EG_TOPIC_HOSTNAME"]

credential = AzureKeyCredential(topic_key)
client = EventGridPublisherClient(topic_hostname, credential)
client = EventGridPublisherClient(endpoint, credential)

client.send([
EventGridEvent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
from datetime import datetime, timedelta

topic_key = os.environ["EG_ACCESS_KEY"]
topic_hostname = os.environ["EG_TOPIC_HOSTNAME"]
endpoint = os.environ["EG_TOPIC_HOSTNAME"]
expiration_date_utc = datetime.utcnow() + timedelta(hours=1)

signature = generate_shared_access_signature(topic_hostname, topic_key, expiration_date_utc)
signature = generate_shared_access_signature(endpoint, topic_key, expiration_date_utc)
credential = AzureSasCredential(signature)
client = EventGridPublisherClient(topic_hostname, credential)
client = EventGridPublisherClient(endpoint, credential)

client.send([
EventGridEvent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
from azure.core.credentials import AzureKeyCredential

topic_key = os.environ["CLOUD_ACCESS_KEY"]
topic_hostname = os.environ["CLOUD_TOPIC_HOSTNAME"]
endpoint = os.environ["CLOUD_TOPIC_HOSTNAME"]

credential = AzureKeyCredential(topic_key)
client = EventGridPublisherClient(topic_hostname, credential)
client = EventGridPublisherClient(endpoint, credential)

client.send([
CloudEvent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
from azure.eventgrid import EventGridPublisherClient, CloudEvent

key = os.environ.get("CLOUD_ACCESS_KEY")
topic_hostname = os.environ["CLOUD_TOPIC_HOSTNAME"]
endpoint = os.environ["CLOUD_TOPIC_HOSTNAME"]

# authenticate client
credential = AzureKeyCredential(key)
client = EventGridPublisherClient(topic_hostname, credential)
client = EventGridPublisherClient(endpoint, credential)

team_members = ["Josh", "Kerri", "Kieran", "Laurent", "Lily", "Matt", "Soren", "Srikanta", "Swathi"] # possible values for data field

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
from azure.eventgrid import EventGridPublisherClient, CloudEvent

domain_key = os.environ["DOMAIN_ACCESS_KEY"]
domain_topic_hostname = os.environ["DOMAIN_TOPIC_HOSTNAME"]
domain_endpoint = os.environ["DOMAIN_TOPIC_HOSTNAME"]
domain_name = os.environ["DOMAIN_NAME"]


# authenticate client
credential = AzureKeyCredential(domain_key)
client = EventGridPublisherClient(domain_topic_hostname, credential)
client = EventGridPublisherClient(domain_endpoint, credential)

def publish_event():
# publish events
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
from azure.eventgrid import EventGridPublisherClient, CustomEvent

key = os.environ["CUSTOM_SCHEMA_ACCESS_KEY"]
topic_hostname = os.environ["CUSTOM_SCHEMA_TOPIC_HOSTNAME"]
endpoint = os.environ["CUSTOM_SCHEMA_TOPIC_HOSTNAME"]

def publish_event():
# authenticate client
credential = AzureKeyCredential(key)
client = EventGridPublisherClient(topic_hostname, credential)
client = EventGridPublisherClient(endpoint, credential)

custom_schema_event = {
"customSubject": "sample",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
from azure.eventgrid import EventGridPublisherClient, EventGridEvent

key = os.environ["EG_ACCESS_KEY"]
topic_hostname = os.environ["EG_TOPIC_HOSTNAME"]
endpoint = os.environ["EG_TOPIC_HOSTNAME"]

# authenticate client
credential = AzureKeyCredential(key)
client = EventGridPublisherClient(topic_hostname, credential)
client = EventGridPublisherClient(endpoint, credential)

team_members = ["Josh", "Kerri", "Kieran", "Laurent", "Lily", "Matt", "Soren", "Srikanta", "Swathi"] # possible values for data field

Expand Down
Loading