Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using boto3 and python3, I cannot base64 encode the JSON for ClientContext?

Tags:

In using lambda, the docs say you must send a base64 encoded JSON object for the ClientContext. It also says Client Context must be a 'str' not bytes.

http://boto3.readthedocs.io/en/latest/reference/services/lambda.html#Lambda.Client.invoke

Since python3's base64 library now encodes using bytes, not string - this appears to have stumped me.

import boto3
import base64

CLIENT = boto3.client('lambda')

client_context = b'{ "client_name": "Andy"}'
encoded_context = base64.b64encode(client_context)
CLIENT.invoke(
        FunctionName='testFunction',
        InvocationType='RequestResponse',
        LogType='Tail',
        ClientContext=encoded_context
    )

The error I get is: Invalid type for parameter ClientContext, value: b'eyAiY2xpZW50X25hbWUiOiJGUkVFSFVCIiB9', type: <class 'bytes'>, valid types: <class 'str'>

or when I set str(encoded_context): botocore.errorfactory.InvalidRequestContentException: An error occurred (InvalidRequestContentException) when calling the Invoke operation: Client context must be a valid Base64-encoded JSON object.

Thanks in advance.

like image 617
andylockran Avatar asked Sep 07 '17 11:09

andylockran


1 Answers

The code below is an example for passing Client Context via boto3.

import boto3
import base64
import json

client = boto3.client("lambda")


def lambda_context(custom=None,
                   env=None,
                   client=None):
    client_context = dict(
        custom=custom,
        env=env,
        client=client)
    json_context = json.dumps(client_context).encode('utf-8')
    return base64.b64encode(json_context).decode('utf-8')

context = {
    "custom": {"foo": "bar"},
    "env": {"test": "test"},
    "client": {}
}

client.invoke(FunctionName="<YOUR_LAMBDA_FUNCTIONS>",
                         ClientContext=lambda_context(**context),
                         Payload=YOUR_PAYLOAD)

Note that env and custom in the Client Context dict object could be anything. For client, only the following keys can be accepted:

app_version_name
app_title
app_version_code
app_package_name
installation_id

Btw, if your lambda function is implemented in Python. The Client Context object may be referred as context.client_context. env(context.cilent_context.env) and custom(context.client_context.custom) are two dict objects. If any of env, custom, or client is not passed from boto3's invoke method, the corresponding one in the context.client_context would be a None.

like image 58
socrates Avatar answered Oct 11 '22 13:10

socrates