Skip to content
This repository was archived by the owner on Mar 15, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add the feature to mock the context object
A `MockContext` object is added which mimics the default behaviour
and implements the necessary attributes and functions described here:
http://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html

The script accepts a `context.json` file. The contents of the file
can be accessed via the python object `context.client_context.custom`
in your handler function.
  • Loading branch information
Marcel Radischat committed May 17, 2016
commit 06884ab0ce8e86c2bfea22477af5dd2c8d918f60
34 changes: 24 additions & 10 deletions aws_lambda/aws_lambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import json
import logging
import os
import sys
import time
from imp import load_source
from shutil import copy, copyfile
Expand All @@ -12,6 +13,7 @@
import pip
import yaml
from . import project_template
from .context import MockContext
from .helpers import mkdir, read, archive, timestamp


Expand Down Expand Up @@ -41,14 +43,32 @@ def deploy(src):
create_function(cfg, path_to_zip_file)


def invoke(src, alt_event=None, verbose=False):
def _load_json(base_dir, filename, default):
if filename is None:
filename = default
path = os.path.join(base_dir, filename)
try:
return read(path, loader=json.loads)
except IOError:
print("File does not exist: {}".format(path))
# file does not exist or json is malformed
return None
except ValueError:
print("Could not decode JSON object: {}".format(path))
print("Aborting...")
sys.exit(1)


def invoke(src, alt_event=None, alt_context=None, verbose=False):
"""Simulates a call to your function.

:param str src:
The path to your Lambda ready project (folder must contain a valid
config.yaml and handler module (e.g.: service.py).
:param str alt_event:
An optional argument to override which event file to use.
:param str alt_context:
An optional argument to override which context file to use.
:param bool verbose:
Whether to print out verbose details.
"""
Expand All @@ -57,22 +77,16 @@ def invoke(src, alt_event=None, verbose=False):
cfg = read(path_to_config_file, loader=yaml.load)

# Load and parse event file.
if alt_event:
path_to_event_file = os.path.join(src, alt_event)
else:
path_to_event_file = os.path.join(src, 'event.json')
event = read(path_to_event_file, loader=json.loads)
event = _load_json(src, alt_event, 'event.json')
context = _load_json(src, alt_context, 'context.json')

handler = cfg.get('handler')
# Inspect the handler string (<module>.<function name>) and translate it
# into a function we can execute.
fn = get_callable_handler_function(src, handler)

# TODO: look into mocking the ``context`` variable, currently being passed
# as None.

start = time.time()
results = fn(event, None)
results = fn(event, MockContext(context))
end = time.time()

print("{0}".format(results))
Expand Down
31 changes: 31 additions & 0 deletions aws_lambda/context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-

class MockContext(object):
def __init__(self, context):
self.function_name = 'Mock'
self.function_version = 'm1'
self.memory_limit_in_mb = '500'
self.aws_request_id = None
self.log_groupd_name = None
self.log_stream_name = None
self.identiy = FakeObject()
self.client_context = ClientContext(context)

def get_remaining_time_in_millis(self):
# Returns the remaining execution time, in milliseconds, until
# AWS Lambda terminates the function.
return 0


class FakeObject(object):
def __init__(self, context=None):
self._context = context or {} # if None was passed

def __getattr__(self, attr):
return self._context.get(attr, None)


class ClientContext(object):
def __init__(self, context):
self.custom = FakeObject(context)
self.client = FakeObject()
5 changes: 3 additions & 2 deletions scripts/lambda
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ def build():

@click.command(help="Run a local test of your function.")
@click.option('--event-file', default=None, help='Alternate event file.')
@click.option('--context-file', default=None, help='Alternate context file.')
@click.option('--verbose', '-v', is_flag=True)
def invoke(event_file, verbose):
aws_lambda.invoke(CURRENT_DIR, event_file, verbose)
def invoke(event_file, context_file, verbose):
aws_lambda.invoke(CURRENT_DIR, event_file, context_file, verbose)


@click.command(help="Register and deploy your code to lambda.")
Expand Down