나만의 웹서비스 런칭
지금까지 만든 프로그램은 내 컴퓨터에서만 돌았어요. 오늘은 누구나 폰으로 접속하는 웹서비스를 만들어 인터넷에 올립니다.
오늘 배우는 것
심화 과정의 첫 수업입니다. 오늘은 화면이 있는 웹앱을 만들고, 그 앱을 인터넷에 배포해 누구나 접속할 수 있는 주소를 만드는 것까지 해봅니다.
Streamlit (스트림릿)이란?
파이썬 코드만으로 웹앱 화면을 만들 수 있게 해주는 도구예요. 버튼·입력창·제목 같은 화면 요소를 st.button(), st.title()처럼 짧은 코드 한 줄로 만들 수 있어요.
인터넷 주소(URL)는 어떻게 생겼을까?
우리가 만든 앱을 인터넷에 올리면 주소가 하나 생겨요. 이 주소(URL)는 아무렇게나 생긴 게 아니라, 정해진 구조가 있어요. 주소만 알면 전 세계 누구나 같은 페이지를 찾아올 수 있게 하는 약속이에요.
지금까지의 프로그램 vs 웹앱
지금까지 만든 파이썬 프로그램은 터미널(검은 화면)에서 글자로만 돌아갔어요. 그리고 그 프로그램은 내 컴퓨터에서만 실행됐죠. 웹앱은 두 가지가 결정적으로 다릅니다.
Streamlit이라는 도구로 코드 몇 줄로 만듭니다.https://... 주소가 생기고 폰에서도 열려요.보통 웹사이트를 만들려면 HTML·CSS·자바스크립트를 따로 배워야 해요. Streamlit은 파이썬 코드만으로 화면을 만들 수 있게 해줍니다. 우리가 이미 아는 파이썬으로 바로 웹앱을 만들 수 있다는 뜻이에요.
'오늘의 운세' 웹앱 띄우기
① Streamlit 설치하기
먼저 도구를 설치합니다. 터미널에 (venv) 표시가 있는지 확인하고 입력하세요. (설치는 한 번만 하면 돼요.)
# (venv) 표시 확인 후 설치
pip install streamlit② AI를 부르는 준비 — API 키와 ask_ai 함수
1단계 — VS Code 터미널에서 수업 폴더 안에 파일 만들기
# Windows
New-Item .env
# Mac
touch .env2단계 — .env 파일을 열고 아래 한 줄 입력 (선생님이 알려준 키 사용)
OPENAI_API_KEY=여기에_선생님이_알려준_키_붙여넣기⚠️ 키 앞뒤에 공백이나 따옴표 없이 딱 붙여서 저장하세요. .env 파일은 코드와 같은 폴더에 있어야 해요.
우리 앱은 AI에게 운세를 부탁할 거예요. 그러려면 두 가지가 필요해요.
.env(또는 배포 시 st.secrets)에서 자동으로 꺼내 씁니다. 키 내용을 화면·채팅·코드에 직접 적지 않아요.그리고 AI를 부르는 짧은 함수 하나를 만들어 두면, 앞으로 계속 편하게 쓸 수 있어요. 이 함수는 한 번 만들어 두고 재사용합니다.
from openai import OpenAI
client = OpenAI() # 키는 .env / secrets에서 자동으로 불러옴
def ask_ai(prompt):
res = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
)
return res.choices[0].message.contentask_ai("질문")이라고 쓰면, AI에게 질문을 보내고 답을 글자로 돌려줘요. 'AI 호출 3단계(준비 → 보내기 → 답 꺼내기)'를 이 함수 하나에 담아 둔 거예요. 다음부터는 ask_ai(...)만 부르면 됩니다.
③ 운세 웹앱 코드 만들기
이제 화면을 만들어요. AI 도구에 아래 프롬프트를 직접 입력해 기본 코드를 받아 보세요. 프롬프트는 ① 무엇을 만들지 ② 어떻게 동작할지 ③ 키 처리 방법 세 가지를 분명히 적는 게 핵심이에요.
④ 핵심 구조 이해하기
코드에는 보통 이런 핵심 줄이 들어 있어요. 이 세 부분만 찾을 수 있으면 충분합니다.
import streamlit as st
# ── ① 화면 만들기 ──
st.title("🔮 오늘의 운세")
# ── ② 버튼을 누르면 실행 ──
if st.button("운세 뽑기"):
result = ask_ai("오늘의 운세를 한 문장으로 말해줘") # 위에서 만든 함수
# ── ③ 결과 보여주기 ──
st.write(result)⑤ 앱 실행하기
코드를 app.py로 저장했다면, 이제 터미널에서 실행합니다. 실행하면 브라우저가 저절로 열려요.
streamlit run app.py버튼을 누르면 브라우저에 이런 식으로 나와요.
🔮 오늘의 운세
[ 운세 뽑기 ]
오늘은 작은 행운이 당신을 따라다니는 날이에요.
망설이던 일에 용기를 내보세요!- ModuleNotFoundError:
streamlit이 설치 안 된 상태. 터미널(venv)표시 확인 후 다시 설치. streamlit run이 아니라python app.py로 실행하면 화면이 안 떠요. 꼭streamlit run app.py.- 버튼을 눌러도 반응이 없으면, AI 호출 부분이
if st.button(...)안에 들어 있는지 확인.
🔒 힌트 — 화면에 빨간 에러가 떠요 (전체 참고 코드)
에러가 계속 나면 아래 전체 구조와 비교해 보세요. (그대로 베끼기보다, 내 코드에서 빠진 부분을 찾는 용도예요.)
import streamlit as st
from openai import OpenAI
client = OpenAI() # 키는 .env / secrets에서 자동으로
def ask_ai(prompt):
res = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
)
return res.choices[0].message.content
st.title("🔮 오늘의 운세")
if st.button("운세 뽑기"):
st.write(ask_ai("오늘의 운세를 한 문장으로 말해줘"))키 관련 에러: 키 설정 파일이 제대로 들어갔는지 선생님께 확인을 요청하세요. 학생이 키를 직접 입력하지 않습니다.
나만의 앱으로 꾸미기
기본 앱이 돌아간다면, 이제 내 취향을 더할 차례예요. 그런데 바로 정답을 보지 말고, 먼저 스스로 생각해 보는 것부터 시작해요.
① 사용자에게 이름을 어떻게 입력받을지 생각해 보세요. ② 그 이름을 AI에게 보내는 요청에 어떻게 끼워 넣을지 생각해 보세요.
떠올랐다면, 바로 코드를 받지 말고 내가 직접 AI에게 요청할 프롬프트를 한 문장으로 적어 보세요.
스스로 프롬프트를 적어봤다면, 아래 예시와 비교해 보세요. 똑같지 않아도 괜찮아요 — 내 방식대로 요청해도 됩니다.
🔒 내가 적은 프롬프트와 비교해보기 (예시)
이 정도로 요청하면 충분해요. 핵심은 "이름을 입력받아 → 운세 요청에 넣는다"는 흐름을 내가 먼저 떠올리는 거예요.
더 꾸미고 싶다면 — Streamlit 위젯
화면에 넣을 수 있는 요소를 위젯(widget)이라고 불러요. 아래 위젯들을 AI에게 "추가해줘"라고 요청하면 화면이 풍성해져요. 어떤 위젯이 있는지 알아두면, 무엇을 요청할지 스스로 정할 수 있어요.
이름을 입력하세요: [ 지민 ]
운세 주제: [ 공부 ▾ ]
[ 운세 뽑기 ]
✅ 지민님의 공부 운세
오늘 집중력이 평소보다 좋아요. 어려운 문제부터 도전!- 입력한 이름이 운세에 안 들어가요 → 입력창 값을 변수에 담아 AI 요청 문장 안에 넣어야 해요.
- 기능을 추가했더니 기존 게 사라졌어요 → "기존 기능은 그대로 두고 ~를 추가해줘"라고 요청하세요.
st.balloons()를if밖에 두면 버튼을 안 눌러도 풍선이 떠요.
🔒 힌트 — 이름이 운세에 안 들어가요 (참고 코드)
입력창의 값을 변수에 담아, AI에게 보내는 요청 문장 안에 그 변수를 끼워 넣어야 해요.
name = st.text_input("이름을 입력하세요")
if st.button("운세 뽑기"):
# 이름을 프롬프트에 직접 끼워 넣기
st.write(ask_ai(f"{name}님을 위한 오늘의 운세를 한 문장으로"))배포해서 폰으로 접속하기
이제 마지막 단계예요. 내 컴퓨터에서만 돌던 앱을 Streamlit Community Cloud라는 무료 서비스에 올리면, 전 세계 어디서나 열리는 주소가 생깁니다.
배포 3단계
배포에 꼭 필요한 파일
배포하려면 "이 앱은 어떤 라이브러리가 필요해요"를 알려주는 목록 파일이 있어야 해요. AI에게 "이 앱의 requirements.txt를 만들어줘"라고 요청하면 됩니다.
streamlit
openai배포가 끝나면 https://...streamlit.app 주소가 생겨요. 이 주소를 폰으로 나에게 보내서 폰 브라우저로 직접 열어 보세요. 내가 만든 앱이 인터넷에 올라가 있는 거예요.
🃏 선택지 카드 — 배포 전에 무엇을 더할까?
배포하기 전, 앱에 하나만 더 추가해 봅시다. 하나를 골라 AI에게 요청해 보세요.
- 배포한 앱이 에러 → 대부분
requirements.txt가 빠졌거나 Secrets에 키를 안 넣어서예요. - GitHub에
.env파일(키)을 올리면 절대 안 돼요 → 키는 배포 화면의 Secrets에만 넣습니다. - 코드를 GitHub에 다시 올렸는데 앱이 그대로면 → 잠시 기다리거나 'Reboot'을 눌러요.
🔒 힌트 — 배포한 앱에서 에러가 떠요
가장 흔한 원인 두 가지예요.
① requirements.txt 누락 — AI에게 "이 앱의 requirements.txt를 만들어줘"라고 요청해 저장소에 추가.
② Secrets 미설정 — 배포 설정의 Secrets 칸에 키를 넣었는지 확인. 형식은 선생님 안내를 따르세요.
더 해보고 싶다면
미션 3까지 끝내고 시간이 남는다면 도전해 보세요. 끝내지 못해도 괜찮습니다.
보너스 ① 방문자 카운터 달기
앱에 접속한 사람 수를 세서 화면에 보여줍니다. "몇 명이나 내 운세를 봤을까?"를 확인할 수 있어요.
# 세션 안에서 숫자를 기억하기
if "count" not in st.session_state:
st.session_state.count = 0
if st.button("운세 뽑기"):
st.session_state.count += 1
st.write(result)
st.caption(f"오늘 {st.session_state.count}번 뽑았어요!")보너스 ② 친구에게 공유하고 후기 받기
완성된 주소를 친구 3명에게 보내고, 써 본 느낌을 물어보세요. "뭐가 제일 재밌었어? 뭘 더하면 좋을까?"를 물어 다음 주 개선 아이디어로 모읍니다.
오늘의 핵심 정리
🔧 막혔을 때 — 자가 디버깅 4단계
에러가 떠도 당황하지 마세요. 선생님께 묻기 전에 이 순서대로 스스로 해결해 봅니다.