Skip to content
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

Lambda.invoke() doesn't send client context #1388

Closed
ghost opened this issue Mar 2, 2017 · 5 comments
Closed

Lambda.invoke() doesn't send client context #1388

ghost opened this issue Mar 2, 2017 · 5 comments
Labels
guidance Question that needs advice or information. service-api This issue is due to a problem in a service API, not the SDK implementation.

Comments

@ghost
Copy link

ghost commented Mar 2, 2017

Im using the latest Javascript SDK and trying to send some client context from a browser app to a Lambda function. Here's a snippet of the sending end:

AWS.config.apiVersions = { lambda: '2015-03-31' };
var la = new AWS.Lambda();
var upevent = { a: 'something' };
var ctx = { LastSequence: lastSequence == null ? '0': lastSequence };
var b64ctx = btoa(JSON.stringify(ctx));
var params = {
    FunctionName: CREATE_EVENT,
    ClientContext: b64ctx,
    InvocationType: 'RequestResponse',
    LogType: 'None',
    Payload: JSON.stringify(upevent)
};
la.invoke(params, function(err, data) {
    ...

This call completes fine and even returns the data I want it to. However the Client Context is lost.
On the server side, I have a Python Lambda function with the usual method signature:

def lambda_handler(event, context):
    ctx = context.client_context

Upon execution the 'ctx' object has three attributes: client, custom, env all of which are None.

Where is my 'client context'?

I'm pretty sure it's being sent correctly on the client side, as if you pass a string that isn't correct, then you get a message 'Client context must be a valid Base64-encoded JSON object'.

@jeskew jeskew added Question service-api This issue is due to a problem in a service API, not the SDK implementation. labels Mar 18, 2017
@jeskew
Copy link
Contributor

jeskew commented Mar 18, 2017

It looks like you need to put the data you wish to send under the key custom in the object that gets JSON.stringify'd and base64 encoded. For example, with the following client code:

var AWS = require('aws-sdk');
var la = new AWS.Lambda({ region: 'us-west-2' });
var ctx = {
    custom: { foo: 'bar' },
    client: { snap: ['crackle', 'pop']},
    env: { fizz: 'buzz' },
};
la.invoke({
    FunctionName: 'contextPrinter',
    ClientContext: AWS.util.base64.encode(JSON.stringify(ctx)),
    InvocationType: 'RequestResponse',
    Payload: JSON.stringify({ baz: 'quux' })
}, function (err, data) { return console.log(err, data); });

and the following lambda:

def lambda_handler(event, context):
    print("context", context.client_context)
    print("client", ', '.join(i for i in dir(context.client_context.client) if not i.startswith('__')))
    print("custom", context.client_context.custom)
    print("env", context.client_context.env)

I get the following log output:

('context', <__main__.ClientContext object at 0x7f5705898170>)
('client', 'app_package_name, app_title, app_version_code, app_version_name, installation_id')
('custom', {u'foo': u'bar'})
('env', {u'fizz': u'buzz'})

The client context contains data about the client, but data under the custom or env keys is made available to the lambda function.

@jeskew jeskew closed this as completed Mar 18, 2017
@ghost
Copy link
Author

ghost commented Mar 21, 2017

Thanks Jason, I can verify that that works now. This should be clarified in the documentation - how do we get an update request into the doc team?

@smber1
Copy link

smber1 commented Jul 9, 2018

The clientContext will also only be passed to the invoked lambda if the InvocationType is RequestResponse. Passing Event as the InvocationType (for fire & forget/async invocations) seems to suppress the ClientContext for reasons unbeknownst to me! Perhaps the docs should be updated to relate this?

@Aea
Copy link

Aea commented Jul 9, 2018

I can confirm @smber1's observation, not getting passed along when running as Event, fine when running as RequestResponse, my sample payload was: eyJjdXN0b20iOnsidXVpZCI6IjA5MGI4ZWJiLWM0NjAtNGZiZS04ZDM0LTI5NWFkZmVjYmE4OCIsInNoYXJkIjowfX0=

Personally I'm finding the documentation around this to be quite sparse, it seems like clientContext is really intended to be used with their mobile / ad SDKs and not well supported otherwise.

@toritsejuFO
Copy link

Don't know if there's an update on this by this time. Would love to pass some context from an ending function call into a chained invocation to maintain state until long-running processing job is complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
guidance Question that needs advice or information. service-api This issue is due to a problem in a service API, not the SDK implementation.
Projects
None yet
Development

No branches or pull requests

5 participants