Skip to content

Instantly share code, notes, and snippets.

@pgolding
Last active August 25, 2023 16:07
Show Gist options
  • Save pgolding/4edc4f3d066679117bba187105678028 to your computer and use it in GitHub Desktop.
Save pgolding/4edc4f3d066679117bba187105678028 to your computer and use it in GitHub Desktop.
Passing AWS Lambda Function parameters using the ClientContext object in Python

Boto3 documentation for lambda_client.invoke suggests it is possible to pass data via the ClientContext object as a string.

The string is required to be base64 encoded JSON.

To encode such a string, use:

import baseb4
base64.b64encode(b'<string>').decode('utf-8')

However, it is not clear how to pass the data. It's tempting to think any JSON string will do and will surface via the Context object of the lambda function handler:

def my_handler(event,context):

However, data should be passed via a custom field:

event = {"body": { "my": "data" }} # body not necessary, but compatible with API gateway invocation
res = lambda_client.invoke(FunctionName='<your_function_name>',
                                   InvocationType='RequestResponse',
                                   ClientContext=base64.b64encode(b'{"custom":{"foo":"bar", \
                                                                  "fuzzy":"wuzzy"}}').decode('utf-8'),
                                   Payload=json.dumps(event))

It can then be access in the lambda function like so:

def my_handler(event,context):
  my_custom_dict = context.client_context.custom
  foo = my_custom_dict["foo"] # "bar"
  # and so on

The use of the custom field is kind of mentioned here, but not very well: http://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html

@akmalmzamri
Copy link

Thanks! This is very useful. Just wondering, in term of usage, what is the difference between ClientContext and Payload?

@mannharleen
Copy link

thats a good question - wats the difference? anyone??

@cnavneet
Copy link

This seems not working....

My cloudwatch code is as follows:

data = json.dumps({"appointment_id": "3e3c37e1-6a60-488b-b92c-9ef9c3136aee", "role": "mentee", "duration": "10 minutes"})
    event = {"body": { "my": "data" }}

    fn_response = lambda_client.invoke(
        FunctionName = fn_name,
        InvocationType = 'RequestResponse',
        LogType = 'None',
        ClientContext=base64.b64encode(b'{"custom":{"appointment_id":"3e3c37e1-6a60-488b-b92c-9ef9c3136aee", "fuzzy":"wuzzy"}}').decode('utf-8'),
        Payload = json.dumps(event)
    )

and my lambda function code is as follows:

def CloudWatchHelper(event, context):
    
    print("context --------------->")
    my_custom_dict = context.client_context.custom
    print("inside --------------------------->")
    print(json.dumps(str(event)))
    print("printing context --------------------------->")
    print(json.dumps(str(context)))
    print("details: " + str(event['detail']))
    print(my_custom_dict['appointment_id'])

it is giving error as: Cannot get custom of object NoneType

@vrgurus
Copy link

vrgurus commented Feb 27, 2019

@cnavneet Try this...

event = {"appointment_id": "3e3c37e1-6a60-488b-b92c-9ef9c3136aee", "role": "mentee", "duration": "10 minutes"}

fn_response = lambda_client.invoke(
FunctionName = fn_name,
InvocationType = 'RequestResponse',
LogType = 'None',
Payload = json.dumps(event)
)

def CloudWatchHelper(event, context):

my_custom_dict = event
print(my_custom_dict["appointment_id"])

@mannharleen
Copy link

Please note:

  • I noticed that we cannot pass ClientContext when we invoke lambda using InvocationType = 'Event'

@stanyates
Copy link

Nice. Much appreciated. This is so poorly documented and poorly conceived in AWS that I'm interested in how it ended up the way it is. But I have a use case needing it and this was the key.

@dmytrokosiachenko
Copy link

Thanks, same applies for Rust.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment