-
-
Save benkehoe/efb75a793f11d071b36fed155f017c8f to your computer and use it in GitHub Desktop.
"""Base class for implementing Lambda handlers as classes. | |
Used across multiple Lambda functions (included in each zip file). | |
Add additional features here common to all your Lambdas, like logging.""" | |
class LambdaBase(object): | |
@classmethod | |
def get_handler(cls, *args, **kwargs): | |
def handler(event, context): | |
return cls(*args, **kwargs).handle(event, context) | |
return handler | |
def handle(self, event, context): | |
raise NotImplementedError |
"""Implementation of a Lambda handler as a class for a specific Lambda function. | |
The Lambda function is deployed with handler set to MyLambdaClass.handler. | |
Class fields will persist across invocations for a given Lambda container, | |
and so are a good way to implement caching. | |
An instance of the class is created for each invocation, so instance fields can | |
be set from the input without the data persisting.""" | |
from LambdaBase import LambdaBase | |
class MyLambdaClass(LambdaBase): | |
def __init__(self, ...): # implementation-specific args and/or kwargs | |
# implementation | |
def handle(self, event, context): | |
# implementation | |
handler = MyLambdaClass.get_handler(...) # input values for args and/or kwargs |
I found this code very useful but didn't like the repetition of handler = MyLambdaClass.get_handler(...)
for each class.
Instead, I created an annotation tag, so I can now do:
@LambdaHandler
class MyLambdaClass(LambdaBase):
def __init__(self, ...): # implementation-specific args and/or kwargs
# implementation
def handle(self, event, context):
# implementation
def LambdaHandler(func):
# Creates dynamic handler in caller's module called MyCallingClassHandler
module = func.__module__
handler_name = f'{func.__name__}Handler'
setattr(sys.modules[module], handler_name, func.get_handler() )
return func
This createss a runtime magic attribute, which can be accessed by MyLambdaClassHandler
I found this code very useful but didn't like the repetition of
handler = MyLambdaClass.get_handler(...)
for each class.Instead, I created an annotation tag, so I can now do:
@LambdaHandler class MyLambdaClass(LambdaBase): def __init__(self, ...): # implementation-specific args and/or kwargs # implementation def handle(self, event, context): # implementation def LambdaHandler(func): # Creates dynamic handler in caller's module called MyCallingClassHandler module = func.__module__ handler_name = f'{func.__name__}Handler' setattr(sys.modules[module], handler_name, func.get_handler() ) return func
This createss a runtime magic attribute, which can be accessed by
MyLambdaClassHandler
Could you help with a hello world example. I tried but cant get this sample the way you describe to work.
Could you perhaps provide an hello world example based on this template. I tried to get it implemented but failed.
I really just need to understand how to create "handler = MyLambdaClass.get_handler(...)" to input event and context.
Anybody else read this: Skip the below, it does not seem to work. The base pattern works well.
@LambdaHandler
class MyLambdaClass(LambdaBase):
def init(self, ...): # implementation-specific args and/or kwargs
# implementation
def handle(self, event, context):
# implementation
def LambdaHandler(func):
# Creates dynamic handler in caller's module called MyCallingClassHandler
module = func.__module__
handler_name = f'{func.__name__}Handler'
setattr(sys.modules[module], handler_name, func.get_handler() )
return func
Thanks bro
Hello @benkehoe. I was thinking about your pattern, and I'd like to know:
What if I have more then one function to call inside MyLambdaClass?
Could you provide an example using multiple functions in MyLambdaClass?
Thank's a lot.