Streamlit은 데이터사이언스/ML 프로젝트를 간단하게 배포할 수 있는 웹어플리케이션으로, 최근에 많은 관심을 받고 있습니다. 이번 포스트에서는 Streamlit의 간단한 소개와 기본 기능들을 훑어보겠습니다.
2020-03-13-intro-to-streamlit/streamlit_logo.png “Source: streamlit.io”)
Streamlit 이란?
Streamlit(스트림릿)은 2019년 하반기에 갑작스레 등장한(?) 파이썬 기반의 웹어플리케이션 툴이다. Medium 플랫폼에서 Streamlit이라는 키워드가 보이는 글이 추천되는 것을 자주 보게 되었는데, “데이터사이언스/머신러닝 프로젝트를 웹 어플리케이션에 배포"하는데 아주 편리한 툴이라는 설명이 눈길을 사로 잡았다.
 
나에게 있어 Streamlit나 Dash 같은 웹어플리케이션의 장점을 꼽자면;
웹개발을 몰라도 된다.
- 웹개발에 대해 아는 것이 전혀 없는 나 같은 사람도 페이지를 띄울 수 있다.
- 주로 사내용으로 이용되기 때문에 UI/UX적인 측면에서 뛰어나지 않아도 되기 때문에 일정 수준의 미적인 요소들이 기본적으로 적용되있는 점이 매우 편리하다.
- 간결하고 명확한 API 덕분에 다른 웹프레임워크와 비교해서 상대적으로 진입장벽이 낮다. 일정한 수준의 결과를 내기 위해 투자하는 시간이 매우 절약된다.
전달력이 매우 좋다.
- 웹어플리케이션은 사용자에게도 진입장벽이 낮다. 특히 interactive한 성향 덕분에, 슬라이드 포맷의 레포트나 자료보다 전달력과 만족도가 높은 것을 볼 수 있었다.
 
덕분에 Streamlit은 조직 내부적으로 탐색적 데이터 분석(EDA) 결과를 공유하거나, 간단한 ML 모델을 배포하고 테스트를 하는 용도에 부합하는 툴이라고 할 수 있다. Streamlit API에서 제공하는 기능들을 간단하게 훑어보자.
Streamlit 간단 맛 보기
설치
pip
를 통해 설치하기
$ pip install streamlit
 
실행하기
Streamlit은 8501
포트에 앱이 실행된다. 일단 지금 아무 것도 없는 상황에서는 우측 상단 버튼만 있는 페이지를 볼 수 있다.
$ streamlit run {your app}.py
You can now view your Streamlit app in your browser.
Local URL: http://localhost:8501
Network URL: http://{your_network}:8501
Streamlit 불러오기
Streamlit은 st
라는 alias로 불러온다.
# import Streamlit Library
import streamlit as st
소스에 변경이 생길 경우 경우 상단에 알림이 뜬다. Rerun
을 해주도록 하자.
 
텍스트 출력
Header와 Text
- Title, Header & Subheader
- Header와 Subheader를 다음과 같이 달 수 있다. 다만 Header의 경우 subheader 레벨까지만 가능하다. Title, Header, Subheader이 각각 Header, Subheader, Subsubheader인 것으로 인식하면 될 것 같다.
## Title
st.title('Streamlit Tutorial')
## Header/Subheader
st.header('This is header')
st.subheader('This is subheader')
## Text
st.text("Hello Streamlit! 이 글은 튜토리얼 입니다.")
 
Markdown
Streamlit도 Dash와 마찬가지로 Markdown을 지원한다.
## Markdown syntax
st.markdown("# This is a Markdown title")
st.markdown("## This is a Markdown header")
st.markdown("### This is a Markdown subheader")
st.markdown("- item 1\n"
" - item 1.1\n"
" - item 1.2\n"
"- item 2\n"
"- item 3")
st.markdown("1. item 1\n"
" 1. item 1.1\n"
" 2. item 1.2\n"
"2. item 2\n"
"3. item 3")
2020-03-13-intro-to-streamlit/4
 
Latex
Latex의 경우 백슬래시(\
)를 빈번히 사용되기 때문에, 일반 string 대신 raw string을 붙여주는 편이 좋다.
## Latex
st.latex(r"Y = \alpha + \beta X_i")
## Latex-inline
st.markdown(r"회귀분석에서 잔차식은 다음과 같습니다 $e_i = y_i - \hat{y}_i$")
 
메세지와 에러메세지, 예외처리 메세지
기본적으로 포맷된 메세지 박스 기능을 제공한다.
## Error/message text
st.success("Successful")
st.info("Information!")
st.warning("This is a warning")
st.error("This is an error!")
st.exception("NameError('Error name is not defined')")
   
데이터프레임과 테이블 출력.
데이터를 출력하는 방법에는 3가지 방법이 있다.
st.table
:- 단순히 입력 테이블 전체를 리턴한다.
st.dataframe
:- 적절히 10개의 행을 기준으로 스크롤을 통해 데이터를 관찰 할 수 있고 각 열마다 정렬도 가능하다. 각 테이블의 우측 상단의 확대 버튼을 통해 테이블을 더 크게 볼 수 있고,
st.write
:st.dataframe
과 똑같은 결과를 리턴한다.
## Load data
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
iris_df['target'] = iris['target']
iris_df['target'] = iris_df['target'].apply(lambda x: 'setosa' if x == 0 else ('versicolor' if x == 1 else 'virginica'))
## Return table/dataframe
# table
st.table(iris_df.head())
# dataframe
st.dataframe(iris_df)
st.write(iris_df)
   
이미지, 오디오, 비디오 파일 출력.
이미지, 영상, 오디오 파일을 열어서 재생할 수 있다.
st.image
: 파이썬 이미지 라이브러리와 함께 쓸 수 있다.st.video
:- 파일의 포맷을 지정해야 하며, 디폴트로는
video/mp4
가 설정되어 있다. start_time
변수를 통해 재생시작점을 조절할 수 있다.
- 파일의 포맷을 지정해야 하며, 디폴트로는
st.audio
:- 파일 포맷은
audio/wav
가 디폴트로 설정되어 있다. - 마찬가지로
start_time
변수를 통해 재생시작점을 조절할 수 있다.
- 파일 포맷은
##Show image
from PIL import Image
img = Image.open("files/example_cat.jpeg")
st.image(img, width=400, caption="Image example: Cat")
## Show videos
vid_file = open("files/example_vid_cat.mp4", "rb").read()
st.video(vid_file, start_time=2)
## Play audio file.
audio_file = open("files/loop_w_bass.mp3", "rb").read()
st.audio(audio_file, format='audio/mp3', start_time=10)
   
위젯
st.checkbox
- 체크박스
## Checkbox
if st.checkbox("Show/Hide"):
st.write("체크박스가 선택되었습니다.")
 
st.radio
- 라디오버튼
## Radio button
status = st.radio("Select status.", ("Active", "Inactive"))
if status == "Active":
st.success("활성화 되었습니다.")
else:
st.warning("비활성화 되었습니다.")
 
st.selectbox
- 드랍다운 선택
## Select Box
occupation = st.selectbox("직군을 선택하세요.",
["Backend Developer",
"Frontend Developer",
"ML Engineer",
"Data Engineer",
"Database Administrator",
"Data Scientist",
"Data Analyst",
"Security Engineer"])
st.write("당신의 직군은 ", occupation, " 입니다.")
 
st.multiselect
- 드랍다운 다중 선택
## MultiSelect
location = st.multiselect("선호하는 유투브 채널을 선택하세요.",
("운동", "IT기기", "브이로그",
"먹방", "반려동물", "맛집 리뷰"))
st.write(len(location), "가지를 선택했습니다.")
 
st.slider
- 슬라이더
## Slider
level = st.slider("레벨을 선택하세요.", 1, 5)
 
st.button
- 버튼
## Buttons
if st.button("About"):
st.text("Streamlit을 이용한 튜토리얼입니다.")
 
텍스트 입력
# Text Input
first_name = st.text_input("Enter Your First Name", "Type Here ...")
if st.button("Submit", key='first_name'):
result = first_name.title()
st.success(result)
# Text Area
message = st.text_area("메세지를 입력하세요.", "Type Here ...")
if st.button("Submit", key='message'):
result = message.title()
st.success(result)
 
날짜와 시간 입력
## Date Input
import datetime
today = st.date_input("날짜를 선택하세요.", datetime.datetime.now())
the_time = st.time_input("시간을 입력하세요.", datetime.time())
 
코드와 JSON 출력
with st.echo():
이하의 코드는 코드블럭으로 출력된다.
## Display Raw Code - one line
st.subheader("Display one-line code")
st.code("import numpy as np")
# Display Raw Code - snippet
st.subheader("Display code snippet")
with st.echo():
# 여기서부터 아래의 코드를 출력합니다.
import pandas as pd
df = pd.DataFrame()
## Display JSON
st.subheader("Display JSON")
st.json({'name' : '민수', 'gender':'male', 'Age': 29})
 
사이드바
st.sidebar
에서도 대부분의 위젯을 지원하므로, 다양하게 사이드바를 구성할 수 있다. (단, st.echo
, st.spinner
, st.write
제외)
## Sidebars
st.sidebar.header("사이드바 메뉴")
st.sidebar.selectbox("메뉴를 선택하세요.", ["데이터", "EDA", "코드"])
 
차트 그리기
Streamlit은 자체 내장된 기본적인 차트 외 matplotlib
, plot.ly
, altair
, vega_ilte
, bokeh
, deck_gl
, pydeck
, graph_viz
등 다양한 시각화 패키지를 지원한다.
(Streamlit은 EDA 용도로 많이 사용되는 만큼, 시각화 부분은 따로 다룰 계획이다.)
## Plotting
st.subheader("Matplotlib으로 차트 그리기")
iris_df[iris_df['target']=='virginica']['petal length (cm)'].hist()
st.pyplot()
   
마무리
Streamlit의 API를 훑어보면서, 전체적으로 많은 부분이 간결하고, 쉽다고 느껴졌다. Flask나 Django로 개발하는 개발자 입장에서 Streamlit 같은 프레임워크는 자유도가 제한된다고 느껴질 수도 있겠다. 하지만 등장한지 얼마 안 되는 만큼 커뮤니티 포럼에서는 활발한 토론과 기능 추가에 대한 요청이 이어지고 있는 중이다. Streamlit 개발자들이 적극적으로 피드백을 반영하는 모습을 보이고 있으므로, 앞으로의 발전이 더 기대된다.
이번 소개 글에 이어, 개인적으로 Streamlit으로 개발하면서 얻은 팁이나, 클라우드 또는 Heroku에 배포하는 과정, 데이터사이언스 프로젝트를 위해 웹어플리케이션을 구성하는 팁 등을 시리즈로 작성할 예정이다. 나처럼 웹개발은 모르지만 데이터분석 결과를 그럴 듯하게 구성하고 싶은 분들께 도움이 되었으면 한다.
 
코드