Python Streamlit 사용법 - 프로토타입 만들기
- Python Streamlit에 대한 글입니다
- python streamlit tutorial, python streamlit dashboard, python streamlit install, python streamlit vs dash, python dashboard, python streamlit example
- 목차
- 회사 또는 프로젝트하며 생길 수 있는 일
- 대표적인 프로토타이핑 도구
- Streamlit 소개
- Streamlit 맛보기
- Streamlit API 소개
- Streamlit Component
- Streamlit 배포하기
회사 또는 프로젝트하며 생길 수 있는 일
- 1) 머신러닝 모델 학습
- 2) 머신러닝 모델 배포
- 3) 머신러닝 모델이 잘 동작하는지 Jupyter Notebook 등에서 확인
- 4) 모델을 만든 당사자는 노트북 파일을 기반으로 여러 동작을 할 수 있음
- 그러나 자신만 디버깅하는게 아닌 다른 분들에게 공유하고 싶은 경우엔 이슈가 존재
- 개발 환경 셋팅, 프리트레인 파일 다운, 노트북 실행 등을 해야 함
- 개발을 어느정도 아는 사람이라면 괜찮지만 회사에서 기획자 또는 운영팀분들에게 보여드리기엔 굳이?라는 생각이 듬
- 그냥 웹 형태에서 간단하게 실행해볼 수 있는 도구들을 만들기 시작
- 그러나 자신만 디버깅하는게 아닌 다른 분들에게 공유하고 싶은 경우엔 이슈가 존재
- 5) 최초엔 Flask + 부트스트랩 등을 사용해 만드는 분들도 있지만 웹 개발에 신경을 쓰는 시간이 많아짐 => 다른 방법을 찾음
- 6) R의 Shiny 같이 인터랙티브한 것을 찾다가 자바스크립트 D3 등을 시도
- 허나 만만치 않구나..를 깨닫고 다시 회귀
- 이런 경우 Python을 사용해서 빠르게 프로토타입을 만들고 싶은 욕구가 생김
- 프로토타입을 하기 위해 찾아보면 대략 대시보드 도구를 찾아보게 됨
- 꼭 머신러닝 모델이 아니여도, 대시보드를 만드는 것도 비슷함
- 주로 필요한 부분은
- 시각화(Visualization)
- 인터랙티브(Interactive)
- 서빙(Serving)
대표적인 프로토타이핑 도구
- 프로토타입은 다양한 방법으로 만들 수 있고, 대표적으로 도구는 다음과 같음. 개인적으로 프로토타이핑 도구는 대시보드 도구랑 맥락이 비슷하다고 생각
- 1) Jupyter Notebook
- 2) Flask : 백엔드를 직접 구성 + 프론트엔드 작업도 진행
- 3) Dash : 제일 기능이 풍부한 Python 대시보드 라이브러리
- 4) Voila : Jupyter Notebook을 바로 시각화 가능
- 5) Streamlit : 이 글에서 소개할 도구
- 개인적으로 모두 사용해보고 느낀 점 정리
- 개인 의견이라 주관적인 의견입니다. 꼭 직접 사용해보시길 추천드려요
Streamlit 소개
- 공식 문서 : The fastest way to build and share data apps
- 가장 빠르게 데이터 어플리케이션을 만들 수 있는 방법
- 앱을 만드는 미니멀한 프레임워크
- 21년 2월 기준 Github Star 13K
- 장점
- 간단하게 파이썬 코드로 앱을 빌드할 수 있음
- 인터랙티브한 기능 제공(백엔드 개발이나 HTTP 요청 구현할 필요 없음)
- 다양한 예시 제공
- 커뮤니티에서 개발한 Component도 존재
- Streamlit에서 배포할 수 있는 시스템 제공(단, 신청 필요)
- 화면을 녹화할 수 있는 Record 기능도 제공
- app을 빌드한 후, 오른쪽 ☰ 버튼을 클릭하면 Record a screencast를 확인할 수 있음
- Awesome Streamlit Github에 참고할 수 있는 자료가 매우 많음
Streamlit 맛보기
설치
pip3 install streamlit
파이썬 파일 작성(공식 홈페이지 샘플 코드 - sample_code.py로 저장)
import streamlit as st import pandas as pd import numpy as np st.title('Uber pickups in NYC') DATE_COLUMN = 'date/time' DATA_URL = ('https://s3-us-west-2.amazonaws.com/' 'streamlit-demo-data/uber-raw-data-sep14.csv.gz') @st.cache def load_data(nrows): data = pd.read_csv(DATA_URL, nrows=nrows) lowercase = lambda x: str(x).lower() data.rename(lowercase, axis='columns', inplace=True) data[DATE_COLUMN] = pd.to_datetime(data[DATE_COLUMN]) return data data_load_state = st.text('Loading data...') data = load_data(10000) data_load_state.text("Done! (using st.cache)") if st.checkbox('Show raw data'): st.subheader('Raw data') st.write(data) st.subheader('Number of pickups by hour') hist_values = np.histogram(data[DATE_COLUMN].dt.hour, bins=24, range=(0,24))[0] st.bar_chart(hist_values) hour_to_filter = st.slider('hour', 0, 23, 17) filtered_data = data[data[DATE_COLUMN].dt.hour == hour_to_filter] st.subheader('Map of all pickups at %s:00' % hour_to_filter) st.map(filtered_data)
Streamlit 실행
streamlit run sample_code.py
http://localhost:8501/
로 접속 가능
- Show raw data를 클릭시 데이터프레임이 출력되고, hour 슬라이더를 조절하면 지도의 데이터가 변하는 것을 볼 수 있음
Streamlit API 소개
- 제목 설정하기
- 캐싱하기
- 위젯 만들기
- 버튼 만들기
- 체크 박스 만들기
- 라디오 버튼 만들기
- 선택 박스 만들기
- 다중 선택 박스 만들기
- 슬라이더 만들기
- 데이터 입력
- 데이터 출력
- 차트 출력
- Progress, Status 메세지
- 각종 컨텐츠 출력
- 사이드바, 레이아웃
제목 설정하기
타이틀
st.title("Title")
헤더
st.header("Header")
서브헤더
st.subheader("subheader")
텍스트 작성하기
st.write("Write Something")
캐싱하기
- 특정 버튼을 누를 때 데이터를 불러오고 싶은 경우가 존재
- 데이터가 많은 경우에 반복적으로 데이터를 불러오는 것보다, 중간에 캐싱을 하면 속도도 개선되고 좋은 UX 경험을 가질 수 있음
- Streamlit에선
st.cache
데코레이터를 사용하면 캐싱을 진행- 함수 이름 확인
- 함수를 구성하는 코드 확인
- 함수 호출시 사용한 매개변수
- 위 3개를 확인하며 로컬에 저장해두고(=캐싱) 다시 호출시 캐싱을 사용할 수 있다면 그대로 사용함
캐싱 관련은 공식 문서를 확인하면 더 자세한 내용을 확인할 수 있음
@st.cache def load_data(): # data load return data
위젯 만들기
버튼 만들기
if st.button("click button"): st.write("Data Loading..") # 데이터 로딩 함수는 여기에!
체크 박스 만들기
checkbox_btn = st.checkbox('Checktbox Button') if checkbox_btn: st.write('Great!')
만약 Default로 체크하고 싶다면
st.checkbox(value=True)
를 주면 됨checkbox_btn2 = st.checkbox('Checktbox Button2', value=True) if checkbox_btn2: st.write('Button2')
- 라디오 버튼 만들기
- 첫 요소가 default로 선택됨
selected_item = st.radio("Radio Part", ("A", "B", "C")) if selected_item == "A": st.write("A!!") elif selected_item == "B": st.write("B!") elif selected_item == "C": st.write("C!")
선택 박스 만들기
option = st.selectbox('Please select in selectbox!', ('kyle', 'seongyun', 'zzsza')) st.write('You selected:', option)
- 다중 선택 박스 만들기
- 결과가 배열로 나옴
- 100개 이상될 경우 유저 경험이 떨어질 수 있음
multi_select = st.multiselect('Please select somethings in multi selectbox!', ['A', 'B', 'C', 'D']) st.write('You selected:', multi_select)
슬라이더 만들기
values = st.slider('Select a range of values', 0.0, 100.0, (25.0, 75.0)) st.write('Values:', values)
데이터 입력
텍스트 데이터를 입력하고 싶은 경우
st.text_input(value)
텍스트 데이터를 암호로 사용하고 싶은 경우엔 type=”password” 인자를 추가
st.text_input(label, value, type="password")
숫자 데이터를 입력하고 싶은 경우
st.number_input(label, value)
여러 줄의 텍스트 데이터를 입력하고 싶은 경우
st.text_area(label, value)
날짜를 입력하고 싶은 경우
st.date_input(label, value)
시간을 입력하고 싶은 경우
st.time_input(label, value)
데이터 출력
st.dataframe
을 사용하면 인터랙티브한 테이블을 볼 수 있고,st.table
을 사용하면 static한 테이블을 볼 수 있음df.style.highlight_max(axis=0)
를 사용하면 최대값이 하이라이트를 줄 수 있음(이 기능은 pandas 0.24에선 오류가 발생하고 1점대에서 실행됨)st.write("st.dataframe api") df = pd.DataFrame(np.random.randn(5, 2), columns=('col %d' % i for i in range(2))) st.dataframe(df.style.highlight_max(axis=0)) st.write("st.table api") st.table(df)
차트 출력
- 현재 Matplotlib, Altair, Deck.gl, Plot.ly, Bokeh, Graphviz 등을 사용해 시각화함
- 대부분 df를 넣으면 바로 시각화할 수 있음
st.line_chart
st.area_chart
st.bar_chart
st.pyplot
st.altair_chart
st.vega_lite_chart
st.plotly_chart
st.bokeh_chart
st.pydeck_chart
st.graphviz_chart
st.map
Progress, Status 메세지
성공 메세지
st.success("Success")
에러 메세지
st.error("Error")
경고 메세지
st.warning("Warning")
정보 메세지
st.info("Info")
코드가 실행되는 도중에 출력할 메세지
import time with st.spinner('Wait for it...'): time.sleep(5) st.success('Done!')
각종 컨텐츠 출력
이미지 출력
from PIL import Image image = Image.open('img.jpg') st.image(image)
비디오 출력
video_file = open('video.mp4', 'rb') video_bytes = video_file.read() st.video(video_bytes)
오디오 출력
audio_file = open('audio.ogg', 'rb') audio_bytes = audio_file.read() st.audio(audio_bytes, format='audio/ogg')
사이드바, 레이아웃
- 웹페이지 왼쪽에 사이드바를 추가하고 싶은 경우
add_selectbox = st.sidebar.selectbox("왼쪽 사이드바 Select Box", ("A", "B", "C"))
- 레이아웃
st.beta_columns
를 사용해 나눌 수 있음
col1, col2, col3 = st.beta_columns(3)
with col1:
st.header("A cat")
st.image("https://static.streamlit.io/examples/cat.jpg", use_column_width=True)
with col2:
st.header("Button")
if st.button("Button!!"):
st.write("Yes")
with col3:
st.header("Chart Data")
chart_data = pd.DataFrame(np.random.randn(50, 3), columns=["a", "b", "c"])
st.bar_chart(chart_data)
- API Cheat Sheet
- API Cheat Sheet에서 치트 시트를 확인할 수 있음
Streamlit Component
- Streamlit Component 홈페이지에 많은 Components가 소개됨. 여러 Components 중 인상 깊은 것들만 추리면 다음과 같음
- streamlit-agraph
- Graph 자료를 표현할 수 있음
- Streamlit Vega-Lite
- Vega Lite를 사용해 인터랙티브하게 데이터를 탐색할 수 있음
- Streamlit - Drawable Canvas
- Canvas에서 그림을 그릴 수 있는 기능
- Streamlit Lottie
- Lottie 애니메이션을 사용할 수 있음
- Streamlit-Cropper
- 이미지를 Crop할 수 있음
Streamlit 앱
- demo-uber-nyc-pickups의 코드를 사용
- 비밀번호 입력 기능
- 비밀번호를 입력하는 기능을 만들어 앱의 보안을 강화하려고 함
- 최초엔 간단하게 password를 입력 받고, 그 password가 맞으면 기존의 함수를 실행하는 방식으로 구현함
- 이 방식으로 구현하니 위젯에서 데이터가 갱신될 때, 다시 password 입력 창으로 이동하는 상황을 발견
- 이슈를 찾아보니 Feature request: confirm_button를 찾았고, gist에 참고할 수 있는 코드를 올려주셨음
- 완성된 코드는 Github Repository에서 확인할 수 있음
Streamlit 배포하기
- 간단히 사용하기 위해선 Heroku를 사용해도 좋고, Streamlit 자체에서 제공하는 기능을 사용해도 좋음. 여기선 Heroku를 사용함
- Heroku 로그인
- 홈페이지에서 로그인(계정이 없다면 가입 후 로그인)
- Create New App
- Create New App을 클릭해 앱 생성
- App name은 헤로쿠 내에서 Unique해야 하며, [Appname].herokuapp.com/ 으로 URL이 생성됨
- 저는
zzsza-streamlit-deploy
로 생성
- Github Repository 생성 및 코드 업로드
- 이 때, setup.sh와 Procfile, requirements.txt가 필요함
setup.sh
mkdir -p ~/.streamlit/ echo "\ [server]\n\ headless = true\n\ enableCORS=false\n\ port = $PORT\n\ " > ~/.streamlit/config.toml
Procfile
web: sh setup.sh && streamlit run app.py
- requirements.txt는 pipreqs나 virtualenv에 있는 라이브러리 정보를 저장해서 업로드
- Heroku에서 Github 연결
- Deployment method에 Github 선택 - Connect to Github에서 인증한 후, Repo 연결
- Settings - Config Vars - Reveal Config Vars를 클릭한 후 Key : STREAMLIT_PASSWORD, Value: 원하는 비밀번호 입력
- 이제 Heroku App에 접근하면(https://[AppName].herokuapp.com/ 같은 URL이 생성됨) Streamlit 페이지가 보임
- 암호를 입력하면 그래프가 보이고, 암호가 틀릴 경우 보이지 않음
Reference
카일스쿨 유튜브 채널을 만들었습니다. 데이터 사이언스, 성장, 리더십, BigQuery 등을 이야기할 예정이니, 관심 있으시면 구독 부탁드립니다 :)
PM을 위한 데이터 리터러시 강의를 만들었습니다. 문제 정의, 지표, 실험 설계, 문화 만들기, 로그 설계, 회고 등을 담은 강의입니다
이 글이 도움이 되셨거나 다양한 의견이 있다면 댓글 부탁드립니다 :)