librelist archives

« back to archive

Lazy Blueprints, centralized routing

Lazy Blueprints, centralized routing

From:
Honza Javorek
Date:
2011-11-15 @ 12:25
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

Re: Lazy Blueprints, centralized routing

From:
Jameson Quinn
Date:
2012-03-08 @ 14:21
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

Re: [flask] Re: Lazy Blueprints, centralized routing

From:
Thiago Padilha
Date:
2012-03-08 @ 14:46
  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

Re: [flask] Re: Lazy Blueprints, centralized routing

From:
Jameson Quinn
Date:
2012-03-08 @ 15:05
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
>

Re: [flask] Lazy Blueprints, centralized routing

From:
Simon Sapin
Date:
2011-11-15 @ 12:40
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

Re: [flask] Lazy Blueprints, centralized routing

From:
Honza Javorek
Date:
2011-11-15 @ 15:00
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
>

Re: [flask] Lazy Blueprints, centralized routing

From:
Honza Javorek
Date:
2011-11-15 @ 15:06
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
>>
>