def rest_api( self, encoding: Encoding = JsonEncoding(), validator: Validator = NoneValidator() ) -> Callable: """ Decorator for API Gateway event. Automatically parse string if the 'body' can be parsed as Dictionary. Automatically returns 500 error if unexpected error happens. Parameters ---------- response_headers: dict Response headers when 500 error get_app. Usage:: >>> from jeffy.framework import setup >>> from jeffy.encoding.json import JsonEncoding >>> app = get_app() >>> @app.handlers.rest_api(encoding=JsonEncoding()) ... def handler(event, context): ... return event['body']['foo'] """ def _rest_api(func: Callable): # type: ignore @functools.wraps(func) def wrapper(event, context): # type: ignore try: self.capture_correlation_id(event) if event.get('body') is not None: try: event['body'] = encoding.decode( event.get('body', '').encode('utf-8')) validator.validate(event['body']) except (DecodeError, ValidationError) as e: self.app.logger.exception(e) return { 'statusCode': 400, 'headers': { self.app.correlation_id_header: self.app.correlation_id }, 'body': json.dumps({'error_message': str(e)}) } self.app.logger.info(event) ret = func(event, context) if ret.get('headers') is not None: ret['headers'].update({ self.app.correlation_id_header: self.app.correlation_id }) self.app.logger.info(ret) return ret except Exception as e: self.app.logger.exception(e) raise e return wrapper return _rest_api
def __init__(self, encoding: Encoding = JsonEncoding()): """ Initialize SNS client. Parameters ---------- encoding: jeffy.encoding.Encoding """ super(Sns, self).__init__(encoding)
def kinesis_streams( self, encoding: Encoding = JsonEncoding(), validator: Validator = NoneValidator() ) -> Callable: """ Decorator for Kinesis stream event. Automatically divide 'Records' for making it easy to treat it inside main process of Lambda. Usage:: >>> from jeffy.framework import get_app >>> from jeffy.encoding.json import JsonEncoding >>> app = get_app() >>> @app.handlers.kinesis_streams(encoding=JsonEncoding()) ... def handler(event, context): ... return event['body']['foo'] """ def _kinesis_streams(func: Callable) -> Callable: # type: ignore @functools.wraps(func) def wrapper(event, context): # type: ignore ret = [] for record in event['Records']: message = encoding.decode( base64.b64decode(record['kinesis']['data'])) validator.validate(message) self.capture_correlation_id(message) try: self.app.logger.info(message) result = func(message, context) self.app.logger.info(result) ret.append(result) except Exception as e: self.app.logger.exception(e) raise e return ret return wrapper return _kinesis_streams
def sqs_raw( self, encoding: Encoding = JsonEncoding(), validator: Validator = NoneValidator() ) -> Callable: """ Decorator for sqs raw events (with all metadatas). Automatically divide 'Records' and pass the record to main process of Lambda. Usage:: >>> from jeffy.framework import get_app >>> app = get_app() >>> @app.handlers.sqs_raw() ... def handler(event, context): ... return event['body'] """ def _sqs_raw(func: Callable): # type: ignore @functools.wraps(func) def wrapper(event, context): # type: ignore ret = [] for record in event['Records']: message = encoding.decode(record['body'].encode('utf-8')) validator.validate(message) self.capture_correlation_id(message) record['body'] = message try: self.app.logger.info(message) result = func(record, context) self.app.logger.info(event) ret.append(result) except Exception as e: self.app.logger.exception(e) raise e return ret return wrapper return _sqs_raw
def json_encoding(): """Get JsonFormatter class.""" return JsonEncoding()