Streamlit Session State 완벽 가이드
📦 Streamlit Session State 완벽 가이드
🎯 개요
Streamlit Session State는 웹 애플리케이션에서 사용자별 세션 데이터를 저장하고 관리하는 핵심 메커니즘임. 페이지가 다시 실행되어도 데이터를 유지할 수 있게 해주어 인터랙티브한 애플리케이션 개발을 가능하게 함.
이 프로젝트는 Session State의 개념부터 실전 활용까지 6가지 인터랙티브 예제로 학습할 수 있도록 설계된 교육용 대시보드임.

🔄 Streamlit 실행 모델 이해하기
기본 동작 방식
Streamlit은 사용자가 위젯과 상호작용할 때마다 전체 스크립트를 처음부터 다시 실행함. 이는 Streamlit의 핵심 철학이지만, 동시에 데이터 유지의 문제를 야기함.
# 매번 재실행됨
count = 0 # 항상 0으로 초기화됨
if st.button("증가"):
count += 1 # 버튼을 눌러도 다음 실행 시 다시 0이 됨
st.write(count) # 항상 0 출력
문제점
- 변수가 매번 초기화됨
- 이전 상태를 기억할 수 없음
- 사용자 입력이 유지되지 않음
Session State의 해결책
Session State를 사용하면 재실행 간에 데이터를 유지할 수 있음.
# Session State 사용
if 'count' not in st.session_state:
st.session_state.count = 0
if st.button("증가"):
st.session_state.count += 1
st.write(st.session_state.count) # 증가된 값이 유지됨

💡 Session State 핵심 개념
1. 딕셔너리 형태
st.session_state는 Python 딕셔너리처럼 동작함.
# 딕셔너리 스타일
st.session_state['key'] = 'value'
value = st.session_state['key']
# 속성 스타일 (권장)
st.session_state.key = 'value'
value = st.session_state.key
2. 초기화 패턴
Session State를 사용하기 전에 반드시 초기화가 필요함.

패턴 1: if 문 사용
if 'counter' not in st.session_state:
st.session_state.counter = 0
장점: 명시적이고 이해하기 쉬움
사용 사례: 단순한 조건부 초기화
패턴 2: setdefault 사용
st.session_state.setdefault('counter', 0)
장점: 간결하고 Pythonic함
사용 사례: 한 줄로 기본값 설정
패턴 3: 초기화 함수
def initialize_session_state():
"""Session State 초기화"""
defaults = {
'count': 0,
'logged_in': False,
'data': []
}
for key, value in defaults.items():
if key not in st.session_state:
st.session_state[key] = value
# 스크립트 시작 시 호출
initialize_session_state()
장점: 재사용 가능하고 관리가 용이함
사용 사례: 복잡한 애플리케이션에서 여러 상태를 한 번에 초기화
3. 데이터 타입
모든 Python 객체를 저장할 수 있음.
# 기본 타입
st.session_state.number = 42
st.session_state.text = "Hello"
st.session_state.flag = True
# 컬렉션
st.session_state.items = [1, 2, 3]
st.session_state.data = {'key': 'value'}
# 객체
st.session_state.df = pd.DataFrame()
st.session_state.model = trained_model
🎨 6가지 실습 예제
1. 🔢 카운터 (난이도: ⭐)
학습 목표: 기본적인 Session State 사용법
기능
- ➕ 증가: 카운터 값을 1 증가시킴
- ➖ 감소: 카운터 값을 1 감소시킴
- 🔄 초기화: 카운터를 0으로 리셋함
- 📊 히스토리: 모든 클릭 기록을 확인함
핵심 코드
if 'counter' not in st.session_state:
st.session_state.counter = 0
st.session_state.click_history = []
def increment():
st.session_state.counter += 1
st.session_state.click_history.append({
'time': datetime.now().timestamp(),
'action': 'increment',
'value': st.session_state.counter
})
st.button("증가", on_click=increment)
st.metric("현재 카운트", st.session_state.counter)
학습 포인트
- Session State 초기화 패턴
- 콜백 함수 활용
- 히스토리 데이터 저장
2. 🔐 로그인 시스템 (난이도: ⭐⭐)
학습 목표: 인증 상태 관리
기능
- 🔓 로그인: 사용자 인증 (테스트 비밀번호: 1234)
- 🔒 로그아웃: 세션 종료
- ⏱️ 로그인 시간 추적: 세션 지속 시간 표시
핵심 코드
if 'logged_in' not in st.session_state:
st.session_state.logged_in = False
st.session_state.username = ''
st.session_state.login_time = None
if not st.session_state.logged_in:
# 로그인 폼
username = st.text_input("사용자 이름")
password = st.text_input("비밀번호", type="password")
if st.button("로그인"):
if password == "1234":
st.session_state.logged_in = True
st.session_state.username = username
st.session_state.login_time = datetime.now()
st.rerun()
else:
# 로그인 후 화면
st.success(f"환영합니다, {st.session_state.username}님!")
if st.button("로그아웃"):
st.session_state.logged_in = False
st.session_state.username = ''
st.session_state.login_time = None
st.rerun()
학습 포인트
- 조건부 UI 렌더링
st.rerun()활용- 시간 데이터 저장
3. 🛒 쇼핑 카트 (난이도: ⭐⭐)
학습 목표: 리스트 데이터 관리
기능
- ➕ 상품 추가: 장바구니에 상품 추가
- ❌ 상품 제거: 개별 상품 삭제
- 🗑️ 장바구니 비우기: 전체 삭제
- 💳 결제: 결제 처리 및 초기화
핵심 코드
if 'cart' not in st.session_state:
st.session_state.cart = []
st.session_state.total_price = 0
# 상품 추가
if st.button(f"추가 - {product}"):
st.session_state.cart.append({
'product': product,
'price': price,
'time': datetime.now().strftime("%H:%M:%S")
})
st.session_state.total_price += price
st.rerun()
# 총 금액 계산
total = sum(item['price'] for item in st.session_state.cart)
st.metric("총 금액", f"{total:,}원")
학습 포인트
- 리스트 데이터 추가/삭제
- 동적 UI 생성
- 실시간 계산
4. 📝 다단계 설문조사 (난이도: ⭐⭐⭐)
학습 목표: 다단계 프로세스 관리
기능
- 1단계: 기본 정보 입력 (이름, 나이)
- 2단계: 선호도 조사 (색상, 음식)
- 3단계: 의견 수집 (피드백, 만족도)
- 4단계: 결과 확인 및 JSON 출력
핵심 코드
if 'survey_step' not in st.session_state:
st.session_state.survey_step = 1
st.session_state.survey_data = {}
# 진행 상황 표시
progress = (st.session_state.survey_step - 1) / 3
st.progress(progress)
if st.session_state.survey_step == 1:
# 1단계 UI
name = st.text_input("이름")
age = st.number_input("나이", min_value=0)
if st.button("다음"):
st.session_state.survey_data['name'] = name
st.session_state.survey_data['age'] = age
st.session_state.survey_step = 2
st.rerun()
elif st.session_state.survey_step == 2:
# 2단계 UI
favorite_color = st.selectbox("좋아하는 색상", ["빨강", "파랑", "초록"])
if st.button("다음"):
st.session_state.survey_data['favorite_color'] = favorite_color
st.session_state.survey_step = 3
st.rerun()
학습 포인트
- 단계별 UI 전환
- 데이터 누적 저장
- 진행 상황 표시
5. ✅ To-Do 리스트 (난이도: ⭐⭐⭐)
학습 목표: CRUD 작업 구현
기능
- ➕ 할 일 추가: 새 항목 생성
- ✅ 완료 체크: 상태 토글
- 🗑️ 삭제: 개별/완료/전체 삭제
- 📊 통계: 전체/완료/대기 개수
핵심 코드
if 'todos' not in st.session_state:
st.session_state.todos = []
st.session_state.todo_id_counter = 0
# 추가
if st.button("추가"):
st.session_state.todos.append({
'id': st.session_state.todo_id_counter,
'text': new_todo,
'completed': False,
'created_at': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
})
st.session_state.todo_id_counter += 1
st.rerun()
# 완료 토글
completed = st.checkbox("완료", value=todo['completed'], key=f"todo_{todo['id']}")
if completed != todo['completed']:
st.session_state.todos[idx]['completed'] = completed
st.rerun()
# 삭제
if st.button("삭제", key=f"delete_{todo['id']}"):
st.session_state.todos.pop(idx)
st.rerun()
학습 포인트
- 고유 ID 관리
- 체크박스 상태 동기화
- 필터링 및 통계
6. 📄 폼 데이터 관리 (난이도: ⭐⭐)
학습 목표: 복잡한 폼 데이터 저장
기능
- 💾 저장: 폼 데이터를 Session State에 저장
- 🔄 초기화: 폼 데이터 삭제
- 📋 미리보기: 저장된 데이터 확인
- 🔁 복원: 저장된 데이터로 폼 채우기
핵심 코드
if 'form_data' not in st.session_state:
st.session_state.form_data = {}
# 저장된 값으로 초기화
name = st.text_input(
"이름",
value=st.session_state.form_data.get('name', '')
)
email = st.text_input(
"이메일",
value=st.session_state.form_data.get('email', '')
)
# 저장
if st.button("저장"):
st.session_state.form_data = {
'name': name,
'email': email,
'saved_at': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
st.success("저장되었습니다!")
학습 포인트
- 딕셔너리 데이터 관리
- 폼 값 복원
- 날짜/시간 데이터 처리
🎨 콜백 함수와 Session State
콜백 함수
위젯이 변경될 때 자동으로 실행되는 함수를 지정할 수 있음.
def increment():
st.session_state.count += 1
if 'count' not in st.session_state:
st.session_state.count = 0
# on_click 콜백
st.button("증가", on_click=increment)
st.write(st.session_state.count)
위젯 키와 자동 동기화
위젯에 key를 지정하면 자동으로 session_state와 동기화됨.
# 위젯 값이 자동으로 session_state에 저장됨
name = st.text_input("이름", key="user_name")
# 다른 곳에서 접근 가능
st.write(f"저장된 이름: {st.session_state.user_name}")
⚠️ 주의사항
1. 키 충돌 방지
위젯의 key와 수동으로 설정한 session_state 키가 충돌하지 않도록 주의함.
# ❌ 잘못된 예
st.session_state.name = "John"
st.text_input("이름", key="name") # 충돌!
# ✅ 올바른 예
st.session_state.user_name = "John"
st.text_input("이름", key="input_name")
2. st.rerun() 사용
Session State를 변경한 후 즉시 UI를 업데이트하려면 st.rerun()을 호출함.
if st.button("초기화"):
st.session_state.count = 0
st.rerun() # 즉시 화면 갱신
3. 초기화 타이밍
Session State 초기화는 스크립트 상단에서 수행하는 것이 좋음.
# ✅ 권장: 스크립트 상단
def initialize_session_state():
if 'initialized' not in st.session_state:
st.session_state.count = 0
st.session_state.data = []
st.session_state.initialized = True
initialize_session_state()
# 나머지 코드...
🔍 디버깅
Session State 내용 확인
# 전체 session_state 출력
st.write("Session State:", st.session_state)
# 특정 키 존재 확인
if 'key' in st.session_state:
st.write("키가 존재함")
# 모든 키 출력
st.write("모든 키:", list(st.session_state.keys()))
개발자 도구
with st.expander("🔧 Session State 디버그"):
st.json(dict(st.session_state))
📊 Session State vs 캐싱
| 특징 | Session State | Caching (@st.cache_data) |
|---|---|---|
| 목적 | 사용자별 상태 저장 | 계산 결과 재사용 |
| 범위 | 단일 세션 | 모든 사용자 공유 |
| 수명 | 세션 종료 시 삭제 | 캐시 만료 시까지 |
| 용도 | UI 상태, 사용자 입력 | 데이터 로딩, 모델 학습 |
💡 베스트 프랙티스
1. 초기화 함수 사용
def initialize_session_state():
"""Session State 초기화"""
defaults = {
'count': 0,
'logged_in': False,
'page': 'home',
'data': []
}
for key, value in defaults.items():
if key not in st.session_state:
st.session_state[key] = value
# 스크립트 시작 시 호출
initialize_session_state()
2. 네임스페이스 사용
# 관련 데이터를 그룹화
if 'user' not in st.session_state:
st.session_state.user = {
'name': '',
'email': '',
'logged_in': False
}
# 접근
st.session_state.user['name'] = "John"
3. 상태 초기화 함수
def reset_state():
"""상태 초기화"""
for key in list(st.session_state.keys()):
del st.session_state[key]
if st.button("전체 초기화"):
reset_state()
st.rerun()
🚀 프로젝트 구조
Session/
├── session_manager.py # 🎯 메인 대시보드 (700+ 줄)
├── session_state_개념.md # 📚 Session State 개념 설명
├── 실습가이드.md # 🚀 실습 가이드
└── README.md # 📖 프로젝트 개요
🎯 학습 체크리스트
기본 (필수)
- Session State 초기화 방법 이해
- 값 읽기/쓰기 방법 이해
- 콜백 함수 사용법 이해
- 카운터 예제 완료
중급 (권장)
- 리스트/딕셔너리 데이터 관리
- 다단계 프로세스 구현
- 조건부 UI 렌더링
- 로그인 & 쇼핑 카트 예제 완료
고급 (선택)
- 복잡한 상태 관리
- 최적화 기법 적용
- 디버깅 및 문제 해결
- 모든 예제 완료 및 커스텀 예제 구현
🌟 프로젝트 하이라이트
교육적 가치
- 📚 체계적인 학습: 개념 → 기본 → 고급 순서
- 🎯 실전 중심: 6가지 실용적인 예제
- 🔍 디버깅 도구: 실시간 상태 확인
기술적 완성도
- 💻 700+ 줄의 코드: 주석과 구조화
- 🎨 프리미엄 디자인: 현대적인 UI/UX
- 🔧 디버그 기능: 개발자 친화적
실용적 가치
- 🚀 즉시 활용 가능: 실제 프로젝트에 적용
- 📖 완벽한 문서화: 개념부터 실습까지
- 🎓 학습 로드맵: 단계별 가이드
📈 활용 사례
1. 교육
- Streamlit 워크샵 교재
- 대학 강의 자료
- 온라인 튜토리얼
2. 개발
- 프로젝트 템플릿
- 코드 참고 자료
- 디버깅 도구
3. 프로토타이핑
- 빠른 UI 프로토타입
- 사용자 테스트
- 개념 증명 (PoC)
🔮 향후 계획
- 더 많은 예제 추가 (게임, 채팅 등)
- 영어 버전 문서
- 비디오 튜토리얼
- 고급 패턴 가이드
- 성능 최적화 팁
📚 참고 자료
공식 문서
커뮤니티
💻 실행 방법
1. 설치
# Streamlit 설치
pip install streamlit pandas
2. 실행
streamlit run session_manager.py
3. 접속
브라우저에서 http://localhost:8501 접속
🎨 UI/UX 디자인
색상 팔레트
- 메인 그라디언트:
#667eea→#764ba2(보라색 계열) - 사이드바:
#2d3748→#1a202c(다크 그레이) - 강조색:
#667eea(보라색)
스타일링 요소
- ✨ 그라디언트 배경: 프리미엄 느낌
- 🌙 다크 사이드바: 가독성 향상
- 🎯 커스텀 탭: 선택된 탭 강조
- 💫 호버 효과: 버튼에 애니메이션
🎓 학습 로드맵
1단계: 개념 이해 (30분)
- Session State의 필요성 이해
- 기본 사용 패턴 학습
- 초기화 방법 익히기
2단계: 기본 실습 (1시간)
- 카운터 예제 실습
- 로그인 시스템 실습
- 쇼핑 카트 실습
3단계: 고급 실습 (1.5시간)
- 다단계 설문조사 실습
- To-Do 리스트 실습
- 폼 데이터 관리 실습
4단계: 응용 (자유)
- 커스텀 예제 만들기
- 실제 프로젝트에 적용
- 고급 패턴 탐구
🎯 핵심 요약
- Session State는 필수: Streamlit에서 상태 관리의 핵심 메커니즘임
- 초기화가 중요: 사용 전 반드시 초기화 필요
- 콜백 활용: 효율적인 상태 업데이트
- 디버깅 도구: 실시간 상태 확인으로 개발 효율 향상
- 베스트 프랙티스: 초기화 함수, 네임스페이스, 키 충돌 방지
Made with ❤️ using Streamlit
2026-02-09
Comments