-
Notifications
You must be signed in to change notification settings - Fork 406
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(data_classes): return empty dict or list instead of None #4606
feat(data_classes): return empty dict or list instead of None #4606
Conversation
aws_lambda_powertools/utilities/data_classes/appsync_resolver_event.py
Outdated
Show resolved
Hide resolved
This simplifies the code internally and also for users. Also wrap all headers in CaseInsensitiveDict from requests. These changes replace the need of utility functions like get_header_value, get_query_string_value or get_multi_value_query_string_values, which are removed.
722d27f
to
c728d2f
Compare
Hello @ericbn! I am positively surprised by this PR. This is something we really need to fix in V3 and it would take us days to do it, but I'm glad you're shortening the path! I started taking a quick look at this PR and it looks like we're headed in the right direction! I saw small things that perhaps we can improve or understand better. I will start reviewing this PR on Monday and hope to get it merged next week! Really thanks for this amazing work! 🚀 |
Updating this PR: I started the review last week, but as there are a lot of details I plan to finish it this week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @ericbn! I have started reviewing this PR and have initial feedback that may be a block for further review. Can you check my comments and address them?
I would like to inform you that reviewing this PR will be an excellent source of new learning for me, I am very excited about it. Thanks!
This is hopefully a simpler implementations that the requests' package one, but still had to be minimally complex to be complete.
@leandrodamascena, PR updated. |
Perfect @ericbn! I'll continue the review today! |
Just a quick note: I'm still reviewing this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did another review. It will take a few more rounds before we approve it because this is huge and there are a lot of changes.
One thing I need to test a little more is where we return CaseInsensitiveDict
instead of self.get("headers"
), for example. This is returning the dictionary without lower in the keys, correct? Or do you always do lower?
Thank you very much for your patience, Eric. This PR has a lot of improvement for Powertools v3, it is, without a doubt, one of the great milestones of this Major release.
aws_lambda_powertools/utilities/data_classes/appsync_resolver_event.py
Outdated
Show resolved
Hide resolved
@leandrodamascena, I've updated the PR with the changes you proposed. Super productive conversation during the review BTW! |
Thanks for addressing them so quickly! And I say the same about the conversation. Working with open source projects sometimes take time to approve things, but working collaboratively makes things easier. I will continue the review. 🚀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @ericbn! I left some other comments but we're almost there!
There's only one thing I'm testing in the CaseInsensitiveDict
class, but I don't think we'll have any new thing.
I hope to merge this PR this week! Thanks a lot!
Some key points worth considering regarding your comments. In no particular order:
This is a good example of the first points above: assert parsed_event.headers["Authorization"] == "value" It's saying "I expect the Authorization header to exist and to have a value equal to 'value'". If the header didn't exist, the test would fail with KeyError. If the header did exist and had a different value, the assertion would fail with AssertionError. If it was a get instead, we would always get an AssertionError, but lose the ability to distinguish between "header did not exist" and "header exists and has a different value". Also, we would be delaying the error to the assert statement, arguably hiding the original cause of the error. And using get instead wound, I think, communicate a confusing intent.
I didn't use get in the cases where I thought getting a KeyError would be a better outcome than hiding the fact the the header didn't exist and replace that by a default value. I also didn't use get where the key is expected and would make the subsequent code fail otherwise. This is another good example of some of the points above: api_key = app.current_event.headers["X-Api-Key"]
todos: Response = requests.get(endpoint, headers={"X-Api-Key": api_key})
todos.raise_for_status() If we used get here instead, we would make a call to the endpoint with an empty X-Api-Key. This would fail at the moment of trying to do the request, which hides the original cause of the error: the X-Api-Key header didn't exist in app.current_event.headers.
Here it's good to think about the difference between I think we're using The specific case here has a clear nature: since header values cannot be Does it make sense and can we revisit your comments with these ideas in mind? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of places where we could do "key" not in headers
instead, now that this is possible with the new API.
You have great strengths here, @ericbn! Thank you for sharing so much knowledge and experience, I agree with the experience and intention to fail first. My argument was because we could prevent the client from failing in the Lambda environment, as it might be an event-driven architecture, for example, and failing because of a key is the kind of thing that could perhaps be avoided. On the other hand, if the code does not fail, it may create some side effects in the business logic. Anyway, if the customers wants to fail silently or avoid exception, there is still the option to use get and solve the problem. I'm going to resolve all comments. |
Quality Gate passedIssues Measures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @ericbn! Thank you for your patience after the long back and forth until we got here. This PR is approved and we plan to create an alpha release of V3 this week!
Once again, thank you very much for your work here!
Issue number: #2605
Summary
Changes
This simplifies the code internally and also for users.
Also wrap all headers in CaseInsensitiveDict from requests.
These changes replace the need of utility functions like get_header_value, get_query_string_value or get_multi_value_query_string_values, which are removed.
User experience
Before:
After:
Checklist
If your change doesn't seem to apply, please leave them unchecked.
Is this a breaking change?
RFC issue number:
Checklist:
Acknowledgment
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.