-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Add support for blueprints #1023
Conversation
This adds support for Flask style blueprints. As part of this change, the internals app.py have been refactored to remove duplication when registering resources. This should make it easier to refactor the event sources into separate classes in the future.
Codecov Report
@@ Coverage Diff @@
## master #1023 +/- ##
==========================================
- Coverage 95.47% 95.45% -0.03%
==========================================
Files 27 27
Lines 4488 4528 +40
Branches 563 569 +6
==========================================
+ Hits 4285 4322 +37
- Misses 131 134 +3
Partials 72 72
Continue to review full report at Codecov.
|
Looking forward to this. :) 👍 |
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.
Looks pretty good just had some comments/questions. A couple things that I am wondering if you have thought about are:
- Is there a plan to do nested blueprints? I saw that in flask people were requesting it and I could see people wanting them in chalice as well.
- I think blueprints could be really powerful mechanism for providing 3rd party chalice packages that people can
pip install
and then register the blueprints from the package to their application. Have you looked into that at all or tried it out? I may take some time playing around with this.
return {'foo': 'bar'} | ||
|
||
|
||
The ``__name__`` is used to denote the import path of the blueprint. This must |
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.
Could you elaborate on why the import_name
is a required parameter when it seems like most of the time users will be supplying __name__
? When will the import_name
not be __name__
?
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.
One reason is that it keeps the API the same as Flask, allowing people to port their code over a bit easier.
A second reason is that a single package can occasionally have multiple blueprints.
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 was mainly more focused on why it is a required parameter as opposed to being an optional parameter that set the import_name
to __name__
when not provided. That should still allow people to port it over from Flask pretty easily and set their own import_name
if need be.
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.
There wasn't a strong reason it was required other than to mimic the Flask API. I thought it would be good to make people aware of this parameter rather than to default it for them, but I don't have a strong reason why it needs to be required.
|
||
def _register_authorizer(self, name, handler_string, wrapped_handler, | ||
kwargs, **unused): | ||
actual_kwargs = kwargs.copy() |
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.
This looks like we just copied over the logic from the previous implementation, but do we still need to do the kwargs
copying and popping when we are the ones providing the kwargs
to this helper method?
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 don't think we should be relying on that. I'd try to avoid mutating input parameters where possible.
@@ -0,0 +1,198 @@ | |||
Blueprints | |||
========== |
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.
Are we planning on adding API references as well for the Blueprints
class? It might be useful at the very least to document the initializer and maybe have a link to the app decorator documentation for each decorator.
@foo.on_sqs_message('MyQueue') | ||
def on_sqs(event): | ||
pass | ||
|
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.
For this test, is there any way to make sure we update this test whenever we add a new decorator?
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.
We could maybe verify that every public method on DecoratorAPI
is also on the blueprint class? In practice I don't think this test is super useful. I originally added it when I was duplicating the decorators in the Blueprint
class. Now this test would be verifying that we're subclassing from the DecoratorAPI
.
No, not right now.
Not specifically, but I AFAICT this should just work. You need to FWIW I don't I'd recommend blueprints for reusable components in its current form now. The big missing piece is a way to specify configuration of some sort. This was alluded to in #608 with "application parameters", but I think you'd need that in order to create reusable packages. It's also not really used that way in Flask (or at least its documentation says its not for reusable components). |
@kyleknap I think I've incorporated everything so far except for the |
The updates look good. As to the
|
@kyleknap actually I don't think we can do this. The issue is that we need the import name of the module where the blueprint is created. We can't default that in the class Blueprint:
def __init__(self):
self._import_name = __name__ then |
Gotcha. Yeah that's a little unfortunate, but makes sense. Let's go ahead and keep it as required. |
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.
The code itself looks good. I think we can just push it to an branch on the chalice repository until we decide what to do about experimental features and close out this PR.
PR #1023 * feature-flags: Add feature opt in test through CLI layer Fix linting error for line spacing Update docs with a link to GH issues Move error message to constant Change link from rst to html Add documentation for feature flags Add support for experimental features
Merged via #1057 |
This adds support for Flask style blueprints.
As part of this change, the internals app.py have been refactored
to remove duplication when registering resources. This should make
it easier to refactor the event sources into separate classes
in the future.
This builds on the work from @ewdurbin #651 (thanks!)
I still think this needs some discussion, and we'll need to figure out where it goes based on the outcome of #1019