Open gabrielalan opened 9 years ago
Wouldn't it be simpler to create a wrapper function that would be registered as route handler and instantiate an appropriate class when it's about to handle a request?
EDIT: The wrapper function could be a class method, too.
Methods aren't "instantiated" in any meaningful way. Can you post some example code of what you want to work?
@foxbunny I see. But the route for that wrapper, must be a "wildcard" route, doesn't? Or there are a "bottle native way" to create a route wrapper function?
@eric-wieser Of course
class Router():
@app.route('/')
def index():
return template('index', name="to home")
@app.route('/hello')
@app.route('/hello/<name>')
def hello(name='Stranger'):
return template('index', name=name)
# on other file
instance = Router()
EDIT: This work today, BUT if I create another Router class, it have to be instantiated. And on a real enviroment where there are many routers, I think that is not a good pratice.
What purpose does your Router
class serve here? Your code works even if I don't instantiate the router:
class Router():
# @app.route runs at declaration-time, not instantiation time
@app.route('/')
def index():
return template('index', name="to home")
@app.route('/hello')
@app.route('/hello/<name>')
def hello(name='Stranger'):
return template('index', name=name)
And furthermore, if I do instantiate it, the instance is useless:
instance = Router()
instance.hello(name='gabriel')
TypeError <some message about the missing self argument
There's no good reason for you not to just write:
@app.route('/')
def index():
return template('index', name="to home")
@app.route('/hello')
@app.route('/hello/<name>')
def hello(name='Stranger'):
return template('index', name=name)
@gabrielalan Ah, I see. I thought you were doing something along the lines of:
class RouteHandler(object):
def __init__(self, *args, **kwargs):
....
@classmethod
def handle(cls, *args, **kwargs):
return cls(*args, **kwargs)
@classmethod
def register(cls, app, path, method, *args, **kwargs):
app.route(path, method, cls.handle, *args, **kwargs)
Maybe I'm doing it wrong. The example above, is kind of simple code. I think I didn't express myself correctly.
But what I really want is something like that: https://webapp-improved.appspot.com/guide/routing.html#guide-routing-lazy-handlers
@foxbunny Your idea seems very good... I will test this.
What goal are you trying to achieve by lazy-loading routes?
Personally, I don't really see any advantage in lazy evaluation of route handlers, to be honest, though there could be valid use cases.
What I normally do is, avoid the route decorator, and do something like this in a central place:
app.route('/some/path/', 'GET', routes.foo.foo_handler)
app.route('/some/path/', 'POST', routes.foo.foo_post_handler)
...
You could wrap app.route
and use strings instead of module names with clever use of imp
and/or pkgutils
modules from the standard library, and/or __import__
call, but that still won't quite be lazy, as you'd be loading modules when you call the wrapper. So something like this:
route = router(app)
route('/some/path/', 'GET', 'routes.foo.foo_handler')
...
@eric-wieser @foxbunny
I think the advantage of having lazy handlers, is, not use resources that are not needed. For example, if the client goes to the initial route, I don't need to load the others routes. I don't want to load resources that I will not use. You see?
Edit: Thank you for the examples...
But eventually, any modules you load get cached, so even with lazy loading, you're not going to save much.
But surely you expect every route to be accessed within the lifetime of your server anyway?
Would this be useful when running something as CGI, for instance, where not every route might be instantiated (since the application has a short lifetime)?
Perhaps, but the original request for lazy-loading of methods is still meaningless. The only thing that is lazy-loadable is modules
Yeah
@foxbunny I see...
@eric-wieser yes...
Well, you opened my mind about ways to make a "route manager". I will try some ideas that you send me here, and I post the result that will perform better. Thank you for now :)
Hello,
Recently I started a personal project, where I use bottle.
But, thinking about the routes, I was searching for a way to do "lazy routes" where the methods that register a path to the route, dont need to be "called".
I implemented some classes, with methods that register routes, and I dont want to call them all, in the WSGI file.
Are there a way to do that?
Ps.: Sorry for my english