LangChain 챗봇7장 · 웹 UI 연동과 배포3 / 22← 이전목차다음 →MetaContents

7장. 웹 UI 연동과 배포

Streamlit 기초와 화면 부품

식당의 주문 키오스크를 떠올려 보세요. 화면에 가게 이름이 크게 뜨고, 메뉴를 고르는 단추와 수량을 정하는 칸이 있고, 옆에는 "매장 / 포장"을 고르는 작은 막대가 붙어 있습니다. 키오스크를 만드는 사람이 그림을 그리듯 화면을 짜는 대신 "여기에 제목, 여기에 고르기 상자"라고 차례로 적어 주기만 하면 화면이 생긴다면 편할 것입니다. Streamlit 이 이렇게 일합니다. 파이썬 파일에 st.title(...), st.selectbox(...) 를 위에서부터 적으면 그 차례대로 웹 화면에 부품이 놓입니다.

웹 화면을 만드는 두 길로 HTML·CSS·자바스크립트로 만드는 웹과 파이썬 파일 하나로 만드는 Streamlit 을 나란히 놓은 비교 그림

왼쪽 파랑 상자는 보통의 웹 화면입니다. 화면의 뼈대(HTML), 꾸밈(CSS), 움직임(자바스크립트)을 따로 쓰고, 그와 별도로 파이썬 서버를 둡니다. 오른쪽 보라 상자는 Streamlit 입니다. 파이썬 파일 하나에 화면과 로직을 함께 적고, Streamlit 이 그것을 웹 화면으로 바꿔 줍니다. 여기서 키오스크 화면이 웹 UI, 키오스크의 단추와 칸이 위젯, 옆의 작은 막대가 사이드바입니다. 비유와 다른 점은, 키오스크는 화면 배치를 마음대로 바꿀 수 있지만 Streamlit 은 부품을 위에서 아래로 쌓는 꼴이 정해져 있어서 화려한 배치에는 맞지 않는다는 것입니다.

자주 쓰는 화면 부품

함수원래 말하는 일돌려주는 값
st.set_page_config(page_title=…)쪽 설정브라우저 탭의 제목을 정한다. 화면 코드 가운데 맨 먼저 부른다없음
st.title("…")제목가장 큰 제목없음
st.write(…), st.markdown("…")쓰다, 마크다운글을 쓴다. write 는 표나 사전도 알아서 그린다없음
st.caption("…")설명 글작고 흐린 설명 글없음
st.text_input("이름")글 입력한 줄 입력칸적은 글(str)
st.selectbox("여행지", [...])고르기 상자목록에서 하나 고르기고른 값
st.slider("박수", 1, 5, 2)밀대최솟값, 최댓값, 처음 값 사이에서 고르기고른 수
st.button("인사하기")단추누른 실행에서만 TrueTrue / False
with st.sidebar:옆 막대이 안의 부품을 왼쪽 사이드바에 놓는다없음

짧은 예시

앱을 브라우저로 띄우지 않고 AppTest 로 한 번 실행해, 화면에 무엇이 놓였는지 꺼내 봅니다. 앱 코드는 글자열로 적었습니다. 실제로는 이 글이 .py 파일 하나가 됩니다.

Python
from streamlit.testing.v1 import AppTest

# 앱 코드를 글자열로 적어 둔다. 실제로는 이 글이 .py 파일 하나가 된다
APP = """
import streamlit as st

st.title("구름다리여행 여행 비서")
st.write("가고 싶은 곳을 골라 보세요.")
city = st.selectbox("여행지", ["제주도", "부산", "강릉"])
nights = st.slider("박수", 1, 5, 2)
st.write(f"{city} {nights}박 {nights + 1}일을 골랐습니다.")
"""

# from_string: 글자열의 앱을 브라우저 없이 한 번 실행한다
at = AppTest.from_string(APP).run()
print("제목:", at.title[0].value)
print("고르기 상자:", at.selectbox[0].label, "→", at.selectbox[0].value)
print("밀대:", at.slider[0].label, "→", at.slider[0].value)
print("마지막 글:", at.markdown[-1].value)
출력
제목: 구름다리여행 여행 비서
고르기 상자: 여행지 → 제주도
밀대: 박수 → 2
마지막 글: 제주도 2박 3일을 골랐습니다.

고르기 상자는 손님이 아직 아무것도 고르지 않았으므로 목록의 첫 값 "제주도"를, 밀대는 처음 값 2 를 돌려주었습니다. 위젯 함수가 돌려준 값(city, nights)을 보통 변수처럼 다음 줄에서 바로 썼습니다. st.write 로 쓴 글은 화면에서 마크다운 글이 되므로 at.markdown 에서 꺼냅니다.

코드가 의미하는 것

이 코드는 키오스크 화면을 "여기에 제목, 여기에 고르기 상자"라고 차례로 적어 만든 뒤, 직원이 화면을 한 번 켜서 무엇이 놓였는지 훑어보는 일을 흉내 낸 것입니다. 화면 적기, 브라우저 없이 켜기, 부품 꺼내 보기의 세 동작입니다.

코드하는 일챗봇에서 뜻하는 것
APP = """ … """앱 코드를 글자열로 담는다실제로는 이 글이 .py 파일 한 장입니다. 챗봇의 웹 화면도 이렇게 파이썬 줄 몇 개로 적습니다
st.title(…), st.write(…)(앱 안)제목과 글을 위에서부터 놓는다적은 차례가 곧 화면의 차례입니다. 챗봇 화면의 제목과 안내 글이 이 자리에 옵니다
city = st.selectbox(…), nights = st.slider(…)(앱 안)위젯을 놓고 손님이 고른 값을 받는다위젯 함수는 부품을 그리면서 값도 돌려줍니다. 챗봇에서는 설정 칸이 이런 위젯입니다
AppTest.from_string(APP).run()앱을 브라우저 없이 한 번 실행한다손님 없이 직원이 화면을 켜 보는 시험입니다. 이 장의 실습은 모두 이 방법으로 화면을 확인합니다
at.title[0].value, at.selectbox[0].value화면에 놓인 부품과 값을 꺼낸다눈으로 보는 대신 코드로 화면을 읽습니다. 그래서 브라우저 없이 같은 결과를 되풀이해 얻습니다

결과에서 읽을 것은 두 가지입니다.

  • 아무것도 고르지 않으면 위젯은 처음 값을 돌려줍니다. 고르기 상자는 목록의 첫 값 "제주도", 밀대는 처음 값 2 를 돌려주었습니다.
  • 돌려받은 값은 다음 줄에서 바로 화면 글이 됩니다. 마지막 글 "제주도 2박 3일을 골랐습니다." 는 city 와 nights 로 만든 글입니다.

주의할 점

  • Streamlit 앱은 python 파일.py 가 아니라 streamlit run 파일.py 로 실행합니다. 그냥 python 으로 돌리면 화면이 뜨지 않고 "missing ScriptRunContext" 같은 경고만 나옵니다.
  • 위젯의 이름표("여행지")가 같은 위젯을 두 번 만들면 "같은 위젯이 둘"이라는 오류가 납니다. 이름표가 같아야 하면 key="city2" 처럼 서로 다른 key 를 줍니다.
  • 이 장의 실습은 앱을 out_ch07_….py 파일로 저장한 뒤 AppTest.from_file(...) 로 시험합니다. 실습이 끝나면 같은 파일을 streamlit run 으로 열어 브라우저에서도 확인해 보세요.
← 이전 절7장 · 용어 짚고 가기다음 절 →7장 · 위에서 아래로 다시 도는 실행 모델