• 【Python】神器:Streamlit,仅使用Python开发一个运维管理后台(不需要编写html,js,css)


    背景

    作为SRE,我们有很多很多自动化的工具,大部分都是自动运行的,还有一部分是CLI,我们一直苦于没有一个自己的管理后台网站,受限于前端能力薄弱,开发出来的网页只能说凑活能用,但是不好用。

    现在我们有了Streamlit这个神奇,可以仅使用Python就开发一个简单的后台管理网站,同时也可以作为我们的内容输出渠道。

    简介

    官网:https://streamlit.io/

    本身streamlit是给做机器学习的人开发的,作为一个实时的数据展示和输出工具,但是自从我们发现它具有一些交互功能(Form表单,按钮,单选框,复选框)等功能后,我们借助这些特性,可以开发一个管理网站。

    官方Demo

    首先安装库:pip3 install streamlit

    运行自带的demo:命令行或者CMD输入:streamlit hello

    打开网页即可看到Demo

    我们的Demo:一个简易的运维管理网站后台

    先上截图:

    首页

     项目管理

     用户管理

     权限管理

     这里只是写了几个demo的功能,每家公司的业务需求不一样,需要根据自己公司实际情况,修改代码

    直接上源代码

    需要的解析都已经写在代码注释里了,这里就不展开说了。

    import streamlit as st
    import time
    # 设置网页标题,以及使用宽屏模式
    st.set_page_config(
        page_title="运维管理后台",
        layout="wide"
    
    )
    # 隐藏右边的菜单以及页脚
    hide_streamlit_style = """
    <style>
    #MainMenu {visibility: hidden;}
    footer {visibility: hidden;}
    </style>
    """
    st.markdown(hide_streamlit_style, unsafe_allow_html=True)
    # 左边导航栏
    sidebar = st.sidebar.radio(
        "导航栏",
        ("首页", "项目管理", "用户管理", "权限管理")
    )
    if sidebar == "项目管理":
        st.title("项目管理")
        # 项目选择框
        project_name = st.selectbox(
            "请选择项目",
            ["项目A", "项目B"]
        )
        if project_name:
            # 表单
            with st.form(project_name):
                project_info_1 = st.text_input("项目信息1", project_name)
                project_info_2 = st.text_input("项目信息2", project_name)
                project_info_3 = st.text_input("项目信息3", project_name)
                submitted = st.form_submit_button("提交")
                if submitted:
                    # 在这里添加真实的业务逻辑
                    # 这是一个进度条
                    bar = st.progress(0)
                    for i in range(100):
                        time.sleep(0.01)
                        bar.progress(i)
                    st.write("项目信息1:%s, 项目信息2:%s, 项目信息3:%s" % (project_info_1, project_info_2, project_info_3))
                    st.success("提交成功")
    
    
    elif sidebar == "用户管理":
        st.title("用户管理")
        # 将页面分为左半边和右半边
        left, right = st.beta_columns(2)
        # 左半边页面展示部分
        with left:
            st.header("查看、更新用户信息")
            user_name = st.selectbox(
                "请选择用户",
                ["郑立赛", "乔布斯", "王大拿"]
            )
            if user_name:
                with st.form(user_name):
                    phone_num = st.text_input("手机号", user_name)
                    role = st.multiselect(
                        "用户角色",
                        ["大神", "大拿"],
                        ["大神"]
                    )
                    user_group = st.multiselect(
                        "请选择用户组",
                        ["大神组", "大拿组"],
                        ["大神组"]
                    )
                    submitted = st.form_submit_button("提交")
                    if submitted:
                        # 这里添加真实的业务逻辑
                        st.write("用户名:%s, 手机号:%s, 用户角色:%s, 用户组:%s" % (user_name, phone_num, role, user_group))
                        st.success("提交成功")
        # 右半边页面展示部分
        with right:
            st.header("添加、删除用户")
            user_action = st.selectbox(
                "请选择操作",
                ["添加用户", "删除用户"]
            )
            if user_action:
                with st.form(user_action):
                    if user_action == "添加用户":
                        phone_num = st.text_input("手机号", user_name)
                        role = st.multiselect(
                            "用户角色",
                            ["大神", "大拿"]
                        )
                        user_group = st.multiselect(
                            "请选择用户组",
                            ["大神组", "大拿组"]
                        )
                        submitted = st.form_submit_button("提交")
                        if submitted:
                            # 请在这里添加真实业务逻辑,或者单独写一个业务逻辑函数
                            st.write("user_name:%s, phone_num:%s, role:%s, user_group:%s" % (user_name, phone_num, role, user_group))
                            st.success("提交成功")
                    else:
                        user_group = st.multiselect(
                            "请选择要删除的用户",
                            ["郑立赛", "乔布斯", "王大拿"]
                        )
                        submitted = st.form_submit_button("提交")
                        if submitted:
                            # 请在这里添加真实业务逻辑,或者单独写一个业务逻辑函数
                            st.write("user_name:%s, phone_num:%s, role:%s, user_group:%s" % (user_name, phone_num, role, user_group))
                            st.success("提交成功")
    elif sidebar == "权限管理":
        st.title("权限管理")
        with st.form("auth"):
            user = st.multiselect(
                "选择用户",
                ["郑立赛", "乔布斯", "王大拿"]
            )
            role = st.multiselect(
                "选择用户角色",
                ["大神", "大拿"]
            )
            user_group = st.multiselect(
                "请选择用户组",
                ["大神组", "大拿组"]
            )
            submitted = st.form_submit_button("提交")
            if submitted:
                # 请在这里添加真实业务逻辑,或者单独写一个业务逻辑函数
                st.write(
                    "用户:%s, 角色:%s, 用户组:%s" % (user, role, user_group))
                st.success("提交成功")
    else:
        st.title("运维管理后台")
        st.write("欢迎使用运维管理后台")

    如果是windows直接在CMD输入,假设你把上面的代码保存为demo.py

    streamlit run demo.py

    打开浏览器即可看到上面的截图

    安全性

    Web类型程序一定避不开安全性的问题,Streamlit不支持安全认证

    即不提供用户名密码等基本的认证方式,查了官方的论坛,目前没有好的办法,官方后续有计划做,但是也是在For Team版本里面,开源版是不提供的。

    解决办法:在程序前面加上一个nginx,利用nginx的basic_auth做认证,然后将请求转发给streamlit。这应该是最简单的办法了。

     附上nginx的配置,有几个选项必须加,要不然会报ws错误

    server {
        listen       8501;
        server_name 0.0.0.0;
        location / {
           proxy_pass http://admin-web:8501;
           auth_basic "Please input password";
           auth_basic_user_file /etc/nginx/conf.d/password.db;
           proxy_set_header    Host             $host;
           proxy_set_header    X-Real-IP        $remote_addr;
           proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
           proxy_set_header   X-Forwarded-Proto $scheme;
           proxy_buffering    off;
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";
           proxy_read_timeout 86400;
           proxy_redirect      default;
          }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }

    附录

    开发者文档

    https://docs.streamlit.io/en/stable/api.html

    原创作者:郑立赛


    邮箱:zhenglisai@qq.com


    欢迎关注我们的公众号获取最新文章:运维自动化开发


    公众号
    公众号
  • 相关阅读:
    在宝塔中升级mysql版本
    测试winform程序到树莓派运行
    winserver2012远程桌面进入只有CMD窗口,无桌面解决方法
    一七年春末
    Linux 上通过rpm安装mysql
    Linux 上关于iptables
    Linux环境下安装JDK
    Linux上安装tomcat
    Linux 下安装redis
    Map集合按照value和key进行排序
  • 原文地址:https://www.cnblogs.com/zhenglisai/p/14844488.html
Copyright © 2020-2023  润新知