Hello,
what design patterns would you suggest to make blueprints as lazy as
possible? I had a huge centralized app.url_map.add(...) before
switching to blueprints and I use lazy pluggable views (see Flask
docs). Having each blueprint in package, I now realized it's
impossible to keep it all lazy anymore. If I put
bla = Blueprint('bla', __name__, template_folder='templates', url_prefix='/bla')
into __init__.py of the package, I have to do this in my app initialization
app.register_blueprint(bla)
and that means I have to import bla and thus also whole the blueprint
package with all views. Moreover, I can't find out how to add
blueprint rules in a centralized way similar to app.url_map.add(...)
using werkzeug Rule class, not by decorators. Thanks for any
suggestions.
Honza
I found this old thread, where Honza Javorek wrote: >>> Hello, >>> >>> what design patterns would you suggest to make blueprints as lazy as >>> possible? I had a huge centralized app.url_map.add(...) before >>> switching to blueprints and I use lazy pluggable views (see Flask >>> docs). Having each blueprint in package, I now realized it's >>> impossible to keep it all lazy anymore. If I put >>> >>> bla = Blueprint('bla', __name__, template_folder='templates', url_prefix='/bla') >>> >>> into __init__.py of the package, I have to do this in my app initialization >>> >>> app.register_blueprint(bla) >>> >>> and that means I have to import bla and thus also whole the blueprint >>> package with all views. Moreover, I can't find out how to add >>> blueprint rules in a centralized way similar to app.url_map.add(...) >>> using werkzeug Rule class, not by decorators. Thanks for any >>> suggestions. ... and then answered himself: > You are right, I later noticed I don't have to use: > > bla = Blueprint('bla', __name__) > > ...I can use this: > > bla = Blueprint('bla', 'path.to.package.bla') But I think his answer is only about a way to do lazy loading inside blueprints. I think there should be a way to lazy-load the blueprint itself. Basically, what I want is something like: from flask import Blueprint class LazyBlueprint(Blueprint): def __init__(self, name, import_name, static_folder=None, static_url_path=None, template_folder=None, url_prefix=None, subdomain=None, url_defaults=None): self.views = '.'.join(name.split('.')[:-1]+['views']) self.lazyloader = self.add_url_rule('/<path:endpoint>', 'lazyloader', self.lazyloader) def lazyloader(self, endpoint, **kw): self.lazyloader.remove_url_rule() #THIS DOESN'T WORK self.addviews(self.views) self.redispatch(endpoint, **kw) Is this somehow against the Flask Zen? If it isn't, would it be crazy for me to do it? Thanks, Jameson
If the reason you have for lazy loading blueprints is to dinamically extend the application at runtime, then you can use a middleware like shown here: http://flask.pocoo.org/docs/patterns/appdispatch/ The difference is that instead of routing to another application, you can recreate the application with the loaded blueprint. Of couse, that only makes sense if you need to extend the application without restarting the wsgi server. On Thu, Mar 8, 2012 at 11:21 AM, Jameson Quinn <jameson.quinn@gmail.com> wrote: > I found this old thread, where Honza Javorek wrote: > >>>> Hello, >>>> >>>> what design patterns would you suggest to make blueprints as lazy as >>>> possible? I had a huge centralized app.url_map.add(...) before >>>> switching to blueprints and I use lazy pluggable views (see Flask >>>> docs). Having each blueprint in package, I now realized it's >>>> impossible to keep it all lazy anymore. If I put >>>> >>>> bla = Blueprint('bla', __name__, template_folder='templates', > url_prefix='/bla') >>>> >>>> into __init__.py of the package, I have to do this in my app >>>> initialization >>>> >>>> app.register_blueprint(bla) >>>> >>>> and that means I have to import bla and thus also whole the blueprint >>>> package with all views. Moreover, I can't find out how to add >>>> blueprint rules in a centralized way similar to app.url_map.add(...) >>>> using werkzeug Rule class, not by decorators. Thanks for any >>>> suggestions. > > ... and then answered himself: > >> You are right, I later noticed I don't have to use: >> >> bla = Blueprint('bla', __name__) >> >> ...I can use this: >> >> bla = Blueprint('bla', 'path.to.package.bla') > > But I think his answer is only about a way to do lazy loading inside > blueprints. I think there should be a way to lazy-load the blueprint itself. > Basically, what I want is something like: > > from flask import Blueprint > > > class LazyBlueprint(Blueprint): > def __init__(self, name, import_name, static_folder=None, > static_url_path=None, template_folder=None, > url_prefix=None, subdomain=None, url_defaults=None): > self.views = '.'.join(name.split('.')[:-1]+['views']) > self.lazyloader = self.add_url_rule('/<path:endpoint>', > 'lazyloader', self.lazyloader) > > def lazyloader(self, endpoint, **kw): > self.lazyloader.remove_url_rule() #THIS DOESN'T WORK > self.addviews(self.views) > self.redispatch(endpoint, **kw) > > > Is this somehow against the Flask Zen? If it isn't, would it be crazy for me > to do it? > > Thanks, > Jameson
No, what I want is to be able to register a blueprint without loading all
the views, but still use decorators instead of add_url_rule inside the
blueprint. So the views for the blueprint would all be loaded at once, the
first time an endpoint (including a 404) inside the blueprint were
addressed.
I realize that this could lead to intermittent bugs if I were using url_for
from outside to inside this blueprint; it would work fine only as long as
I'd hit something inside the blueprint first, but blow up if I hadn't. As
long as url_for("myblueprint.index") worked, that's not an issue for me; I
don't need "deep linking".
Basically, I'm asking for sugar, since I can always get what I need using
add_url_rule; but I think it's sugar that a lot of people would happily use
if it existed.
Btw: Thanks for the response, and sorry I wasn't clearer the first time.
Jameson
2012/3/8 Thiago Padilha <tpadilha84@gmail.com>
> If the reason you have for lazy loading blueprints is to dinamically
> extend the application at runtime, then you can use a middleware like
> shown here: http://flask.pocoo.org/docs/patterns/appdispatch/
>
> The difference is that instead of routing to another application,
> you can recreate the application with the loaded blueprint. Of couse,
> that only makes sense if you need to extend the application without
> restarting the wsgi server.
>
>
> On Thu, Mar 8, 2012 at 11:21 AM, Jameson Quinn <jameson.quinn@gmail.com>
> wrote:
> > I found this old thread, where Honza Javorek wrote:
> >
> >>>> Hello,
> >>>>
> >>>> what design patterns would you suggest to make blueprints as lazy as
> >>>> possible? I had a huge centralized app.url_map.add(...) before
> >>>> switching to blueprints and I use lazy pluggable views (see Flask
> >>>> docs). Having each blueprint in package, I now realized it's
> >>>> impossible to keep it all lazy anymore. If I put
> >>>>
> >>>> bla = Blueprint('bla', __name__, template_folder='templates',
> > url_prefix='/bla')
> >>>>
> >>>> into __init__.py of the package, I have to do this in my app
> >>>> initialization
> >>>>
> >>>> app.register_blueprint(bla)
> >>>>
> >>>> and that means I have to import bla and thus also whole the blueprint
> >>>> package with all views. Moreover, I can't find out how to add
> >>>> blueprint rules in a centralized way similar to app.url_map.add(...)
> >>>> using werkzeug Rule class, not by decorators. Thanks for any
> >>>> suggestions.
> >
> > ... and then answered himself:
> >
> >> You are right, I later noticed I don't have to use:
> >>
> >> bla = Blueprint('bla', __name__)
> >>
> >> ...I can use this:
> >>
> >> bla = Blueprint('bla', 'path.to.package.bla')
> >
> > But I think his answer is only about a way to do lazy loading inside
> > blueprints. I think there should be a way to lazy-load the blueprint
> itself.
> > Basically, what I want is something like:
> >
> > from flask import Blueprint
> >
> >
> > class LazyBlueprint(Blueprint):
> > def __init__(self, name, import_name, static_folder=None,
> > static_url_path=None, template_folder=None,
> > url_prefix=None, subdomain=None, url_defaults=None):
> > self.views = '.'.join(name.split('.')[:-1]+['views'])
> > self.lazyloader = self.add_url_rule('/<path:endpoint>',
> > 'lazyloader', self.lazyloader)
> >
> > def lazyloader(self, endpoint, **kw):
> > self.lazyloader.remove_url_rule() #THIS DOESN'T WORK
> > self.addviews(self.views)
> > self.redispatch(endpoint, **kw)
> >
> >
> > Is this somehow against the Flask Zen? If it isn't, would it be crazy
> for me
> > to do it?
> >
> > Thanks,
> > Jameson
>
Le 15/11/2011 13:25, Honza Javorek a écrit : > Hello, > > what design patterns would you suggest to make blueprints as lazy as > possible? I had a huge centralized app.url_map.add(...) before > switching to blueprints and I use lazy pluggable views (see Flask > docs). Having each blueprint in package, I now realized it's > impossible to keep it all lazy anymore. If I put > > bla = Blueprint('bla', __name__, template_folder='templates', url_prefix='/bla') > > into __init__.py of the package, I have to do this in my app initialization > > app.register_blueprint(bla) > > and that means I have to import bla and thus also whole the blueprint > package with all views. Moreover, I can't find out how to add > blueprint rules in a centralized way similar to app.url_map.add(...) > using werkzeug Rule class, not by decorators. Thanks for any > suggestions. Hi, How about keeping the same patterns of centralized maps and lazy views at the blueprint levels so that blueprints are cheap to load? Regards, -- Simon Sapin
You are right, I later noticed I don't have to use:
bla = Blueprint('bla', __name__)
...I can use this:
bla = Blueprint('bla', 'path.to.package.bla')
which basically solves everything. However, I found another problem, a
bit different. Lazy views as defined here
http://flask.pocoo.org/docs/patterns/lazyloading/ does not provide
"methods" and "decorators" class properties (
http://flask.pocoo.org/docs/views/#method-hints and
http://flask.pocoo.org/docs/views/#decorating-views ). I have no idea
how to solve it and keep it lazy. Well, I can define methods somewhere
else, but I'd really like to define decorators with the class :-(
Any ideas? Thanks,
Honza
On Tue, Nov 15, 2011 at 13:40, Simon Sapin <simon.sapin@exyr.org> wrote:
> Le 15/11/2011 13:25, Honza Javorek a écrit :
>> Hello,
>>
>> what design patterns would you suggest to make blueprints as lazy as
>> possible? I had a huge centralized app.url_map.add(...) before
>> switching to blueprints and I use lazy pluggable views (see Flask
>> docs). Having each blueprint in package, I now realized it's
>> impossible to keep it all lazy anymore. If I put
>>
>> bla = Blueprint('bla', __name__, template_folder='templates',
url_prefix='/bla')
>>
>> into __init__.py of the package, I have to do this in my app initialization
>>
>> app.register_blueprint(bla)
>>
>> and that means I have to import bla and thus also whole the blueprint
>> package with all views. Moreover, I can't find out how to add
>> blueprint rules in a centralized way similar to app.url_map.add(...)
>> using werkzeug Rule class, not by decorators. Thanks for any
>> suggestions.
>
> Hi,
>
> How about keeping the same patterns of centralized maps and lazy views
> at the blueprint levels so that blueprints are cheap to load?
>
> Regards,
> --
> Simon Sapin
>
Ah... sorry :) I always find out the solution right after being
totally desperate and posting a message about it or telling to a
friend... Solution is:
def __call__(self, *args, **kwargs):
view = self.view.as_view(...)
for decorator in view.decorators:
view = decorator(view)
return view(*args, **kwargs)
in lazy view.
Honza
On Tue, Nov 15, 2011 at 16:00, Honza Javorek <honza@javorek.net> wrote:
> You are right, I later noticed I don't have to use:
>
> bla = Blueprint('bla', __name__)
>
> ...I can use this:
>
> bla = Blueprint('bla', 'path.to.package.bla')
>
> which basically solves everything. However, I found another problem, a
> bit different. Lazy views as defined here
> http://flask.pocoo.org/docs/patterns/lazyloading/ does not provide
> "methods" and "decorators" class properties (
> http://flask.pocoo.org/docs/views/#method-hints and
> http://flask.pocoo.org/docs/views/#decorating-views ). I have no idea
> how to solve it and keep it lazy. Well, I can define methods somewhere
> else, but I'd really like to define decorators with the class :-(
>
> Any ideas? Thanks,
> Honza
>
>
>
>
>
> On Tue, Nov 15, 2011 at 13:40, Simon Sapin <simon.sapin@exyr.org> wrote:
>> Le 15/11/2011 13:25, Honza Javorek a écrit :
>>> Hello,
>>>
>>> what design patterns would you suggest to make blueprints as lazy as
>>> possible? I had a huge centralized app.url_map.add(...) before
>>> switching to blueprints and I use lazy pluggable views (see Flask
>>> docs). Having each blueprint in package, I now realized it's
>>> impossible to keep it all lazy anymore. If I put
>>>
>>> bla = Blueprint('bla', __name__, template_folder='templates',
url_prefix='/bla')
>>>
>>> into __init__.py of the package, I have to do this in my app initialization
>>>
>>> app.register_blueprint(bla)
>>>
>>> and that means I have to import bla and thus also whole the blueprint
>>> package with all views. Moreover, I can't find out how to add
>>> blueprint rules in a centralized way similar to app.url_map.add(...)
>>> using werkzeug Rule class, not by decorators. Thanks for any
>>> suggestions.
>>
>> Hi,
>>
>> How about keeping the same patterns of centralized maps and lazy views
>> at the blueprint levels so that blueprints are cheap to load?
>>
>> Regards,
>> --
>> Simon Sapin
>>
>