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 자료를 표현할 수 있음
- 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
카일스쿨 유튜브 채널을 만들었습니다. 데이터 분석, 커리어에 대한 내용을 공유드릴 예정입니다.
PM을 위한 데이터 리터러시 강의를 만들었습니다. 문제 정의, 지표, 실험 설계, 문화 만들기, 로그 설계, 회고 등을 담은 강의입니다
이 글이 도움이 되셨거나 의견이 있으시면 댓글 남겨주셔요.