背景
作為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
