Skip to content

feat(event_source): Event source dataclasses for IoT Core Registry Events #6123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4d58c5d
Comment out fields to work with
basvandriel Feb 17, 2025
0d6a615
work on tests
basvandriel Feb 18, 2025
7b18d10
Add docs
basvandriel Feb 18, 2025
5e6655a
Add initial doc links
basvandriel Feb 19, 2025
9b63aed
work
basvandriel Feb 19, 2025
7a9ebf9
fix links
basvandriel Feb 19, 2025
92cd5da
Add github links
basvandriel Feb 19, 2025
bcee331
work
basvandriel Feb 19, 2025
f2b3dff
Merge branch 'develop' into feature/event-source-iot-registry-events
basvandriel Feb 19, 2025
212c802
Merge branch 'develop' into feature/event-source-iot-registry-events
leandrodamascena Feb 24, 2025
d0b54f5
Merge branch 'develop' into feature/event-source-iot-registry-events
basvandriel Feb 24, 2025
0f95d3c
add files
basvandriel Feb 20, 2025
cc9f0d0
fill classes
basvandriel Feb 20, 2025
0a32947
add log statement
basvandriel Feb 20, 2025
d092614
work
basvandriel Feb 24, 2025
f4d6281
apply suggestions
basvandriel Feb 24, 2025
a727e67
Add examples for first items
basvandriel Feb 24, 2025
8e26cdf
Fix documentation
basvandriel Feb 24, 2025
6cb994f
apply suggestion
basvandriel Feb 24, 2025
c77c890
Add doc example
basvandriel Feb 24, 2025
d3a0511
Work
basvandriel Feb 24, 2025
5c04230
work
basvandriel Feb 24, 2025
1539bb5
Merge branch 'develop' into feature/event-source-iot-registry-events
leandrodamascena Feb 25, 2025
6751e09
Adding more coverage + documentation
leandrodamascena Feb 25, 2025
d79a661
Adding more coverage + documentation
leandrodamascena Feb 25, 2025
958be88
Adding more coverage + documentation
leandrodamascena Feb 25, 2025
950619b
Adding more coverage + documentation
leandrodamascena Feb 25, 2025
0fda7a5
Adding more coverage + documentation
leandrodamascena Feb 25, 2025
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
418 changes: 418 additions & 0 deletions aws_lambda_powertools/utilities/data_classes/iot_registry_event.py

Large diffs are not rendered by default.

92 changes: 92 additions & 0 deletions docs/utilities/data_classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ Each event source is linked to its corresponding GitHub file with the full set o
| [TransferFamilyAuthorizerResponse] | `TransferFamilyAuthorizerResponse` | [Github](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/utilities/data_classes/transfer_family_event.py) |
| [VPC Lattice V2](#vpc-lattice-v2) | `VPCLatticeV2Event` | [Github](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py) |
| [VPC Lattice V1](#vpc-lattice-v1) | `VPCLatticeEvent` | [Github](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py) |
| [IoT Core Thing Created/Updated/Deleted](#iot-core-thing-createdupdateddeleted) | `IoTCoreThingEvent` | [GitHub](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/utilities/data_classes/iot_registry_event.py#L33) |
| [IoT Core Thing Type Created/Updated/Deprecated/Undeprecated/Deleted](#iot-core-thing-type-createdupdateddeprecatedundeprecateddeleted) | `IoTCoreThingTypeEvent` | [GitHub](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/utilities/data_classes/iot_registry_event.py#L96) |
| [IoT Core Thing Type Associated/Disassociated with a Thing](#iot-core-thing-type-associateddisassociated-with-a-thing) | `IoTCoreThingTypeAssociationEvent` | [GitHub](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/utilities/data_classes/iot_registry_event.py#L173) |
| [IoT Core Thing Group Created/Updated/Deleted](#iot-core-thing-group-createdupdateddeleted) | `IoTCoreThingGroupEvent` | [GitHub](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/utilities/data_classes/iot_registry_event.py#L214) |
| [IoT Thing Added/Removed from Thing Group](#iot-thing-addedremoved-from-thing-group) | `IoTCoreAddOrRemoveFromThingGroupEvent` | [GitHub](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/utilities/data_classes/iot_registry_event.py#L304) |
| [IoT Child Group Added/Deleted from Parent Group](#iot-child-group-addeddeleted-from-parent-group) | `IoTCoreAddOrDeleteFromThingGroupEvent` | [GitHub](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/utilities/data_classes/iot_registry_event.py#L366) |

???+ info
The examples showcase a subset of Event Source Data Classes capabilities - for comprehensive details, leverage your IDE's
Expand Down Expand Up @@ -811,6 +817,92 @@ You can register your Lambda functions as targets within an Amazon VPC Lattice s
--8<-- "examples/event_sources/events/vpc_lattice_payload.json"
```

### IoT Core Events

#### IoT Core Thing Created/Updated/Deleted

You can use IoT Core registry events to trigger your lambda functions. More information on this specific one can be found [here](https://docs.aws.amazon.com/iot/latest/developerguide/registry-events.html#registry-events-thing).

=== "app.py"
```python hl_lines="2 5"
--8<-- "examples/event_sources/src/iot_registry_thing_event.py"
```

=== "Example Event"
```json
--8<-- "tests/events/iotRegistryEventsThingEvent.json"
```

#### IoT Core Thing Type Created/Updated/Deprecated/Undeprecated/Deleted

You can use IoT Core registry events to trigger your lambda functions. More information on this specific one can be found [here](https://docs.aws.amazon.com/iot/latest/developerguide/registry-events.html#registry-events-thingtype-crud).

=== "app.py"
```python hl_lines="2 5"
--8<-- "examples/event_sources/src/iot_registry_thing_type_event.py"
```

=== "Example Event"
```json
--8<-- "tests/events/iotRegistryEventsThingTypeEvent.json"
```

#### IoT Core Thing Type Associated/Disassociated with a Thing

You can use IoT Core registry events to trigger your lambda functions. More information on this specific one can be found [here](https://docs.aws.amazon.com/iot/latest/developerguide/registry-events.html#registry-events-thingtype-assoc).

=== "app.py"
```python hl_lines="2 5"
--8<-- "examples/event_sources/src/iot_registry_thing_type_association_event.py"
```

=== "Example Event"
```json
--8<-- "tests/events/iotRegistryEventsThingTypeAssociationEvent.json"
```

#### IoT Core Thing Group Created/Updated/Deleted

You can use IoT Core registry events to trigger your lambda functions. More information on this specific one can be found [here](https://docs.aws.amazon.com/iot/latest/developerguide/registry-events.html#registry-events-thinggroup-crud).

=== "app.py"
```python hl_lines="2 5"
--8<-- "examples/event_sources/src/iot_registry_thing_group_event.py"
```

=== "Example Event"
```json
--8<-- "tests/events/iotRegistryEventsThingGroupEvent.json"
```

#### IoT Thing Added/Removed from Thing Group

You can use IoT Core registry events to trigger your lambda functions. More information on this specific one can be found [here](https://docs.aws.amazon.com/iot/latest/developerguide/registry-events.html#registry-events-thinggroup-addremove).

=== "app.py"
```python hl_lines="2 5"
--8<-- "examples/event_sources/src/iot_registry_add_or_remove_from_thing_group_event.py"
```

=== "Example Event"
```json
--8<-- "tests/events/iotRegistryEventsAddOrRemoveFromThingGroupEvent.json"
```

#### IoT Child Group Added/Deleted from Parent Group

You can use IoT Core registry events to trigger your lambda functions. More information on this specific one can be found [here](https://docs.aws.amazon.com/iot/latest/developerguide/registry-events.html#registry-events-thinggroup-adddelete).

=== "app.py"
```python hl_lines="2 5"
--8<-- "examples/event_sources/src/iot_registry_add_or_delete_from_thing_group_event.py"
```

=== "Example Event"
```json
--8<-- "tests/events/iotRegistryEventsAddOrDeleteFromThingGroupEvent.json"
```

## Advanced

### Debugging
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from aws_lambda_powertools.utilities.data_classes import event_source
from aws_lambda_powertools.utilities.data_classes.iot_registry_event import IoTCoreAddOrDeleteFromThingGroupEvent


@event_source(data_class=IoTCoreAddOrDeleteFromThingGroupEvent)
def lambda_handler(event: IoTCoreAddOrDeleteFromThingGroupEvent, context):
print(f"Received IoT Core event type {event.event_type}")
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from aws_lambda_powertools.utilities.data_classes import event_source
from aws_lambda_powertools.utilities.data_classes.iot_registry_event import IoTCoreAddOrRemoveFromThingGroupEvent


@event_source(data_class=IoTCoreAddOrRemoveFromThingGroupEvent)
def lambda_handler(event: IoTCoreAddOrRemoveFromThingGroupEvent, context):
print(f"Received IoT Core event type {event.event_type}")
7 changes: 7 additions & 0 deletions examples/event_sources/src/iot_registry_thing_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from aws_lambda_powertools.utilities.data_classes import event_source
from aws_lambda_powertools.utilities.data_classes.iot_registry_event import IoTCoreThingEvent


@event_source(data_class=IoTCoreThingEvent)
def lambda_handler(event: IoTCoreThingEvent, context):
print(f"Received IoT Core event type {event.event_type}")
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from aws_lambda_powertools.utilities.data_classes import event_source
from aws_lambda_powertools.utilities.data_classes.iot_registry_event import IoTCoreThingGroupEvent


@event_source(data_class=IoTCoreThingGroupEvent)
def lambda_handler(event: IoTCoreThingGroupEvent, context):
print(f"Received IoT Core event type {event.event_type}")
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from aws_lambda_powertools.utilities.data_classes import event_source
from aws_lambda_powertools.utilities.data_classes.iot_registry_event import IoTCoreThingTypeAssociationEvent


@event_source(data_class=IoTCoreThingTypeAssociationEvent)
def lambda_handler(event: IoTCoreThingTypeAssociationEvent, context):
print(f"Received IoT Core event type {event.event_type}")
7 changes: 7 additions & 0 deletions examples/event_sources/src/iot_registry_thing_type_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from aws_lambda_powertools.utilities.data_classes import event_source
from aws_lambda_powertools.utilities.data_classes.iot_registry_event import IoTCoreThingTypeEvent


@event_source(data_class=IoTCoreThingTypeEvent)
def lambda_handler(event: IoTCoreThingTypeEvent, context):
print(f"Received IoT Core event type {event.event_type}")
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ def handler(event, context):
assert "stack_trace" not in log


@pytest.mark.skipif(reason="Test temporarily disabled")
def test_thread_safe_keys_encapsulation(service_name, stdout):
logger = Logger(
service=service_name,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
from datetime import datetime

from aws_lambda_powertools.utilities.data_classes.iot_registry_event import (
IoTCoreAddOrDeleteFromThingGroupEvent,
IoTCoreAddOrRemoveFromThingGroupEvent,
IoTCoreThingEvent,
IoTCoreThingGroupEvent,
IoTCoreThingTypeAssociationEvent,
IoTCoreThingTypeEvent,
)
from tests.functional.utils import load_event


def test_iotcore_thing_event():
raw_event = load_event("iotRegistryEventsThingEvent.json")
parsed_event = IoTCoreThingEvent(raw_event)

assert parsed_event.event_type == raw_event["eventType"]
assert parsed_event.operation == raw_event["operation"]
assert parsed_event.thing_id == raw_event["thingId"]
assert parsed_event.account_id == raw_event["accountId"]
assert parsed_event.thing_name == raw_event["thingName"]
assert parsed_event.version_number == raw_event["versionNumber"]
assert parsed_event.thing_type_name == raw_event.get("thingTypeName")
assert parsed_event.attributes == raw_event["attributes"]
assert parsed_event.event_id == raw_event["eventId"]

# Validate timestamp conversion
# Original field is int
expected_timestamp = datetime.fromtimestamp(
raw_event["timestamp"] / 1000 if raw_event["timestamp"] > 10**10 else raw_event["timestamp"],
)
assert parsed_event.timestamp == expected_timestamp


def test_iotcore_thing_type_event():
raw_event = load_event("iotRegistryEventsThingTypeEvent.json")
parsed_event = IoTCoreThingTypeEvent(raw_event)

assert parsed_event.event_type == raw_event["eventType"]
assert parsed_event.operation == raw_event["operation"]
assert parsed_event.event_id == raw_event["eventId"]
assert parsed_event.account_id == raw_event["accountId"]
assert parsed_event.thing_type_name == raw_event["thingTypeName"]
assert parsed_event.is_deprecated == raw_event["isDeprecated"]
assert parsed_event.deprecation_date == raw_event["deprecationDate"]
assert parsed_event.searchable_attributes == raw_event["searchableAttributes"]
assert parsed_event.propagating_attributes == raw_event["propagatingAttributes"]
assert parsed_event.description == raw_event["description"]
assert parsed_event.thing_type_id == raw_event["thingTypeId"]


def test_iotcore_thing_type_association_event():
raw_event = load_event("iotRegistryEventsThingTypeAssociationEvent.json")
parsed_event = IoTCoreThingTypeAssociationEvent(raw_event)

assert parsed_event.event_type == raw_event["eventType"]
assert parsed_event.operation == raw_event["operation"]
assert parsed_event.event_id == raw_event["eventId"]
assert parsed_event.thing_id == raw_event["thingId"]
assert parsed_event.thing_type_name == raw_event["thingTypeName"]
assert parsed_event.thing_name == raw_event["thingName"]


def test_iotcore_thing_group_event():
raw_event = load_event("iotRegistryEventsThingGroupEvent.json")
parsed_event = IoTCoreThingGroupEvent(raw_event)

assert parsed_event.event_type == raw_event["eventType"]
assert parsed_event.event_id == raw_event["eventId"]
assert parsed_event.operation == raw_event["operation"]
assert parsed_event.account_id == raw_event["accountId"]
assert parsed_event.thing_group_name == raw_event["thingGroupName"]
assert parsed_event.thing_group_id == raw_event["thingGroupId"]
assert parsed_event.version_number == raw_event["versionNumber"]
assert parsed_event.parent_group_name == raw_event["parentGroupName"]
assert parsed_event.parent_group_id == raw_event["parentGroupId"]
assert parsed_event.description == raw_event["description"]
assert parsed_event.root_to_parent_thing_groups == raw_event["rootToParentThingGroups"]
assert parsed_event.attributes == raw_event["attributes"]
assert parsed_event.dynamic_group_mapping_id == raw_event["dynamicGroupMappingId"]


def test_iotcore_add_or_remove_from_thing_group_event():
raw_event = load_event("iotRegistryEventsAddOrRemoveFromThingGroupEvent.json")
parsed_event = IoTCoreAddOrRemoveFromThingGroupEvent(raw_event)

assert parsed_event.event_type == raw_event["eventType"]
assert parsed_event.operation == raw_event["operation"]
assert parsed_event.account_id == raw_event["accountId"]
assert parsed_event.event_id == raw_event["eventId"]
assert parsed_event.group_id == raw_event["groupId"]
assert parsed_event.group_arn == raw_event["groupArn"]
assert parsed_event.thing_arn == raw_event["thingArn"]
assert parsed_event.thing_id == raw_event["thingId"]
assert parsed_event.membership_id == raw_event["membershipId"]


def test_iotcore_add_or_delete_from_thing_group_event():
raw_event = load_event("iotRegistryEventsAddOrDeleteFromThingGroupEvent.json")
parsed_event = IoTCoreAddOrDeleteFromThingGroupEvent(raw_event)

assert parsed_event.event_type == raw_event["eventType"]
assert parsed_event.event_id == raw_event["eventId"]
assert parsed_event.account_id == raw_event["accountId"]
assert parsed_event.thing_group_id == raw_event["thingGroupId"]
assert parsed_event.thing_group_name == raw_event["thingGroupName"]
assert parsed_event.child_group_id == raw_event["childGroupId"]
assert parsed_event.child_group_name == raw_event["childGroupName"]
assert parsed_event.operation == raw_event["operation"]

expected_timestamp = datetime.fromtimestamp(
raw_event["timestamp"] / 1000 if raw_event["timestamp"] > 10**10 else raw_event["timestamp"],
)
assert parsed_event.timestamp == expected_timestamp
Loading