Introduction of Superset

Superset is an open source Airbnb data visualization tool that can be accessed from Druid, Presto, Kylin and other databases or query engines. Provides rich visualization effects and supports TERabyte data volume query. Superset uses flask-AppBuilder as the back-end development framework, providing more flexible login, permission management, view and other customized functions, convenient integration of their own systems and secondary development. Superset solves the problem of cumbersome report development process and chaotic authority management.

Superset code structure

After downloading the source code from Github and opening the folder, the main code logic is in the superset path. If is through PIP install, through which superset can view the executable file path/usr/local/lib/python2.7 / site – packages/superset, the path of files and source code, as shown below.

  • superset/bin: in this directorysupersetThe file is the execution entry of the program
  • superset/connectorsSuperset data sources, table model and View
  • superset/migration: Stores superset DB schema upgrades and version changes
  • superset/models: Stores the database model of superset. The core logic of superset such as Slice and Dashboard can be found here.
  • superset/staticsuperset/templates: Superset front-end related template, control code
  • superset/views: Place all superset views, for Slice, Dashboard and SQL Lab related display, query, storage, download functions can be viewed here source code.
  • superset/__init__.pyFlask APP, Flask AppBuilder, SQLAlchemy, and Security Manager startup work, start superset view, database connection, Security management, etc.

By reading the code in superset/config.py, if you need to modify the configuration yourself, create a superset_config.py file and export the path to this file to the environment variable SUPERSET_CONFIG_PATH.

Login permission custom development

The Superset login module is a login authentication framework using F.A.B(Flask-AppBuilder for short). The login authentication modes are as follows:

AUTH_TYPE value description
0 / AUTH_OID Open ID authentication, such as gmail, Twitter and FB third-party apps, all fall into this category
1 / AUTH_DB The login information is saved to the database
2 / AUTH_LDAP Login authorization is performed through LDAP. Search for login authorizationThe LDAP protocol
3 / AUTH_REMOTE_USER Get validation from a Web Server, which can be a unified login system across the company
4 / AUTH_OAUTH Superset does not support this configuration method

For more details, see the F.A.B SecurityManager source code

Py, write the value of AUTH_TYPE to superset_config.py and tell Superset the path to the file. This allows you to replace the configuration in the Superset source code with the configuration you want to change. I write my own configuration information to ~/superset/conf/superset_config.py

export SUPERSET_CONFIG_PATH=~/superset/conf/superset_config.py
Copy the code

AUTH_REMOTE_USER development

In the daily production of the company, a new system is added. For the sake of unification and security, the login module generally uses the existing email addresses and passwords of employees as the login mode, that is, to obtain the authentication information of users by calling remote Server API(such as the API of email authentication). After the authentication, the user information will be saved to the DB. As long as the user’s session does not expire, the user can directly visit the website next time. The AUTH_REMOTE_USER method mentioned above.

1. The configuration

First configure CUSTOM_SECURITY_MANAGER in superset_config.py, replacing the SecurityManager used in superset. Next, write a MySecurityManager class that inherits the SecurityManager and overrides some views and methods to customize the login effects you want.

from flask_appbuilder.security.manager import AUTH_REMOTE_USER
from security.security_models import MySecurityManager

# using customize MY security manager
CUSTOM_SECURITY_MANAGER = MySecurityManager

# AUTHENTICATION CONFIG
Use remote server for authentication
AUTH_TYPE = AUTH_REMOTE_USER

# setup Public role name, no authentication needed
AUTH_ROLE_PUBLIC = 'Gamma'

# Will allow user self registration
AUTH_USER_REGISTRATION = True
Copy the code

2. Inheritance and rewrite

Flask-appbuilder the class that manages security is the SecurityManager, as described:

Responsible for authentication, registering security views, role and permission auto management. If you want to change anything just inherit and override, then pass your own security manager to AppBuilder.

It is responsible for authentication, registration of security-related views, and automated management of roles and permissions. So the idea of development is to keep clear of its inheritance relationship, to see which view, model or method can be rewritten, so as to achieve the desired effect.

  • A View can be understood simply as something you see in the interface, and a Model can be understood as a model associated with database interaction.
  • Here also involves object-oriented, inheritance, rewrite and other concepts, not clear students recommended reading

    , in the face of object-oriented is very good!

I focused on the auth_remote_user logic and overwrote the AuthRemoteUserView object and login methods. Specific view code:

# -*- coding: utf-8 -*-
import logging

from flask_appbuilder.const import LOGMSG_WAR_SEC_LOGIN_FAILED
from flask_appbuilder.security.sqla.manager import SecurityManager

from security.security_views import MyAuthRemoteUserView

logger = logging.getLogger(__name__)

Create MySecurityManager class by inheriting SecurityManager
class MySecurityManager(SecurityManager):
    logger.info("using customize my security manager")
    # Rewrite auth remote User view to achieve logon interface logic control
    # MyAuthRemoteUserView can be found in the Github link
    authremoteuserview = MyAuthRemoteUserView

    This method is done by looking at the SecurityManager source code
    # The auth_db and other methods of the operation logic, their own slightly modified
    def auth_user_remote_user(self, username):
        """ this is a overwrite method REMOTE_USER user Authentication :type self: User model """
        user = self.find_user(username=username)

        # User does not exist, create one if auto user registration.
        if user is None and self.auth_user_registration:
            user = self.add_user(
    # All we have is REMOTE_USER, so we set
    # the other fields to blank.
                username=username,
                first_name=username.split(The '@')[0],
                last_name=The '-',
                email=username,
                role=self.find_role(self.auth_user_registration_role))

        # If user does not exist on the DB and not auto user registration,
        # or user is inactive, go away.
        elif user is None or (not user.is_active()):
            logger.info(LOGMSG_WAR_SEC_LOGIN_FAILED.format(username))
            return None
            
        self.update_user_auth_stat(user)
        return user
Copy the code
  • MyAuthRemoteUserView: this implementation is also simple logic, I want to login via email and password, check whether the form submission data is accurate, overwrite login endpoint. The LoginForm used in this process is very useful, but I’d like to say more about it. It’s a widget from Flask that checks if the fields submitted by the user are correct (for example, if the email format is correct), sets the required item, and so on.

The above code demo I already submitted to githubhttps://github.com/yamyamyuo/superset-development, don’t know if I wrote to you help, if you have not the clear place, welcome to discuss ~ ~ in the comment area

conclusion

After a long delay, I finally sorted out the article. This period of time has been looking at superset source code, feel a lot of progress, reading source code is to improve the ability of the sharp weapon ~


If this article is helpful to you

Please don’t be stingy with your likes and followers

I will continue to summarize and update 🍻