【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