1

I created a flask addon using "flask fab create-addon".

I would like to change the template appbuilder/general/security/login_oauth.html so I have:

templates
  appbuilder
     general
       security
          login_oauth.html

But when I load the host application my version of login_oauth.html is not loaded. I tried registering a blueprint as in this post with the following code:

from flask import Blueprint
bp = Blueprint('fab_addon_fslogin', __name__, template_folder='templates')

class MyAddOnManager(BaseManager):
    def __init__(self, appbuilder):
        """
        Use the constructor to setup any config keys specific for your app.
        """
        super(MyAddOnManager, self).__init__(appbuilder)
        self.appbuilder.get_app.config.setdefault("MYADDON_KEY", "SOME VALUE")
        self.appbuilder.register_blueprint(bp)

    def register_views(self):
        """
        This method is called by AppBuilder when initializing, use it to add you views
        """
        pass

    def pre_process(self):
        pass

    def post_process(self):
        pass

But register_blueprint(bp) return:

  File "/home/cquiros/data/projects2017/personal/software/superset/addons/fab_addon_fslogin/fab_addon_fslogin/manager.py", line 24, in __init__
    self.appbuilder.register_blueprint(bp)
  File "/home/cquiros/data/projects2017/personal/software/superset/env_superset/lib/python3.8/site-packages/Flask_AppBuilder-3.3.0-py3.8.egg/flask_appbuilder/base.py", line 643, in register_blueprint
    baseview.create_blueprint(
AttributeError: 'Blueprint' object has no attribute 'create_blueprint'

Not much information out there on how to do this. Any clue is appreciated

QLands
  • 2,424
  • 5
  • 30
  • 50

1 Answers1

1

If you want to customize login_oauth.html, The easiest way is that adding it into your app directly not addon. That means the login_oauth.html should be put in this path.

YourApp
- app
-- templates
--- appbuilder
---- general
----- security
------ login_oauth.html

For solution of addons, the function self.appbuilder.register_blueprint is for views not for the object which Blueprint fuction returns. It should be replaced with

self.appbuilder.get_app.register_blueprint(Blueprint('fab_addon_fslogin', __name__, template_folder='templates')) 

Keep the blueprint registration and try to rename the login_oauth.html to login_oauth_xxxx.html which at

{your python packages root path}\site-packages\flask_appbuilder\templates\appbuilder\general\security

That will let the template be overwrote as you need. I guess that the template searching order of app-builder package is greater than addons. The searching order of blueprints depend on order of registrations

Finally, I have found a trick without renaming the file, you could try the following

class MyAddOnManager(BaseManager):


    def __init__(self, appbuilder):
        """
             Use the constructor to setup any config keys specific for your app. 
        """
        super(MyAddOnManager, self).__init__(appbuilder)
        self.appbuilder.get_app.config.setdefault('MYADDON_KEY', 'SOME VALUE')
        self.static_bp = Blueprint('fab_addon_fslogin', __name__, template_folder='templates')

    def register_views(self):
        """
            This method is called by AppBuilder when initializing, use it to add you views
        """
        pass

    def pre_process(self):
        self.appbuilder.get_app.register_blueprint(self.static_bp)
        blueprint_order = self.appbuilder.get_app._blueprint_order
        # move blueprint order of addon to top
        blueprint_order.insert(0, blueprint_order.pop())

    def post_process(self):
        pass

Reference: flask-appbuilder Customizing

Epic Chen
  • 1,282
  • 12
  • 17
  • Hi Epic Chen. My guess with addons is that they can extend/modify a FAB application in a modular so you don't need to modify the FAB code. In my case, the FAB application (Apache SuperSet) does not extend/modify login_oauth.html but I need my addon to modify it. I tried your code: self.appbuilder.get_app.register_blueprint(Blueprint('fab_addon_fslogin', __name__, template_folder='templates')) but when SuperSet loads login_oauth.html it does not load the modifications made by the addon. – QLands Jun 02 '21 at 15:58
  • Basically, the order should be: 1) the version of flask_appbuilder, 2) the version of the FAB App (if any), 3) the version of the addon. I know that the easy way would be to modify the FAB App but in my case, I cant modify SuperSet because such change only apply to me. – QLands Jun 02 '21 at 16:04
  • I have done some surveys, as I mentioned that template searching order of app-builder package is greater than addons, so the login_laugh.html will not be overwrote without renaming it, I also have checked codes in the app-builder and the blueprint of flask, I don't found a normal way without modifying codes of modules. – Epic Chen Jun 02 '21 at 16:20
  • Your guess may be intuitive, but consider about security reasons, if add-on could overwrite template in main app, that may be a risk. Moreover, since dev and release environment of each apps may be isolated, I think it is fine to modify files of modules if it can not do want you want. – Epic Chen Jun 02 '21 at 16:21
  • If the template searching order of app-builder package is greater than addons then it is not possible to do it. Do you know the file and line where I can see such order? It does not make any sense and it seems like a design flaw. On your comment about security: it is not a risk since you need to indicate which addons to load using ADDON_MANAGERS = [] in config.py . If I construct the add-ons then there is no risk on use them. – QLands Jun 02 '21 at 16:48
  • I have found a way to change the order and updated the answer, you could check it. By the way, searching order of blueprint depends on order of registration. I mention it is a risk because of you need to check what templates are overwrote by addons if they are from third-party. – Epic Chen Jun 02 '21 at 17:09
  • Well, Epi Chen. That worked as expected. Thank you very much!!! – QLands Jun 02 '21 at 17:28
  • Glad to be of help. I have updated the answer again for the changing order logic. – Epic Chen Jun 02 '21 at 17:37