pythonflaskckan

How to make customized middleware in CKAN


I've met a scenario which I have to override a common middleware in CKAN. And in CKAN default plugins/interface.py:

class IMiddleware(Interface):
    u'''Hook into CKAN middleware stack
    Note that methods on this interface will be called two times,
    one for the Pylons stack and one for the Flask stack (eventually
    there will be only the Flask stack).
    '''
    def make_middleware(self, app, config):
        u'''Return an app configured with this middleware
        When called on the Flask stack, this method will get the actual Flask
        app so plugins wanting to install Flask extensions can do it like
        this::
            import ckan.plugins as p
            from flask_mail import Mail
            class MyPlugin(p.SingletonPlugin):
                p.implements(p.I18nMiddleware)
                def make_middleware(app, config):
                    mail = Mail(app)
                    return app
        '''
        return app

It shows that I have to define "MyMiddleWare" class under a plugin that I want to implement in an extension. However, as it shows in the example, the actual middleware Mail is imported from a different class. I want to override TrackingMiddleware especially the __call__(self, environ, start_response) method, which environ and start_response are passed in when make_pylons_stack are invoked during the configuration phase. If I want to override TrackingMiddleware Should I create another config/middleware/myTrackingMiddleware.py under ckanext-myext/ and then in plugin.py I implement the following?:

from myTrackingMiddleware import MyTrackingMiddleware

class MyPlugin(plugins.SingletonPlugin):
    plugins.implements(plugins.IMiddleware, inherit=True)

    def make_middleware(self, app, config):
        tracking = MytrackingMiddleware(app, config)
        return app

Update:

I tried to make the myTrackingMiddleware in an hierarchy and imported it in plugin.py, but I didn't received any request to '/_tracking' in myTrackingMiddleware.


Solution

  • I have implemented a set of process, and it works for myself. Basically, I kept what I have done as what I have mentioned in my own question. Then, if your middleware has some conflict with CKAN default Middleware, you probably have to completely disable the default one. I discussed with some major contributors of CKAN here: https://github.com/ckan/ckan/issues/4451. After I disabled CKAN ckan.tracking_enabled in dev.ini, I have the flexibility to get values from environ and handle tracking with my customized logic.