Skip to content

Commit

Permalink
Release of Version 1.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
seanc-amazon committed Nov 27, 2018
1 parent 1865d02 commit f242d01
Show file tree
Hide file tree
Showing 22 changed files with 1,268 additions and 203 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
=========
CHANGELOG
=========

1.3.0
======

SDK supports SecretsManager client.


1.2.0
======

SDK and GGC compatibility check takes place in the background.


1.1.0
======
Lambda only accepted payload in JSON format. With this update, Invoking or publishing binary payload to a lambda is supported.
402 changes: 201 additions & 201 deletions LICENSE

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include *.txt *.py
recursive-include *.txt *.py
2 changes: 0 additions & 2 deletions README.md

This file was deleted.

69 changes: 69 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
Greengrass SDK
=====================

The AWS Greengrass Core SDK is meant to be used by AWS Lambda functions running on an AWS Greengrass Core. It will enable Lambda functions to invoke other Lambda functions deployed to the Greengrass Core, publish messages to the Greengrass Core and work with the local Shadow service.
You can find the latest, most up to date, documentation at our `doc site <http://aws-greengrass-core-sdk-python-docs.s3-website-us-east-1.amazonaws.com/v1.3.0/index.html>`_.

===============================
Using AWS Greengrass Core SDK
===============================

To use the AWS Greengrass Core SDK, you must first import the AWS Greengrass Core SDK in your Lambda function as you would with any other external libraries. You then need to create a client for 'iot-data' or 'lambda'. Use 'iot-data' if you wish to publish messages to the local AWS Greengrass Core and interact with the local Shadow service. Use 'lambda' if you wish to invoke other Lambda functions deployed to the same AWS Greengrass Core.

Here is an example for using the 'iot-data' client

.. code-block:: python
import greengrasssdk
# Let's instantiate the iot-data client
client = greengrasssdk.client('iot-data')
Now that you have an ``iot-data`` client, you can publish requests.

.. code-block:: python
response = client.publish(
topic='someTopic',
payload='some data'.encode()
)
Here is an example for using the 'lambda' client.

.. code-block:: python
import greengrasssdk
client = greengrasssdk.client('lambda')
Now that you have a lambda client, you can publish requests.

.. code-block:: python
# Define the payload to pass to the invoked lambda function
msg = json.dumps({
'message':"hello"
})
# Invoke the lambda function
response = client.invoke(
FunctionName='arn:aws:lambda:<region>:<account id>:function:<function name>',
InvocationType='RequestResponse',
Payload=payload,
Qualifier='2'
)
==============
Compatibility
==============

As new features are added to AWS Greengrass, previous versions of the Greengrass SDK will be incompatible with newer versions of the AWS Greengrass core. The following table lists the compatible SDKs for all GGC releases.

+-------------+------------------------+
| GGC Version | Compatible SDK Versions|
+=============+========================+
| 1.0.x-1.6.x | 1.0.x-1.2.x |
+-------------+------------------------+
| 1.7.x | 1.0.x-1.3.x |
+-------------+------------------------+
14 changes: 14 additions & 0 deletions examples/BinaryLambdaInvoke/invokee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#
# Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
import sys
import logging

# Setup logging to stdout
logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)


def handler(event, context):
logger.info('Invoked with payload ' + str(event))
return 'Invoked successfully'
42 changes: 42 additions & 0 deletions examples/BinaryLambdaInvoke/invoker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#
# Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#

# This example demonstrates invoking a lambda with 'binary' encoding type. In
# order to run this example, remember to mark your 'invokee' lambda as a binary
# lambda. You can configure this on the lambda configuration page in the
# console. After the lambdas get deployed to your Greengrass Core, you should
# be able to see 'Invoked successfully' returned by 'invokee' lambda. A lambda
# function can support non-json payload, which is a new feature introduced in
# GGC version 1.5.
#
import sys
import base64
import logging
import json
import greengrasssdk

# Setup logging to stdout
logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

client = greengrasssdk.client('lambda')


def handler(event, context):
client_context = json.dumps({
'custom': 'custom text'
})

try:
response = client.invoke(
ClientContext=base64.b64encode(bytes(client_context)),
FunctionName='arn:aws:lambda:<region>:<accountId>:function:<targetFunctionName>:<targetFunctionQualifier>',
InvocationType='RequestResponse',
Payload='Non-JSON Data',
Qualifier='1'
)

logger.info(response['Payload'].read())
except Exception as e:
logger.error(e)
56 changes: 56 additions & 0 deletions examples/HelloWorld/greengrassHelloWorld.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#
# Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#

# greengrassHelloWorld.py
# Demonstrates a simple publish to a topic using Greengrass core sdk
# This lambda function will retrieve underlying platform information and send
# a hello world message along with the platform information to the topic
# 'hello/world'. The function will sleep for five seconds, then repeat.
# Since the function is long-lived it will run forever when deployed to a
# Greengrass core. The handler will NOT be invoked in our example since
# the we are executing an infinite loop.

import greengrasssdk
import platform
from threading import Timer


# Creating a greengrass core sdk client
client = greengrasssdk.client('iot-data')

# Retrieving platform information to send from Greengrass Core
my_platform = platform.platform()


# When deployed to a Greengrass core, this code will be executed immediately
# as a long-lived lambda function. The code will enter the infinite while
# loop below.
# If you execute a 'test' on the Lambda Console, this test will fail by
# hitting the execution timeout of three seconds. This is expected as
# this function never returns a result.

def greengrass_hello_world_run():
if not my_platform:
client.publish(
topic='hello/world',
payload='Hello world! Sent from Greengrass Core.')
else:
client.publish(
topic='hello/world',
payload='Hello world! Sent from '
'Greengrass Core running on platform: {}'
.format(my_platform))

# Asynchronously schedule this function to be run again in 5 seconds
Timer(5, greengrass_hello_world_run).start()


# Start executing the function above
greengrass_hello_world_run()


# This is a dummy handler and will not be invoked
# Instead the code above will be executed in an infinite loop for our example
def function_handler(event, context):
return
30 changes: 30 additions & 0 deletions examples/Storyline_MessageLambda/messageLambda.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#

import sys
import logging
import greengrasssdk

# Setup logging to stdout
logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

client = greengrasssdk.client('iot-data')


def message_handler(event, context):
logger.info("Received message!")
if 'state' in event:
if event['state'] == "on":
client.update_thing_shadow(
thingName="RobotArm_Thing",
payload='{"state":{"desired":{"myState":"on"}}}')
logger.info("Triggering publish to shadow "
"topic to set state to ON")
elif event['state'] == "off":
client.update_thing_shadow(
thingName="RobotArm_Thing",
payload='{"state":{"desired":{"myState":"off"}}}')
logger.info("Triggering publish to shadow "
"topic to set state to OFF")
30 changes: 30 additions & 0 deletions examples/Storyline_UptimeLambda/uptimeLambda.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#

import sys
import logging
import greengrasssdk

# Setup logging to stdout
logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

client = greengrasssdk.client('iot-data')


def uptime_handler(event, context):
logger.info("Received message!")
if 'state' in event:
if event['state'] == "on":
client.publish(
topic='/topic/metering',
payload="Robot arm turned ON")
logger.info("Triggering publish to topic "
"/topic/metering with ON state")
elif event['state'] == "off":
client.publish(
topic='/topic/metering',
payload="Robot arm turned OFF")
logger.info("Triggering publish to topic "
"/topic/metering with OFF state")
74 changes: 74 additions & 0 deletions examples/TES/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
The TES example package contains a Lambda function that, when run,
will attempt to retrieve AWS credentials. The goal of TES is to allow
users to retrieve credentials without having them hard-coded on the
system itself.

Assuming no credentials exist on the system, when the Lambda function
is run, temporary credentials will be sourced from the cloud. They
will be formatted as <Access Key, Secret Key, Session Key, Expiration Date>.

The code sample performs logger initialization and credential retrieval
is outside of the function handler. This means that a pinned lambda
should be used to test functionality.

In case you would like to use an On-Demand Lambda function, you will then
need to create a subscription to invoke the Lambda function
(so that the handler is executed).

### SETUP ###
1. In order to use this example, you will need to include greengrasssdk, boto3,
botocore and any of the dependencies those libraries require in the zip file before
uploading it.

2. After creating a zip file, create a Lambda function
in the Lambda Console.

Handler: lambda_function.lambda_handler
Runtime: python2.7
Timeout: 3s
Role: any basic execution role can be used here

3. Create a group that contains your Greengrass Core and the Lambda
function you've just created.

4. Deploy the latest Greengrass release to your device.

5. Ensure that your logging configuration includes either a logging
configuration for CW, the FileSystem, or both. For example:

"Logging": {
"Content": [
{
"Type": "FileSystem",
"Component": "GreengrassSystem",
"Level": "DEBUG",
"Space": 25600
},
{
"Type": "FileSystem",
"Component": "Lambda",
"Level": "DEBUG",
"Space": 25600
},
{
"Type": "AWSCloudWatch",
"Component": "Lambda",
"Level": "DEBUG"
},
{
"Type": "AWSCloudWatch",
"Component": "GreengrassSystem",
"Level": "DEBUG"
}
]
}

6. Make a deployment to your Greengrass Core, then start your Greengrass
Core. The core will check for any new deployments and will proceed to
download the newest configuration file (group.json) as well as the Lambda
function you've created.

7. Check either the local logs or CloudWatch logs for output from the function.

Local Path: /greengrass/var/log/user/<REGION>/<ACCOUNT>/<FUNCTION_NAME>.log
CloudWatch: /aws/greengrass/Lambda/<REGION>/<ACCOUNT>/<FUNCTION_NAME>
35 changes: 35 additions & 0 deletions examples/TES/lambda_function.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#
# Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#

from botocore.session import Session
import greengrasssdk

import sys
import logging

# Setup logging to stdout
logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

client = greengrasssdk.client('iot-data')

logger.info('Hello from pinned lambda. Outside of handler.')

# Get creds from TES
# Note: must make sure that creds are not available within local folder
# Can get cred info from /greengrass/var/log/system/tes.log
session = Session()
creds = session.get_credentials()
formatted_creds = """
Access Key: {}\n
Secret Key: {}\n
Session Key: {}\n""".format(creds.access_key, creds.secret_key, creds.token)

# Logging credential information is not recommended. This is for demonstration purposes only.
# logger.info(formatted_creds)


def lambda_handler(event, context):
logger.debug("Hello from pinned lambda. Inside handler.")
return
Loading

0 comments on commit f242d01

Please sign in to comment.