Skip to main content

Grid Smarter Cities

Build Status License: MIT Github Release

Python Versions PyPi Version PyPi Status Pypi Downloads

aws-lambda-decorators

A set of Python decorators to ease the development of AWS lambda functions.

Installation

The easiest way to use these AWS Lambda Decorators is to install them through Pip:

pip install aws-lambda-decorators

Package Contents

Decorators

The current list of AWS Lambda Python Decorators includes:

  • extract: a decorator to extract and validate specific keys of a dictionary parameter passed to a AWS Lambda function.
  • extract_from_event: a facade of extract to extract and validate keys from an AWS API Gateway lambda function event parameter.
  • extract_from_context: a facade of extract to extract and validate keys from an AWS API Gateway lambda function context parameter.
  • extract_from_ssm: a decorator to extract from AWS SSM the values of a set of parameter keys.
  • validate: a decorator to validate a list of function parameters.
  • log: a decorator to log the parameters passed to the lambda function and/or the response of the lambda function.
  • handle_exceptions: a decorator to handle any type of declared exception generated by the lambda function.
  • response_body_as_json: a decorator to transform a response dictionary body to a json string.

Validators

Currently, the package offers 2 validators:

Decoders

The package offers functions to decode from JSON and JWT.

  • decode_json: decodes/converts a json string to a python dictionary
  • decode_jwt: decodes/converts a JWT string to a python dictionary

Examples

extract

This decorator extracts and validates values from dictionary parameters passed to a Lambda Function.

  • The decorator takes a list of Parameter objects.
  • Each Parameter object requires a non-empty path to the parameter in the dictionary, and the name of the dictionary (func_param_name)
  • The parameter value is extracted and added as a kwarg to the lambda handler (or any other decorated function/method).
  • You can add the parameter to the handler signature, or access it in the handler through kwargs.
  • The name of the extracted parameter is defaulted to the last element of the path name, but can be changed by passing a (valid pythonic variable name) var_name
  • You can define a default value for the parameter in the Parameter or in the lambda handler itself.
  • A 400 exception is raised when the parameter cannot be extracted or when it does not validate.
  • A variable path (e.g. '/headers/Authorization[jwt]/sub') can be annotated to specify a decoding. In the example, Authorization might contain a JWT, which needs to be decoded before accessing the "sub" element.

Example: code | test

@extract(parameters=[
    Parameter(path='/parent/my_param', func_param_name='a_dictionary'),  # extracts a non mandatory my_param from a_dictionary
    Parameter(path='/parent/missing_non_mandatory', func_param_name='a_dictionary', default='I am missing'),  # extracts a non mandatory missing_non_mandatory from a_dictionary
    Parameter(path='/parent/missing_mandatory', func_param_name='a_dictionary'),  # does not fail as the parameter is not validated as mandatory
    Parameter(path='/parent/child/id', validators=[Mandatory], var_name='user_id', func_param_name='another_dictionary')  # extracts a mandatory id as "user_id" from another_dictionary
])
def extract_example(a_dictionary, another_dictionary, my_param='aDefaultValue', missing_non_mandatory='I am missing', missing_mandatory=None, user_id=None):
    """
        Given these two dictionaries:

        a_dictionary = { 
            'parent': { 
                'my_param': 'Hello!' 
            }, 
            'other': 'other value' 
        }

        another_dictionary = { 
            'parent': { 
                'child': { 
                    'id': '123' 
                } 
            } 
        }

        you can now access the extracted parameters directly: 
    """
    return my_param, missing_non_mandatory, missing_mandatory, user_id

Or you can use kwargs instead of specific parameter names:

Example: code | test

@extract(parameters=[
    Parameter(path='/parent/my_param', func_param_name='a_dictionary')  # extracts a non mandatory my_param from a_dictionary
])
def extract_to_kwargs_example(a_dictionary, **kwargs):
    """
        a_dictionary = { 
            'parent': { 
                'my_param': 'Hello!' 
            }, 
            'other': 'other value' 
        }
    """
    return kwargs['my_param']  # returns 'Hello!'

A missing mandatory parameter, or a parameter that fails validation, will raise an exception:

Example: code | test 1 | test 2

@extract(parameters=[
    Parameter(path='/parent/mandatory_param', func_param_name='a_dictionary', validators=[Mandatory])  # extracts a mandatory mandatory_param from a_dictionary
])
def extract_mandatory_param_example(a_dictionary, mandatory_param=None):
    return 'Here!'  # this part will never be reached, if the mandatory_param is missing

response = extract_mandatory_param_example({'parent': {'my_param': 'Hello!'}, 'other': 'other value'} )

print(response)  # prints { 'statusCode': 400, 'body': 'Error extracting parameters' } and logs a more detailed error

You can decode any part of the parameter path from json or any other existing annotation.

Example: code | test

@extract(parameters=[
    Parameter(path='/parent[json]/my_param', func_param_name='a_dictionary')  # extracts a non mandatory my_param from a_dictionary
])
def extract_from_json_example(a_dictionary, my_param=None):
    """
        a_dictionary = { 
            'parent': '{"my_param": "Hello!" }', 
            'other': 'other value' 
        }
    """
    return my_param  # returns 'Hello!'

extract_from_event

This decorator is just a facade to the extract method to be used in AWS Api Gateway Lambdas. It automatically extracts from the event lambda parameter.

Example: code | test

@extract_from_event(parameters=[
    Parameter(path='/body[json]/my_param', validators=[Mandatory]),  # extracts a mandatory my_param from the json body of the event
    Parameter(path='/headers/Authorization[jwt]/sub', validators=[Mandatory], var_name='user_id')  # extract the mandatory sub value as user_id from the authorization JWT
])
def extract_from_event_example(event, context, my_param=None, user_id=None):
    """
        event = { 
            'body': '{"my_param": "Hello!"}', 
            'headers': { 
                'Authorization': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' 
            } 
        }
    """
    return my_param, user_id  # returns ('Hello!', '1234567890')

extract_from_context

This decorator is just a facade to the extract method to be used in AWS Api Gateway Lambdas. It automatically extracts from the context lambda parameter.

Example: code | test

@extract_from_context(parameters=[
    Parameter(path='/parent/my_param', validators=[Mandatory])  # extracts a mandatory my_param from the parent element in context
])
def extract_from_context_example(event, context, my_param=None):
    """
        context = {
            'parent': {
                'my_param': 'Hello!'
            }
        }
    """    
    return my_param  # returns 'Hello!'

extract_from_ssm

This decorator extracts a parameter from AWS SSM and passes the parameter down to your function as a kwarg.

  • The decorator takes a list of SSMParameter objects.
  • Each SSMParameter object requires the name of the SSM parameter (ssm_name)
  • If no var_name is passed in, the extracted value is passed to the function with the ssm_name name

Example: code | test

@extract_from_ssm(ssm_parameters=[
    SSMParameter(ssm_name='one_key'),  # extracts the value of one_key from SSM as a kwarg named "one_key"
    SSMParameter(ssm_name='another_key', var_name="another")  # extracts another_key as a kwarg named "another"
])
def extract_from_ssm_example(your_func_params, one_key=None, another=None):
    return your_func_params, one_key, another

validate

This decorator validates a list of non dictionary parameters from your lambda function.

  • The decorator takes a list of ValidatedParameter objects.
  • Each parameter object needs the name of the lambda function parameter that it is going to be validated, and the list of rules to validate.
  • A 400 exception is raised when the parameter does not validate.

Example: code | test

@validate(parameters=[
    ValidatedParameter(func_param_name='a_param', validators=[Mandatory]),  # validates a_param as mandatory
    ValidatedParameter(func_param_name='another_param', validators=[Mandatory, RegexValidator(r'\d+')])  # validates another_param as mandatory and containing only digits
])
def validate_example(a_param, another_param):
    return a_param, another_param  # returns 'Hello!', '123456

validate_example('Hello!', '123456')

Given the same function validate_example, a 400 exception is returned if at least one parameter does not validate:

validate_example('Hello!', 'ABCD')  # returns a 400 status code and an error message

log

This decorator allows for logging the function arguments and/or the response.

Example: code | test

@log(parameters=True, response=True)
def log_example(parameters): 
    return 'Done!'

log_example('Hello!')  # logs 'Hello!' and 'Done!'

handle_exceptions

This decorator handles a list of exceptions, returning a 400 response containing the specified friendly message to the caller.

  • The decorator takes a list of ExceptionHandler objects.
  • Each ExceptionHandler requires the type of exception to check, and the friendly message to return to the caller.

Example: code | test

@handle_exceptions(handlers=[
    ExceptionHandler(ClientError, "Your message when a client error happens.")
])
def handle_exceptions_example():
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('non_existing_table')
    table.query(KeyConditionExpression=Key('user_id').eq(user_id))
    # ...

handle_exceptions_example()  # returns {'body': 'Your message when a client error happens.', 'statusCode': 400}

response_body_as_json

This decorator ensures that, if the response contains a body, the body is dumped as json.

  • Returns a 500 error if the response body cannot be dumped as json.

Example: code | test

@response_body_as_json
def response_body_as_json_example():
    return {'statusCode': 400, 'body': {'param': 'hello!'}}

response_body_as_json_example()  # returns { 'statusCode': 400, 'body': "{ 'param': 'hello!' }" }

Documentation

You can get the docstring help by running:

>>> from aws_lambda_decorators.decorators import extract
>>> help(extract)

Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aws-lambda-decorators-0.14.tar.gz (14.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aws_lambda_decorators-0.14-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

Details for the file aws-lambda-decorators-0.14.tar.gz.

File metadata

  • Download URL: aws-lambda-decorators-0.14.tar.gz
  • Upload date:
  • Size: 14.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.5.0.1 requests/2.20.0 setuptools/39.2.0 requests-toolbelt/0.8.0 tqdm/4.30.0 CPython/3.6.5

File hashes

Hashes for aws-lambda-decorators-0.14.tar.gz
Algorithm Hash digest
SHA256 837ec0d4cdadb673ef4e540a8729524ec02a0e8061de4421c7df5fc20a84eda4
MD5 8b64e4655552a0cf770f8adea7f61d53
BLAKE2b-256 a41af69b81f34878ba00bfc9222c5d12f3b05fa6fa7aca1e317c5934b3c57fce

See more details on using hashes here.

File details

Details for the file aws_lambda_decorators-0.14-py3-none-any.whl.

File metadata

  • Download URL: aws_lambda_decorators-0.14-py3-none-any.whl
  • Upload date:
  • Size: 12.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.5.0.1 requests/2.20.0 setuptools/39.2.0 requests-toolbelt/0.8.0 tqdm/4.30.0 CPython/3.6.5

File hashes

Hashes for aws_lambda_decorators-0.14-py3-none-any.whl
Algorithm Hash digest
SHA256 4e45c31c297a9800756e664425c34a29f9e90f70aaef82bc87170638a7f1f714
MD5 50b16cb8bc7f35552ec2a1e6ce277bbe
BLAKE2b-256 a41015a0b4259bb5cabd383c720de6af90777c085ab0070f7fcf7d2567ee95df

See more details on using hashes here.

Release history Release notifications | RSS feed

0.53

2 files

0.52

2 files

0.51

2 files

0.50

2 files

0.49

2 files

0.48

2 files

0.47

2 files

0.46

2 files

0.45

2 files

0.44

2 files

0.43

2 files

0.42

2 files

0.40

2 files

0.39

2 files

0.38

2 files

0.36

2 files

0.35

2 files

0.34

2 files

0.33

2 files

0.32

2 files

0.31

2 files

0.30

2 files

0.29

2 files

0.28

2 files

0.27

2 files

0.26

2 files

0.25

2 files

0.24

2 files

0.23

2 files

0.22

2 files

0.21

2 files

0.20

2 files

0.19

2 files

0.18

2 files

0.17

2 files

0.16

2 files

0.15

2 files

This release

0.14 This release

2 files

0.13

2 files

0.12

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page