-
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
Hey, I just met you, and this is crazy, but lets put routes in a module... Blueprints maybe? #651
Conversation
45ad987
to
4b14ce0
Compare
138842b
to
e3cfc82
Compare
👍 I really like the idea of blueprints for chalice. One thing that I think we should consider is how (or if) this is going to affect other decorators other than What do others think? cc @kyleknap @stealthycoin |
Just giving my initial thoughts so far. Will do a little deeper review later... I like the idea as well. In terms of the Not sure if it needs to be included in this initial implementation, but I do think adding support for the other decorators in the blueprint would be useful. Specifically, I think it could be useful for logically assigning lambda functions to a particular blueprint so that they are better organized and can potentially be reused. Furthermore, I think it will be even more powerful once we implement managed resources as I imagine you would be able to register resources to a blueprint as well. |
Just want to add an additional voice from someone using Chalice for production grade purposes. My app.py is over 300 lines now and I'd love to be able to split that up by object with something like Blueprints just to improve readability. Not a deal breaker by any means, but I like the PR. |
I'm wondering what the status of this is, as I would absolutely love this feature. |
Hi everyone, just following up here. This is a fairly large (and useful!) change to chalice that I think will require some experimentation before we get a solid API. Once it lands in master we do have to preserve backwards compatibility. At the same time I don't want this to sit any longer in a PR until then. Here's what I'd propose. I think we should create an Let me know what you all think about this. cc / @aws/aws-sdk-python-team |
@jamesls I like the idea of the |
I kind of feel like an I think a better way of implementing it is to use feature flags to enable experimental features. This allows people to opt into experimental features on a feature by feature basis. It reduces the drift problem (because This gets a lot harder to deal with when you have whole new experimental functions rather than experimental data paths in existing functions, but that largely comes down to how the feature flags are implemented. At worst you can have a experimental namespace that stuff can live in, before it moves into the non experimental namespace. |
I've not seen too many open source projects manage new things with flags like that, @dstufft but I have done that plenty of times with customer facing projects. Either way though, I'm up to 650 lines in my app.py file, so I'd be happy to help develop this and have a good real world production app to help test it against. |
I also think that experimental branches cause more trouble than they are worth and ultimately increase the time (and work) it takes to merge features. I honestly think that simply declaring a portion of the code as unstable but including it in the main branch is the way to go. This is how the Github API gets updated- they release the new features but you opt into using them knowing that you'll need to put more work into maintaining compatibility until they are stable. Even outside of that I think this is an important enough feature that it should be fast tracked. Once blueprints are added we get considerably easier testing and the ability to create third party extensions (which is currently very difficult because of the need to work off of the primary |
I like the idea of feature flags, but I've never seen it used in the context of a library. I've seen it in web apps and backend APIs, but how does it work with a python API? So let's take this PR as an example. Are you saying that until you enable some feature flag (in the app config file?) the Or what about the Resources proposal? #516 This would add new modues such as If that's true then it feels like you'd have the code littered with
and then any consuming code that uses It seems like you're trading off complex repo management via complicated cherry-picked merges vs. more complex code. Are there any existing libraries that use feature flags that we could use as inspiration? |
I think the easiest way to handle this for things where the API isn't finished but people want to start using the code you could place things into an experimental package, such that This method is nice because it requires the user to explicitly acknowledge the experimental status during import without requiring the writers of the code to do a bunch of "is feature enabled" checks. A downside to this method is that it makes changes to the application class itself difficult to do in an experimental feature- using this case as an example the I want to stress though that blueprints will make this a lot easier in the future, as it will allow these types of features to be created in completely standalone modules until they're ready to be merged into core (if there even is a need for that). |
Yeah so just to be clear, I'm working on getting this PR in a shape that we can merge, regardless of where we decide to put it. That being said, the only downside to the |
@jamesiri - yeah, it would result in a code change, but a fairly minimum one. If there's real concern that people aren't testing code before pushing upgrades into production that can be solved by a simple wrapper at the With the experimental branch you're either committing to keeping that branch in sync (lots of work for you) or forcing users to pick between new features in the master branch or the experimental features they need. In my opinion it really comes down to who ends up having to do more work (you maintaining the experiments branches or users having to test their code), and in my experience the more work put on the maintainer the slower the features get pushed out to users. |
As a user of this code I'd rather get the features faster- knowing that I'll have to put in extra work if I'm using experimental features- than have a long period of development before the features are available. |
If we feel like this code can be done with |
Just wanted to give an update: I've created a separate tracking issue for what to do about experimental features (#1019) so we can keep this PR about blueprints. I have an update that adds support for all the decorators. The only big deviation between what I have and what Flask can do is that you can register a blueprint multiple times in a single app. The way this is implemented now is you can only register a blueprint to an app once. This simplifies the implementation and will likely result in this getting merged quicker. Does anyone need the ability to register a single blueprint to an app multiple times? |
@jamesis - the biggest argument for being able to register a blueprint repeatedly to different apps is for testing purposes. Removing that ability makes testing a little more complicated, but ultimately isn't the biggest deal. |
Use case
I have been working on a chalice based app lately that is growing a bit beyond having all routes set up in
app.py
.Being heavily influenced by Flask's API, I figured Blueprints might be a welcome addition for Chalice.
Status of this PR
This is mostly intended as a provisional or "Request for Comment" PR. If the maintainers of Chalice like this approach, I'd be happy to continue work on adding tests and documentation for this :)
Currently only very basic functionality exists:
chalice.blueprint.Blueprint
objectchalice.blueprint.Blueprint
instance with theroute
decorator, which should accept all the same Keyword Arguments as a vanillaChalice.route
... though i'm not sure if they'll all work :)current_request
access inBlueprint
routesurl_for
inBlueprint
routes.Example!
/app.py
/chalicelib/blueprint.py
Demo!