美文网首页
Superset 源码分析

Superset 源码分析

作者: 程序员赤小豆_gzh同名 | 来源:发表于2022-05-19 09:37 被阅读0次

    我最初接触 Superset 是在2018年的时候,那时候 Superset 的版本才0.26,当时在公司内部积累了一些best practice,遇到了bug还顺便贡献了代码,算是对这个项目有比较深入的了解。

    这些年看着 Superset 社区越来越成功,国内也有很多公司和开发者需要围绕着 Superset 做一些公司生态内的二次开发,而我现在回过头来看这个项目,对整个项目有了更深刻的理解,接下来,我会输出一系列的文章,讲解如何玩转 Superset 的二次开发。

    刚开始接手一个新的项目,大致了解每个目录下的代码大概是做什么的非常重要,你会知道代码去哪里修改,做到心中有数才能更加游刃有余。

    Superset 介绍

    Superset 是一个款非常优秀的开源项目,作为BI工具,它的开发语言大众化,云原生的架构能够满足企业各种各样的定制化需求,从 web server,后端数据库,消息队列,缓存层都可以根据业务需要进行配置更改。支持各种各样的大数据组件作为查询引擎,如 Presto,Hive,Spark,Clickhouse,Amazon Athena,Redshift 等等。

    而丰富的数据可视化解决方案才是 Superset 最大的亮点,它还支持自定义plugin的方式去增加自己想要的图表。


    gallery.jpeg

    代码目录介绍

    Superset branch 1.5为例,根目录下通常会存放一些代码样式规范,git相关的配置,docker文件,python setup等脚本。还有做开源贡献必须仔细阅读的 code of conductcontributing

    这些文件中需要着重阅读的是 contributing,里面有很详细的步骤告诉你如何开始贡献代码,如何把前端本地开发环境搭建起来,前后端如何协调,怎么修改代码的缩进等等。

    根目录下还有如图所示的各个文件夹


    Screen Shot 2022-05-17 at 23.05.22.png

    挑几个比较重要的来说说,

    • superset:后端代码主要放在这个文件夹中
    • superset-frontend: 前端代码的入口
    • superset-websocket:Nodejs websocket相关
    • docker:docker文件,docker的启动脚本等等
    • helm/superset:helm charts 的配置文件,不太了解 helm 的可以看看官方介绍
    • requirements:python环境下,需要安装的一些第三方包及其版本
    • .github:存放github CI/CD 相关的 workflow 配置,可略过
    • RELEASING:存放版本release note

    我个人多年来阅读项目源码的习惯是先抓住重点,细枝末节的东西可以以后慢慢一点点补充。一上来不要一下子输入太多,细节有时候会把人带跑。

    以上就是比较重要的一些模块,作为后端开发(前端我无能为力 🙂 ),首先可以看看 superset 文件夹下的代码。

    看源码的过程建议结合前端的UI交互、功能来看对应的后端代码。首先应该自己去上手用一用这款产品,连接一些数据库,建几张表,最后建几个dashboard玩一玩,数据可视化方面的一些基本知识也需要顺便补一补,只有真正成为一个产品的用户,才会变成一个有心人,发现很多别人看不到的细节,才有可能做到深入。

    后端代码入口

    后端是如何启动起来的,通过看 Dockerfile 的 entrypoint 或者 CMD

    Screen Shot 2022-05-18 at 21.30.27.png

    这段代码可以发现,启动后端服务应该是在 ./docker/docker-ci.sh 这个文件里执行的,顺着这个文件找下去,会发现最终执行的是一个叫 ./docker/run-server.sh 的脚本。

    Screen Shot 2022-05-18 at 21.36.37.png

    启动 Superset 后端server的一个命令就是 gunicorn 这一句。gunicorn 要启动的这个 ${FLASK_APP} 变量通过代码搜索可以发现就是 FLASK_APP="superset.app:create_app()"

    它所对应的方法就是 superset/app.py 文件中的 create_app() 方法。

    
    def create_app() -> Flask:  
        app = SupersetApp(__name__)  
      
        try:  
            # Allow user to override our config completely  
            config_module = os.environ.get("SUPERSET_CONFIG", "superset.config")  
            app.config.from_object(config_module)  
      
            app_initializer = app.config.get("APP_INITIALIZER", SupersetAppInitializer)(app)  
            app_initializer.init_app()  
      
            return app  
      
        # Make sure that bootstrap errors ALWAYS get logged  
        except Exception as ex:  
            logger.exception("Failed to create app")  
            raise ex  
      
      
    class SupersetApp(Flask):  
        pass
    

    这段创建应用的代码做了几件事:

    • 加载 superset/config.py,也就是说将配置文件加载进来,看过官网的介绍应该也知道默认的配置文件就是这个。
    • 调用 app_initializer 进行一系列的初始化,配置文件里没有的话,默认就调用 SupersetAppInitializer.init_app() 方法
      • 这个 init_app() 里面又处理了很多初始化的工作,比如 setup database, configure celery, config cache 等等
      • 最重要的还有一个 init_views() 方法。

    代码:https://github.com/apache/superset/blob/1.5/superset/initialization/init.py

    def init_app(self) -> None:  
        """  
        Main entry point which will delegate to other methods in    order to fully init the app    """    self.pre_init()  
        self.check_secret_key()  
        # Configuration of logging must be done first to apply the formatter properly  
        self.configure_logging()  
        # Configuration of feature_flags must be done first to allow init features  
        # conditionally    self.configure_feature_flags()  
        self.configure_db_encrypt()  
        self.setup_db()  
        self.configure_celery()  
        self.enable_profiling()  
        self.setup_event_logger()  
        self.setup_bundle_manifest()  
        self.register_blueprints()  
        self.configure_wtf()  
        self.configure_middlewares()  
        self.configure_cache()  
      
        with self.superset_app.app_context():  
            self.init_app_in_ctx()  
      
        self.post_init()
    

    init_views()

    这个方法很重要,因为 Superset 后端是用 Flask + FlaskAppBuilder 这两个框架去写的,因此需要初始化一些 FlaskAppBuilder 的 views,API,links 等等。

    到此为止,整个后端代码的入口介绍就差不多了,后端核心的代码放在 superset 文件夹中,通过文件夹的命名,也能够看到大致的端倪。

    这个看代码入口的方法套到其他的开源项目也是适用的哦,这是一个屡试不爽的好方法。

    如何上手代码

    想要更好地理解 Superset 的代码,你还需要做一些额外的准备:

    • 熟悉 Python 语言,了解一些常见的语法糖,语言的特性。这样看到报错信息可以帮助更好地定位问题,而不是一头雾水。
    • 熟悉 Flask 和 FlaskAppBuilder 框架,因为 Superset 的后端 API,views,models 的理解都需要在了解这两个框架的基础上。
    • 熟悉一些常见的 python package,如 SQLAlchemy,marshmallow,pandas,celery等。

    最后

    如果你对Superset的代码或者二次开发有问题,可以找我咨询,我组建了免费的社区,大家都很乐于分享。如有需要,看我个人简介来联系我,注明来意~

    相关文章

      网友评论

          本文标题:Superset 源码分析

          本文链接:https://www.haomeiwen.com/subject/uyttprtx.html