bottlepy / bottle

bottle.py is a fast and simple micro-framework for python web-applications.
http://bottlepy.org/
MIT License
8.34k stars 1.46k forks source link

Question: Get route inside of a wsgi middleware #1249

Closed SaschaHeyer closed 3 years ago

SaschaHeyer commented 3 years ago

Hi bottle Folks,

is there a way to get the route inside of a middleware? Similar to flasks request.url_rule

Sample

@bottle.route('/test/<name>')

Would like to get the route /test/<name> inside of the middleware.

Best regards Sascha

PyB1l commented 3 years ago

Hi there, you mean that you need to get the /test/<name>string? Or you need to get every time the '/test/spesific-name' on every request?

SaschaHeyer commented 3 years ago

Hi Papavassiliou,

appreciate your fast response.

exactly /test/<name>. Writing a middleware to log metrics and I need the route instead of some values.

PyB1l commented 3 years ago

I would suggest to use a plugin approach in order to create your feature. How can do it using a middleware class, but it's less elegant and will require to use more bottle "internal" stuff. Plugin interface provides you with a route instance per request ad you can use it directly without worrying about WSGI ENV

For instance:


class LoggerPlugin(object):
    """Bottle.py application plugin for logging
    """
    api = 2

    def __init__(self, keyword='logger'):
        self.keyword = keyword

    def setup(self, app): 
        """Make sure that other installed plugins don't affect the same
        keyword argument and check if metadata is available.
        """

        for other in app.plugins:
            if not isinstance(other, LoggerPlugin):
                continue
            if other.keyword == self.keyword:
                raise bottle.PluginError("Found another plugin "
                                         "with conflicting settings ("
                                         "non-unique keyword).")

    def apply(self, callback, route):
        """Implement bottle.py API version 2 `apply` method.
        """

        def _wrapper(*args, **kwargs):
            """Decorated Injection
            """
            your_value = route.rule  # Route instance has a `rule` attribute which contains what you need
            # DO YOUR LOGGING
            return callback(*args, **kwargs)

        return _wrapper

# In your bottle.Bottle instance.
app.install(LoggerPlugin())
SaschaHeyer commented 3 years ago

This looks like a reasonable way. Will go with a plugin. Thanks a lot