def prepare_invocation( self, context: InvocationContext ) -> Optional[Union[AdditionalInvocationOptions, InvocationResult]]: if is_java_lambda(context.lambda_function): return _prepare_invocation_for_java_lambda(context) elif is_nodejs_runtime(context.lambda_function): return _prepare_invocation_for_node_lambda(context) elif is_python_runtime(context.lambda_function): return _prepare_invocation_for_python_lambda(context) return None
def set_function_code(code, lambda_name, lambda_cwd=None): def generic_handler(event, context): raise ClientError(('Unable to find executor for Lambda function "%s". Note that ' + 'Node.js, Golang, and .Net Core Lambdas currently require LAMBDA_EXECUTOR=docker') % lambda_name) arn = func_arn(lambda_name) lambda_details = arn_to_lambda[arn] runtime = lambda_details.runtime lambda_environment = lambda_details.envvars handler_name = lambda_details.handler or LAMBDA_DEFAULT_HANDLER code_passed = code code = code or lambda_details.code is_local_mount = code.get('S3Bucket') == BUCKET_MARKER_LOCAL zip_file_content = None if code_passed: lambda_cwd = lambda_cwd or set_archive_code(code_passed, lambda_name) if not is_local_mount: # Save the zip file to a temporary file that the lambda executors can reference zip_file_content = get_zip_bytes(code_passed) else: lambda_cwd = lambda_cwd or lambda_details.cwd # get local lambda working directory tmp_file = '%s/%s' % (lambda_cwd, LAMBDA_ZIP_FILE_NAME) if not zip_file_content: zip_file_content = load_file(tmp_file, mode='rb') # Set the appropriate lambda handler. lambda_handler = generic_handler is_java = lambda_executors.is_java_lambda(runtime) if is_java: # The Lambda executors for Docker subclass LambdaExecutorContainers, which # runs Lambda in Docker by passing all *.jar files in the function working # directory as part of the classpath. Obtain a Java handler function below. lambda_handler = get_java_handler(zip_file_content, handler_name, tmp_file) if not is_local_mount: # Lambda code must be uploaded in Zip format if not is_zip_file(zip_file_content): raise ClientError( 'Uploaded Lambda code for runtime ({}) is not in Zip format'.format(runtime)) # Unzipping should only be required for (1) non-Java Lambdas, or (2) zip files containing JAR files if not is_java or zip_contains_jar_entries(zip_file_content, 'lib/'): unzip(tmp_file, lambda_cwd) # Obtain handler details for any non-Java Lambda function if not is_java: handler_file = get_handler_file_from_name(handler_name, runtime=runtime) handler_function = get_handler_function_from_name(handler_name, runtime=runtime) main_file = '%s/%s' % (lambda_cwd, handler_file) if not os.path.exists(main_file): # Raise an error if (1) this is not a local mount lambda, or (2) we're # running Lambdas locally (not in Docker), or (3) we're using remote Docker. # -> We do *not* want to raise an error if we're using local mount in non-remote Docker if not is_local_mount or not use_docker() or config.LAMBDA_REMOTE_DOCKER: file_list = run('cd "%s"; du -d 3 .' % lambda_cwd) config_debug = ('Config for local mount, docker, remote: "%s", "%s", "%s"' % (is_local_mount, use_docker(), config.LAMBDA_REMOTE_DOCKER)) LOG.debug('Lambda archive content:\n%s' % file_list) raise ClientError(error_response( 'Unable to find handler script (%s) in Lambda archive. %s' % (main_file, config_debug), 400, error_type='ValidationError')) if runtime.startswith('python') and not use_docker(): try: # make sure the file is actually readable, then read contents ensure_readable(main_file) zip_file_content = load_file(main_file, mode='rb') # extract handler lambda_handler = exec_lambda_code( zip_file_content, handler_function=handler_function, lambda_cwd=lambda_cwd, lambda_env=lambda_environment) except Exception as e: raise ClientError('Unable to get handler function from lambda code.', e) add_function_mapping(lambda_name, lambda_handler, lambda_cwd) return {'FunctionName': lambda_name}