프로토타이핑- 웹 서비스 형태(Streamlit)

-·2022년 1월 11일
0

강의정리 - MLOps

목록 보기
5/18

이글은 네이버 부스트캠프 ai tech 변성윤 강사님의 product serving강의를 정리한 글입니다.
문제 혹은 틀린점이 있다면 말씀해주세요. 빠른 시일내에 수정하겠습니다 :)

웹프로그래밍에 대한 지식이 없어도 웹서비스 형태로 프로토타이핑을 할 수 있는
Streamlit이라는 프레임워크에 대해서 학습해보자 !

프로토타입부터 점진적으로 개선하기

목차

  • 웹서비스 형태 - Streamlit
    -- 웹서비스를 만드는 과정
    -- Streamlit의 대안
    -- Streamlit Component
    -- Session State
    -- @st.cache

웹 서비스 형태 - Streamlit

Voila의 장점 (이전 강의)

  • 노트북에서 쉽게 프로토타입을 만들 수 있음
  • 단, 대시보드처럼 레이아웃을 잡기 어려움 => 이런 경우 웹 개발 진행할 수 있음

웹서비스를 만드는 과정

  • 자바스크립트,React, Vue 등을 사용해 프로토타입을 만드는 것은 시간 효율적이지 않음
  • 처음부터 HTML/자바스크립트+Flask/FastAPI가 아닌, 기존 코드를 조금만 수정해서 웹서비스를 만드는 것이 목표

데이터 Product로 중요하게 된다면 프론트엔드/PM 조직과 협업

  • 단, 프론트엔드/PM조직은 다른 웹도 만들고 있어서 빠르게 이터레이션이 어려움

다른 조직의 도움 없이 빠르게 웹 서비스를 만드는 방법이 무엇일까?
이 문제를 해결하기 위해 등장한 것이 Streamlit !!

주의할 점 : 툴이나 라이브러리에 집착하지 말고, 점진적으로 문제를 해결하는 과정에 집중하기
현재 사용하는 도구의 장단점은 어떤 것이고 새로운 대안이 있을지 항상 생각해보기 !

가으이에선 Voila-Streamlit 순서로 했지만 추후엔 Streamlit부터 시작해도 괜찮음
모든 것은 프로젝트의 요구 조건에 따라 다름!

Streamlit의대안

1) R의 Shiny
2) Flas, Fast API: 백엔드를 직접 구성 + 프론트엔드 작업도 진행
3) Dash: 제일 기능이 풍부한 Python 대시보드 라이브러리
4) Voila: Jupyter Notebook을 바로 시각화 가능

슬로건 : The fastest way to build and share data apps

장점

  • 파이썬 스크립트 코드를 조금만 수정하면 웹을 띄울 수 있음
  • 백엔드 개발이나 HTTP요청을 구현하지 않아도 됨
  • 다양한 Component제공해 대시보드 UI구성할 수 있음
  • Steamlit Cloud도 존재해서 쉽게 배포할 수 있음(단, Community Plan은 Pulblic Repo만 가능)
  • 화면 녹화 기능(Record) 존재

Streamlit예시
albumentations Demo도 Streamlit으로 만들어짐.(augmentation 효과 보여주는 웹페이지)

Streamlit설치
pip install streamlit

Streamlit실행방법
(CLI) streamlit run streamlit-basic.py
localhost:8501에 접근가능

Streamlit Component

Streamlit Text작성 (Title, Header, Write)


import streamlit as st
import pandas as pd
import numpy as np
import time

st.title("Title")
st.header("Header")
st.subheader("subheader")

st.write("Write Something")
if st.button("버튼이 클릭되면"):
	st.write("클릭 후 보이는 메시지 !")

if st.button("버튼이 클릭되면2"):
	st.write("클릭 후 보이는 메세지 2!")
    

checkbox_btn = st.checkbox('체크박스 버튼')

if checkbox_btn :
	st.write("체크박스 버튼 클릭!")

checkbox_btn2 = st.checkbox('체크박스 버튼2', value = True)
if checkbox_btn2 :
	st.write('Button2')
    
    

st.write: 보여줄 수 있는것이면 어떤 것이든 보여줌

st.dataframe: Interactive한 Dataframe, 컬럼 클릭이 가능하고 정렬도 가능
st.table: Static한 Dataframe

df = pd.DataFrame({
	'first column':[1,2,3,4,],
    'second column':[10,20,30,40,]
    })
    
st.markdown("=======")

st.write(df)
st.dataframe(df)
st.table(df)

Dataframe의 Max값을 색칠할 수 있음

st.dataframe(df.style.highlight_max(axis=0))
st.table(df.style.highlight_max(axis=0))

Streamlit Metric, JSON

st.metric("Mymetric",42,2)
st.json(df.to_json())

Streamlit Line Chart

저장할 수도 있음

chart_data = pd.DataFrame(
	np.random.randn(20,3),
    columns=['a','b','c']
    )

st.line_chart(chart_data)

Streamlit Map Chart

map_data = pd.DataFrame(
	np.random.randn(1000,2)/[50,50] + [37.76,-122.4],
    columns=['lat','lon']
st.map(map_data)

Streamlit Chart

그 외에도 Plotly Chart등을 쉽게 사용할 수 있음
Chart 문서

Streamlit Radio Button, Select Box

A가 선택되면 이 작업을 수행

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!', 
						'J','H','D'))
st.write("You selected:", option)

selectbox의 Output을 변수에 저장해서 확인할 수 있음

Streamlit Multi Select Box

multi_select = st.multiselect('Please select Something in multi selectbox!' , 
							['A','B','C','D'])
st.write('You selected:', multi_select)

결과물:
[
	0:"A"
    1:"C"
]

Streamlit Slider

#description, min, max, default
value= st.slider('Select a range of values', 0.0, 100.0, (25.0,75.0))
st.write('Values:',values)

Streamlit Input Box, Caption, Code, Latex


text_input = st.text_input("텍스트를 입력해주세요")
st.write(text_input)

password_input = st.text_input("암호를 입력해주세요",type= "password")

number_input = st.number_input("숫자를 입력해주세요")
st.write(number_input)

st.date_input("날짜를 입력하세요")
st.time_input("시간을 입력하세요")

st.caption("This is caption")
st.code("a= 123")
st.latex("\int a x^2 \,dx")

Streamlit Layout - Sidebar

Sidebar에는 파라미터를 지정하거나, 암호를 설정할 수 있음

st.sidebar.button("hi")

기존 Method앞에 sidebar를 붙이면 sidebar에 보이게 됨

Streamlit Layout - Columns

여러 칸으로 나눠서 Component를 추가하고 싶은 경우 활용


col1, col2, col3, col4 = st.columns(4)
col1.write("this is col1")
col2.write("this is col2")
col3.write("this is col3")
col4.write("this is col4")

Streamlit Layout - Expander

눌렀을 경우 확장하는 부분이 필요한 경우


with st.expander("클릭하면 열려요"):
	st.write("content!")

Streamlit Spinner

연산이 진행되는 도중 메세지를 보여주고 싶은 경우


with st.spinner("Please wait.."):
	time.sleep(5)
    

연산 진행 도중 메세지를 보여주고 싶다.
inference, 전처리할때 작업중입니다~ 를 보여주기

Streamlit Balloons

ㅋㅋ귀여움 이거

st.balloons() 

Streamlit Status Box

st.success("Success") #초록
st.info("Info") # 파랑
st.warning("Warning")#노랑
st.error("Error message")#빨강

Streamlit Form

with st.form(key="입력 form"):
	username = st.text_input("User name")
    password = st.text_input("Password", type= "password")
    st.form_submit_button("login")
   

Streamlit File Uploader

200mb 제한 있음


uploaded_file = st.file_uploader("Choose a file", type= ["png","jpg","jpeg"])

Streamlit API Document & Cheat Sheet

정말 많은 Component가 존재함
문서 확인해보면서 실행하기!
Streamlit API Document <- 클릭

Streamlit 치트시트 <- 클릭

!!Streamlit의 DataFlow!!

Streamlit의 화면에서 무언가 업데이트 되면 전체 Streamlit코드가 다시 실행
1) Code가 수정되는 경우
2) 사용자가 Streamlit의 위젯과 상호작용하는 경우(버튼 클릭, 입력상자에 텍스트 입력시 등)

Session State

  • Streamlit의 DataFlow로 인해 매번 코드가 재실행되며 중복 이벤트를 할 수 없음
    -- Global Variable처럼 서로 공유할 수 있는 변수가 필요
  • Streamlit 0.84버전에 session_state가 개발됨
st.session_state.{session_state_value}
#session_state_value에 저장해서 활용하는 방식 

Session State가 없다면?

Increment 버튼을 누르면 +1, Decrement 버튼을 누르면 -1이 되는 Counter예제


st.title('Counter Example without session state')

count_value =0
increment = st.button('Increment')
if increment :
	count_value +=1
decrement = st.button('Decrement')
if decrement:
	count_value -= 1
    
st.write("Count = ", count_value)

버튼을 누를때마다 계속 다시 실행되므로 count_value는 0.


st.title('Counter Example without session state')

if 'count' not in st.session_state:
	st.session_state.count = 0
    
increment = st.button('Increment')
if increment :
	count_value +=1
    
decrement = st.button('Decrement')
if decrement:
	count_value -= 1
    
st.write("Count = ", count_value)

session_state의 경우 변수의 이름을 확인해야 하는데
if 'count' not in st.session_state: 가 없다면 실행될때마다
st.session_state.count = 0가 실행되서 똑같은 결과를 보여줄 것이다.

Session State가 이해되지 않는다면 실제로 코드를 실행해보고 아래 문서 읽어보기 !

session_state_for_streamlit

Session State를 사용한 예시

streamlit_app.py

st.slider가 변할 경우(on_change) Callback 함수를 사용해서 session_state값을 유지하는 코드 만들기.

Streamlit Cache - @st.cache

매번 다시 실행하는 특성 때문에 데이터도 매번 다시 읽을 수 있음
이런 경우 @st.cache 데코레이터를 사용해 캐싱하면 좋음(캐싱: 성능을 위해 메모리등에 저장하는 행위)

데이터를 읽는 함수를 만들고 데코레이터 적용

DATE_COLUMN = 'data/time'
DATE_URL = ('https~~')

@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
profile
-

0개의 댓글