powertools-lambda-python icon indicating copy to clipboard operation
powertools-lambda-python copied to clipboard

Feature request: Parsing nested Parser envelopes

Open heitorlessa opened this issue 1 year ago • 2 comments

Discussed in https://github.com/aws-powertools/powertools-lambda-python/discussions/2287

Related: https://github.com/aws-powertools/powertools-lambda-python/issues/2678

Originally posted by sk0g May 18, 2023 So we have payloads that are essentially Kinesis Firehouse events containing an SQS event. Is there a way to unwrap this using @event_parser()? If not, what's the next best thing?

heitorlessa avatar Jul 06 '23 08:07 heitorlessa

Note: we have a RFC for Event Source Data Classes but not for Parser (after the former is done).

https://github.com/aws-powertools/powertools-lambda-python/issues/2678

heitorlessa avatar Jul 10 '23 08:07 heitorlessa

Hey @heitorlessa. I've tried to check this a bit, and even experimented with the implementation. You can check the implementation itself here https://github.com/aradyaron/powertools-lambda-python/pull/3

Please note that It's a bit problematic for me to get a nested event, so if you got some examples of such payloads and scenarios, it will allow to further implement this feature.

Please see that this Pr Contains two new functions

def chained_parse(event: Dict[str, Any], model: Type[Model], envelopes: List[Type[Envelope]]) -> List:

which receives a list of envelopes to extract the nested event from. It returns a list of the given model type. It also assumes one each nesting can be a list of event, so it expands the events into a flat list.

In case the model itself is not to be parsed as an envelope, the last envelope can be None

For example:


   parsed_event: List[MySnsBusiness] = chained_parse(
       event=raw_event,
       model=MySnsBusiness,
       envelopes=[envelopes.X, envelopes.Y, None],
   )

same with

@lambda_handler_decorator
def event_parser(
   handler: Callable[[Any, LambdaContext], EventParserReturnType],
   event: Dict[str, Any],
   context: LambdaContext,
   model: Type[Model],
   envelope: Optional[Union[Type[Envelope], List[Type[Envelope]]]] = None,
) -> EventParserReturnType:

which in case envelope is a list, will use chained envelope with the same logic.

WDYT about this kind of solution? Please note that without actual nested use cases it's purely a theoretical solution

aradyaron avatar Sep 16 '23 10:09 aradyaron