pythonmatomofalconframework

How can I intercept static routes in a falcon app?


I'm currently serving up files using a static route like so:

application.add_static_route('/artifacts/', '/artifacts/')

How can I add a function that is called before every GET to this route and any route below it? I'd like to send some data to our matomo (analytics) server when any user tries to grab an artifact from that route.


Solution

  • You can add middleware to process every request before routing. The drawback is that this would apply to all incoming requests, so you might need to recheck req.path first:

    class AnalyticsMiddleware:
        def process_request(self, req, resp):
            if req.path.startswith('/artifacts/'):
                print(f'Do something with {req.uri}...')
    
    
    application = falcon.App(middleware=[AnalyticsMiddleware(), ...])
    

    Alternatively, you could subclass StaticRoute and add it as a sink:

    import falcon
    import falcon.routing.static
    
    
    class MyStaticRoute(falcon.routing.static.StaticRoute):
        def __call__(self, req, resp):
            print(f'Do something with {req.uri}...')
    
            super().__call__(req, resp)
    
    
    # ...
    
    static = MyStaticRoute('/artifacts/', '/artifacts/')
    application.add_sink(static, '/artifacts/')
    

    However, the latter approach is not officially documented, so it could theoretically break in a future release without notice. Use this only if the middleware approach doesn't cut it for your use case for some reason.