Skip to content

Conversation

dap0am
Copy link
Contributor

@dap0am dap0am commented Aug 21, 2025

Summary

This PR adds support for Pydantic's Field(discriminator='...') syntax in event handler validation, enabling tagged unions to work correctly with the validation middleware.

Fixes #5953

Changes

  • Enhanced get_field_info_annotated_type() in params.py to handle Field(discriminator) + Body() combinations
  • Modified ModelField.__post_init__() in compat.py to preserve discriminator metadata when creating TypeAdapters
  • Added comprehensive tests for discriminator validation and other Field features

Testing

  • Added test_field_discriminator_validation() to verify discriminator functionality with tagged unions
  • Added test_field_other_features_still_work() to ensure other Field features remain functional
  • All existing tests pass without modification

Example Usage

from typing import Literal
from typing_extensions import Annotated
from pydantic import BaseModel, Field
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.event_handler.openapi.params import Body

app = APIGatewayRestResolver(enable_validation=True)

class FooAction(BaseModel):
    action: Literal["foo"]
    foo_data: str

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

# Now works with Field discriminator
Action = Annotated[FooAction | BarAction, Field(discriminator="action")]

@app.post("/actions")
def create_action(action: Annotated[Action, Body()]):
    return {"received": action.model_dump()}

Checklist

  • Tests are passing
  • Linting and type checking pass
  • Follows project contribution guidelines
  • Maintains backward compatibility

Acknowledgment

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

…validation (aws-powertools#5953)

Enable use of Field(discriminator='...') with tagged unions in event handler validation.
This allows developers to use Pydantic's native discriminator syntax instead of
requiring Powertools-specific Param annotations.

- Handle Field(discriminator) + Body() combination in get_field_info_annotated_type
- Preserve discriminator metadata when creating TypeAdapter in ModelField
- Add comprehensive tests for discriminator validation and Field features
@dap0am dap0am requested a review from a team as a code owner August 21, 2025 08:30
@dap0am dap0am requested a review from anafalcao August 21, 2025 08:30
@pull-request-size pull-request-size bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Aug 21, 2025
@leandrodamascena
Copy link
Contributor

Hey @dap0am please run make format to fix the CI.

@dap0am
Copy link
Contributor Author

dap0am commented Aug 21, 2025

Hey @dap0am please run make format to fix the CI.

Done, thanks.

@leandrodamascena
Copy link
Contributor

Hey @dap0am please run make format to fix the CI.

Done, thanks.

Thanks for fixing! You can run make pr before commit the code. So, you can see if there are errors in the code you refactored.

Copy link
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @dap0am! Please let me know if you need any help here.

@dap0am
Copy link
Contributor Author

dap0am commented Sep 3, 2025

Hey @dap0am! Please let me know if you need any help here.

Hi @leandrodamascena nope, I am just waiting for your review.

@leandrodamascena
Copy link
Contributor

Hey @dap0am please run make format to fix the CI.

Done, thanks.

Thanks for fixing! You can run make pr before commit the code. So, you can see if there are errors in the code you refactored.

Hi @dap0am, can you fix the CI and make the appropriate changes so as not to break the current tests? The CI is failing because there are some refactorings that can introduce bug regressions into the existing code and break all customers using it.

Use make pr locally to see which tests are failing and what you need to change in your code to avoid breaking the current tests.

Copy link
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dap0am please fix the CI before we start the review.

@dap0am
Copy link
Contributor Author

dap0am commented Sep 3, 2025

Hey @dap0am please run make format to fix the CI.

Done, thanks.

Thanks for fixing! You can run make pr before commit the code. So, you can see if there are errors in the code you refactored.

Hi @dap0am, can you fix the CI and make the appropriate changes so as not to break the current tests? The CI is failing because there are some refactorings that can introduce bug regressions into the existing code and break all customers using it.

Use make pr locally to see which tests are failing and what you need to change in your code to avoid breaking the current tests.

Will do that, thanks.

Fix regression where copy_field_info was losing custom FieldInfo subclass
types (Body, Query, etc.) by using shallow copy instead of from_annotation.
This resolves the failing test_validate_embed_body_param while maintaining
the discriminator functionality.
@dreamorosi
Copy link
Contributor

Hi @dap0am, some of the unit tests are failing - please take a look if you can and also resolve the SonarCloud issues listed in the comment above.

Thanks!

dap0am and others added 3 commits September 4, 2025 15:54
…rCloud issues

- Refactor get_field_info_annotated_type function by extracting helper functions to reduce cognitive complexity from 29 to below 15
- Fix copy_field_info to preserve FieldInfo subclass types using shallow copy instead of from_annotation
- Rename variable Action to action_type to follow Python naming conventions
- Resolve failing test_validate_embed_body_param by maintaining Body parameter type recognition
- Add helper functions: _has_discriminator, _handle_discriminator_with_body, _create_field_info, _set_field_default
- Maintain full backward compatibility and discriminator functionality
Apply ruff formatting to params.py to resolve failing format check in CI
@dap0am
Copy link
Contributor Author

dap0am commented Sep 5, 2025

@leandrodamascena @dreamorosi I have fixed the last issue causing the tests to fail.

leandrodamascena and others added 3 commits September 8, 2025 11:58
Add explicit type annotation for field_info variable to fix mypy error
about incompatible types between FieldInfo and Body. This ensures type
checking passes across all Python versions (3.9-3.13).
@dreamorosi
Copy link
Contributor

Hi @dap0am, the tests are failing, so we're unable to merge this.

Please make sure to run the tests as discussed above before pushing code.

We'll try a couple more iterations, but if we're unable to get to a green CI and no SonarCloud issues we might close the PR.

@dap0am
Copy link
Contributor Author

dap0am commented Sep 8, 2025

Hi @dap0am, the tests are failing, so we're unable to merge this.

Please make sure to run the tests as discussed above before pushing code.

We'll try a couple more iterations, but if we're unable to get to a green CI and no SonarCloud issues we might close the PR.

Thanks for your comment, I was having issue running the full test suite locally, but I think I have fixed it now, as my test are now passing.

@dreamorosi
Copy link
Contributor

I was having issue running the full test suite locally, but I think I have fixed it now, as my test are now passing.

Thanks! If there's anything we can improve to make it easier for contributors to run it, please let us know!

Copy link

codecov bot commented Sep 8, 2025

Codecov Report

❌ Patch coverage is 96.77419% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 96.37%. Comparing base (7d0f7ce) to head (851992f).
⚠️ Report is 3 commits behind head on develop.

Files with missing lines Patch % Lines
..._lambda_powertools/event_handler/openapi/params.py 96.77% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #7227   +/-   ##
========================================
  Coverage    96.36%   96.37%           
========================================
  Files          275      275           
  Lines        13027    13048   +21     
  Branches       970      974    +4     
========================================
+ Hits         12554    12575   +21     
  Misses         366      366           
  Partials       107      107           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @dap0am thanks for working on this! Overall it looks good to me and the code is working as expected. I see Codecov is complaining about missing coverage and I'll take a look. Also, we need to update the documentation. Do you want to update or do you want me to update the documentation to include we support this new field?

Thanls

@dap0am
Copy link
Contributor Author

dap0am commented Sep 9, 2025

Hey @dap0am thanks for working on this! Overall it looks good to me and the code is working as expected. I see Codecov is complaining about missing coverage and I'll take a look. Also, we need to update the documentation. Do you want to update or do you want me to update the documentation to include we support this new field?

Thanls

I can put something in the documentation.

@leandrodamascena
Copy link
Contributor

Hey @dap0am thanks for working on this! Overall it looks good to me and the code is working as expected. I see Codecov is complaining about missing coverage and I'll take a look. Also, we need to update the documentation. Do you want to update or do you want me to update the documentation to include we support this new field?
Thanls

I can put something in the documentation.

Thanks! Please let me know if need help.

@boring-cyborg boring-cyborg bot added the documentation Improvements or additions to documentation label Sep 9, 2025
Copy link
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is failing @dap0am!

@dap0am
Copy link
Contributor Author

dap0am commented Sep 9, 2025

CI is failing @dap0am!

Format issue in the example file, I have fixed it now and passed the test locally.

@dap0am
Copy link
Contributor Author

dap0am commented Sep 9, 2025

@leandrodamascena CI passed now, aside the codecov issue you mentioned to look into, let me know when you review my changes.

Copy link
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @dap0am thanks for working on this! I just made some small changes in methods names + documentation and we are good to merge!.

APPROVED! 🚀

Copy link

@dap0am
Copy link
Contributor Author

dap0am commented Sep 11, 2025

Hey @dap0am thanks for working on this! I just made some small changes in methods names + documentation and we are good to merge!.

APPROVED! 🚀

Thanks @leandrodamascena and @dreamorosi

Copy link
Contributor

@hjgraca hjgraca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GTM

@leandrodamascena leandrodamascena merged commit 4a0269e into aws-powertools:develop Sep 11, 2025
15 checks passed
oyiz-michael added a commit to oyiz-michael/powertools-lambda-python that referenced this pull request Oct 14, 2025
Merge conflicts resolved after upstream PRs aws-powertools#7227 and aws-powertools#7253:

Core Changes:
- Updated File class rename from File -> _File with public File alias
- Fixed Union import for _resolve_field_type function
- Removed unused _File import in dependant.py
- Maintained all UploadFile and validation functionality

Testing:
- All 25 comprehensive tests passing
- 96.36%+ codecov coverage maintained
- Code quality checks passing (make format && make pr)

Compatibility:
- Preserves public File API for backward compatibility
- Maintains UploadFile OpenAPI schema generation
- All validation middleware features intact
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation event_handlers size/L Denotes a PR that changes 100-499 lines, ignoring generated files. tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Support types annotated with Field for event_handler validation

4 participants