Skip to content

Feature request: Support types annotated with Field for event_handler validation #5953

Description

@rtandy

Use case

Hi, thank you for working on Powertools.

My Pydantic models are shared between multiple applications. For example, a client application builds an instance of a model and submits it to the API, which validates the request against the same model.

A few types I want to accept as API payloads or parameters are annotated with Field, mainly tagged unions.

I am aware of the Powertools OpenAPI Param annotations, but they have downsides:

  • having to import Powertools into non-Lambda projects;
  • being stuck with a single Param type (i.e. Body, Path, etc) per annotated type, or having to duplicate the arguments for different types

With Powertools 3.5.0, the example code below fails:

  • with def create_action(action: Action): AssertionError: Param: action can only be a request body, use Body()
  • with def create_action(action: Annotated[Action, Body()]): AssertionError: Only one FieldInfo can be used per parameter

It would be nice if event_handler would allow nested Field annotations, so that I can apply Annotated[some_type, Body()] to an existing annotated type such as a tagged union.

Thank you for considering.

Solution/User Experience

class FooAction(BaseModel):
    action: Literal['foo']
    foo: int 

class BarAction(BaseModel):
    action: Literal['bar']
    bar: int 

Action = Annotated[FooAction | BarAction, Field(discriminator='action')]

app = APIGatewayHttpResolver(enable_validation=True)

@app.post('/actions')
def create_action(action: Action): # or Annotated[Action, Body()]
    ...

def lambda_handler(event, context):
    return app.resolve(event, context)

Alternative solutions

  1. use event_handler OpenAPI Param annotations exclusively
Action = Annotated[FooAction | BarAction, Body(discriminator='action')]
  1. use TypeAdapter manually
Action = Annotated[FooAction | BarAction, Field(discriminator='action')]
action_adapter = TypeAdapter(Action)

@app.post('/actions')
def create_action():
    try:
        action = action_adapter.validate_json(app.current_event.body)
    except ValidationError as e:
        raise RequestValidationError(e.errors())

Acknowledgment

Activity

  1. leandrodamascena commented on Jan 31, 2025

    @leandrodamascena
    Contributor

    Hi @rtandy! Thanks for opening this issue! Yes, I agree that we need to support this.

    Are you interested in submitting a PR to implement this support?

  2. rtandy commented on Feb 3, 2025

    @rtandy
    Author

    Are you interested in submitting a PR to implement this support?

    I'd like to, but it's not a priority for my employer (the workaround of using a TypeAdapter manually is sufficient) and it will be at least a few weeks before I can look at it on my own time. It's not an urgent request, just an idea for future improvement.

  3. dap0am commented on Aug 20, 2025

    @dap0am
    Contributor

    Can I start working on this? I think I have an idea.

  4. leandrodamascena commented on Aug 20, 2025

    @leandrodamascena
    Contributor

    Yes @dap0am please go ahead!

  5. powertools-for-aws-oss-automation commented on Sep 11, 2025

    @powertools-for-aws-oss-automation

    Warning

    This issue is now closed. Please be mindful that future comments are hard for our team to see.
    If you need more assistance, please either reopen the issue, or open a new issue referencing this one.
    If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions