[Python 100일 챌린지] Day 81 - Flask 시작하기
지금까지 Python으로 데이터를 처리하고, 파일을 다루고, 웹을 크롤링했습니다. 🤔 ──이제는 “우리만의 웹사이트를 만드는 법”을 배울 차례입니다! 🌐
Flask는 Python으로 웹 애플리케이션을 만드는 가장 쉽고 빠른 방법입니다. 단 5줄의 코드로 웹서버를 만들 수 있다는 것을 믿으시나요?
오늘부터 여러분은 웹 개발자의 세계에 입문합니다! Instagram, Pinterest, LinkedIn 같은 유명 서비스들도 Flask를 사용했습니다. 💡
(30분 완독 ⭐⭐⭐⭐)
🎯 오늘의 학습 목표
📚 사전 지식
- Day 24: 함수 정의하기 - 함수의 기초
- Day 51: requests 라이브러리 - HTTP 요청의 이해
- 기본적인 HTML 지식 - 간단한 태그 정도만 알아도 OK!
🎯 학습 목표 1: 웹 개발의 기본 개념 이해하기
웹은 어떻게 동작할까?
1
2
3
4
5
6
7
8
9
10
11
12
13
🌐 웹의 동작 원리
사용자 (Client) 웹 서버 (Server)
| |
| ① HTTP 요청 (Request) |
| ----------------------> |
| |
| ② 처리
| |
| ③ HTTP 응답 (Response) |
| <---------------------- |
| |
화면에 표시 데이터 준비
실생활 비유:
- 식당 손님(클라이언트): 웹 브라우저 (Chrome, Safari 등)
- 웨이터(HTTP): 요청과 응답을 전달
- 주방(서버): Flask 애플리케이션
- 요리사(코드): Python 코드로 작성한 로직
프론트엔드 vs 백엔드
1
2
3
4
5
6
7
8
9
# 프론트엔드 (사용자가 보는 부분)
- HTML: 웹페이지의 구조 (뼈대)
- CSS: 웹페이지의 디자인 (옷)
- JavaScript: 웹페이지의 동작 (움직임)
# 백엔드 (서버에서 처리하는 부분) ← 우리가 배울 것!
- Flask: Python 웹 프레임워크
- 데이터베이스: 정보 저장
- API: 다른 서비스와 통신
Flask란?
Flask는 Python으로 웹 애플리케이션을 만드는 마이크로 프레임워크입니다.
1
2
3
4
5
6
7
8
9
10
11
12
# Flask의 철학: "작고 강력하게"
✅ 장점:
- 배우기 쉬움 (단순한 문법)
- 빠른 개발 속도
- 유연성 (필요한 것만 추가)
- 강력한 커뮤니티
❓ 다른 프레임워크와 비교:
- Django: 모든 기능 포함 (무겁지만 강력)
- Flask: 필요한 것만 선택 (가볍고 유연) ← 초보자 추천!
- FastAPI: 최신 비동기 프레임워크 (고급)
Flask로 무엇을 만들 수 있나?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Flask로 만들 수 있는 것들:
🌐 웹사이트
- 블로그
- 쇼핑몰
- SNS
📊 대시보드
- 데이터 시각화
- 관리자 페이지
🔌 REST API
- 모바일 앱 백엔드
- 마이크로서비스
🤖 자동화 도구
- 웹훅 서버
- 챗봇 백엔드
🎯 학습 목표 2: Flask 설치와 환경 설정하기
1. 가상 환경 만들기 (중요!)
왜 가상 환경이 필요할까?
- 프로젝트마다 독립적인 패키지 관리
- 버전 충돌 방지
- 깔끔한 의존성 관리
1
2
3
4
5
6
7
8
9
10
# Windows
python -m venv venv
venv\Scripts\activate
# Mac/Linux
python3 -m venv venv
source venv/bin/activate
# 가상 환경 활성화 확인 (프롬프트 앞에 (venv) 표시됨)
(venv) $
2. Flask 설치하기
1
2
3
4
5
# Flask 설치
pip install flask
# 설치 확인
pip show flask
출력:
1
2
3
Name: Flask
Version: 3.0.0
Summary: A simple framework for building complex web applications.
3. 프로젝트 구조 만들기
1
2
3
4
5
6
7
# 프로젝트 폴더 구조
my_flask_app/
├── venv/ # 가상 환경 (건드리지 않음)
├── app.py # 메인 애플리케이션 파일
├── templates/ # HTML 파일들 (나중에)
├── static/ # CSS, JS, 이미지 파일들 (나중에)
└── requirements.txt # 패키지 목록
1
2
3
4
5
6
# 폴더 만들기
mkdir my_flask_app
cd my_flask_app
# 나중에 사용할 폴더들
mkdir templates static
🎯 학습 목표 3: 첫 Flask 애플리케이션 만들기
최소한의 Flask 앱 (5줄!)
app.py 파일을 만들고 다음 코드를 작성하세요:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# app.py - 세상에서 가장 간단한 Flask 앱!
from flask import Flask
# Flask 애플리케이션 객체 생성
app = Flask(__name__)
# 라우트 정의: "/" 주소로 접속하면 실행됨
@app.route('/')
def home():
return "Hello, Flask! 🎉"
# 개발 서버 실행
if __name__ == '__main__':
app.run(debug=True)
코드 실행:
1
python app.py
출력:
1
2
3
4
* Serving Flask app 'app'
* Debug mode: on
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
브라우저에서 확인:
- 웹 브라우저를 열고
- 주소창에
http://127.0.0.1:5000또는http://localhost:5000입력 - “Hello, Flask! 🎉” 메시지 확인!
코드 분석
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1. Flask 클래스 임포트
from flask import Flask
# 2. Flask 애플리케이션 객체 생성
# __name__은 현재 모듈의 이름 (자동으로 설정됨)
app = Flask(__name__)
# 3. 라우트 데코레이터
# @app.route('/')는 URL 경로를 함수에 매핑
# '/'는 루트 경로 (메인 페이지)
@app.route('/')
def home():
"""
이 함수는 사용자가 '/' 경로로 접속하면 실행됩니다.
반환값은 HTTP 응답으로 전송됩니다.
"""
return "Hello, Flask! 🎉"
# 4. 개발 서버 실행
# 직접 실행할 때만 서버 시작 (import 시에는 실행 안 됨)
if __name__ == '__main__':
app.run(debug=True) # debug=True: 코드 변경 시 자동 재시작
여러 페이지 만들기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# app.py - 여러 페이지가 있는 Flask 앱
from flask import Flask
app = Flask(__name__)
# 메인 페이지
@app.route('/')
def home():
return """
<h1>환영합니다! 🏠</h1>
<p>Flask 학습 첫 날입니다.</p>
<ul>
<li><a href="/about">소개</a></li>
<li><a href="/contact">연락처</a></li>
</ul>
"""
# 소개 페이지
@app.route('/about')
def about():
return """
<h1>소개 📝</h1>
<p>Python Flask 100일 챌린지 Day 81입니다.</p>
<a href="/">홈으로 돌아가기</a>
"""
# 연락처 페이지
@app.route('/contact')
def contact():
return """
<h1>연락처 📧</h1>
<p>Email: [email protected]</p>
<a href="/">홈으로 돌아가기</a>
"""
if __name__ == '__main__':
app.run(debug=True)
테스트:
http://localhost:5000/- 메인 페이지http://localhost:5000/about- 소개 페이지http://localhost:5000/contact- 연락처 페이지
🎯 학습 목표 4: Flask 개발 서버 실행과 디버그 모드
개발 서버 옵션
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# app.py
if __name__ == '__main__':
# 기본 실행
app.run()
# 옵션 1: 디버그 모드 (개발 중 필수!)
app.run(debug=True)
# 옵션 2: 호스트와 포트 지정
app.run(host='0.0.0.0', port=5000)
# 옵션 3: 모든 옵션 조합
app.run(
host='0.0.0.0', # 외부 접속 허용
port=8080, # 포트 변경
debug=True # 디버그 모드
)
디버그 모드의 장점
1
2
3
4
5
6
7
8
9
10
11
12
# debug=True일 때:
✅ 1. 자동 재시작
코드를 수정하고 저장하면 서버가 자동으로 재시작됩니다.
✅ 2. 상세한 에러 메시지
에러 발생 시 브라우저에 상세한 오류 정보가 표시됩니다.
✅ 3. 대화형 디버거
에러 발생 지점에서 Python 코드를 실행할 수 있습니다.
⚠️ 주의: 실제 서비스에서는 debug=False로 설정해야 합니다!
실습: 에러 처리하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# app.py - 에러 페이지 커스터마이징
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return "홈 페이지입니다."
# 404 에러 핸들러 (페이지를 찾을 수 없을 때)
@app.errorhandler(404)
def page_not_found(error):
return """
<h1>404 - 페이지를 찾을 수 없습니다 😢</h1>
<p>요청하신 페이지가 존재하지 않습니다.</p>
<a href="/">홈으로 돌아가기</a>
""", 404
# 500 에러 핸들러 (서버 내부 오류)
@app.errorhandler(500)
def internal_error(error):
return """
<h1>500 - 서버 오류입니다 😱</h1>
<p>죄송합니다. 서버에 문제가 발생했습니다.</p>
<a href="/">홈으로 돌아가기</a>
""", 500
if __name__ == '__main__':
app.run(debug=True)
테스트:
- 존재하지 않는 페이지 접속:
http://localhost:5000/nonexistent - 커스텀 404 페이지 확인
💻 실전 예제
예제 1: 동적 인사말 페이지
문제: 사용자 이름을 URL에서 받아 개인화된 인사말을 출력하는 페이지를 만드세요.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return """
<h1>이름 인사 서비스</h1>
<p>URL 끝에 당신의 이름을 입력하세요!</p>
<p>예: /hello/철수</p>
"""
# 동적 라우트: <name> 부분이 변수가 됩니다
@app.route('/hello/<name>')
def hello(name):
return f"""
<h1>안녕하세요, {name}님! 👋</h1>
<p>Flask에 오신 것을 환영합니다!</p>
<a href="/">처음으로</a>
"""
if __name__ == '__main__':
app.run(debug=True)
실행 결과:
http://localhost:5000/hello/철수→ “안녕하세요, 철수님! 👋”http://localhost:5000/hello/영희→ “안녕하세요, 영희님! 👋”
예제 2: 간단한 계산기 API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# app.py - RESTful API 맛보기
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return """
<h1>계산기 API</h1>
<p>사용법:</p>
<ul>
<li>/add/5/3 - 더하기</li>
<li>/subtract/10/4 - 빼기</li>
<li>/multiply/6/7 - 곱하기</li>
<li>/divide/20/4 - 나누기</li>
</ul>
"""
@app.route('/add/<int:a>/<int:b>')
def add(a, b):
result = a + b
return f"""
<h2>더하기 결과</h2>
<p>{a} + {b} = <strong>{result}</strong></p>
<a href="/">처음으로</a>
"""
@app.route('/subtract/<int:a>/<int:b>')
def subtract(a, b):
result = a - b
return f"<h2>{a} - {b} = {result}</h2><a href='/'>처음으로</a>"
@app.route('/multiply/<int:a>/<int:b>')
def multiply(a, b):
result = a * b
return f"<h2>{a} × {b} = {result}</h2><a href='/'>처음으로</a>"
@app.route('/divide/<int:a>/<int:b>')
def divide(a, b):
if b == 0:
return "<h2>에러: 0으로 나눌 수 없습니다!</h2><a href='/'>처음으로</a>"
result = a / b
return f"<h2>{a} ÷ {b} = {result:.2f}</h2><a href='/'>처음으로</a>"
if __name__ == '__main__':
app.run(debug=True)
테스트:
http://localhost:5000/add/10/5→ “10 + 5 = 15”http://localhost:5000/divide/20/4→ “20 ÷ 4 = 5.00”
🎓 실무 활용
활용 1: 개인 포트폴리오 사이트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# portfolio.py
from flask import Flask
from datetime import datetime
app = Flask(__name__)
@app.route('/')
def home():
return """
<html>
<head>
<title>내 포트폴리오</title>
<style>
body { font-family: Arial; max-width: 800px; margin: 50px auto; }
h1 { color: #333; }
nav { margin: 20px 0; }
nav a { margin-right: 15px; text-decoration: none; }
</style>
</head>
<body>
<h1>홍길동의 포트폴리오</h1>
<nav>
<a href="/about">소개</a>
<a href="/projects">프로젝트</a>
<a href="/skills">기술 스택</a>
</nav>
<p>안녕하세요! Python 개발자 홍길동입니다.</p>
</body>
</html>
"""
@app.route('/projects')
def projects():
projects_list = [
"날씨 크롤러",
"데이터 분석 대시보드",
"REST API 서버"
]
html = "<h1>프로젝트</h1><ul>"
for project in projects_list:
html += f"<li>{project}</li>"
html += "</ul><a href='/'>홈으로</a>"
return html
if __name__ == '__main__':
app.run(debug=True)
활용 2: 서버 상태 모니터링
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# monitor.py
from flask import Flask
import psutil # pip install psutil
from datetime import datetime
app = Flask(__name__)
@app.route('/')
def home():
return """
<h1>서버 모니터링 대시보드</h1>
<ul>
<li><a href="/status">시스템 상태</a></li>
<li><a href="/time">현재 시간</a></li>
</ul>
"""
@app.route('/status')
def status():
cpu_percent = psutil.cpu_percent(interval=1)
memory = psutil.virtual_memory()
return f"""
<h1>시스템 상태 📊</h1>
<ul>
<li>CPU 사용률: {cpu_percent}%</li>
<li>메모리 사용률: {memory.percent}%</li>
<li>사용 가능한 메모리: {memory.available / (1024**3):.2f} GB</li>
</ul>
<a href="/">홈으로</a>
"""
@app.route('/time')
def current_time():
now = datetime.now()
return f"""
<h1>현재 시간 ⏰</h1>
<p>{now.strftime('%Y년 %m월 %d일 %H:%M:%S')}</p>
<a href="/">홈으로</a>
"""
if __name__ == '__main__':
app.run(debug=True)
⚠️ 주의사항
1. 디버그 모드는 개발 환경에서만!
1
2
3
4
5
6
7
8
9
# ❌ 위험: 실제 서비스에서 debug=True
app.run(debug=True) # 해커가 코드를 실행할 수 있음!
# ✅ 안전: 실제 서비스
app.run(debug=False)
# ✅ 더 좋은 방법: 환경 변수 사용
import os
app.run(debug=os.getenv('FLASK_DEBUG', 'False') == 'True')
2. 가상 환경 활성화 확인
1
2
3
4
5
6
7
# ❌ 잘못됨: 가상 환경 없이 설치
pip install flask
# ✅ 올바름: 가상 환경 활성화 후 설치
source venv/bin/activate # Mac/Linux
venv\Scripts\activate # Windows
pip install flask
3. name 체크의 중요성
1
2
3
4
5
6
# ✅ 올바름: 직접 실행 시에만 서버 시작
if __name__ == '__main__':
app.run()
# ❌ 잘못됨: import 시에도 서버가 시작됨
app.run()
🔧 트러블슈팅
문제 1: “Address already in use” 에러
증상:
1
OSError: [Errno 48] Address already in use
원인: 포트 5000이 이미 사용 중
해결:
1
2
3
4
5
6
7
8
9
# 방법 1: 다른 포트 사용
app.run(port=8080)
# 방법 2: 이전 프로세스 종료 (Mac/Linux)
# lsof -ti:5000 | xargs kill -9
# 방법 3: 이전 프로세스 종료 (Windows)
# netstat -ano | findstr :5000
# taskkill /PID [프로세스ID] /F
문제 2: 코드 수정이 반영되지 않음
증상: 코드를 수정했는데 브라우저에 변경사항이 보이지 않음
원인:
- 디버그 모드가 꺼져 있음
- 브라우저 캐시
해결:
1
2
3
4
5
6
# 1. 디버그 모드 활성화
app.run(debug=True)
# 2. 브라우저 강력 새로고침
# Windows: Ctrl + F5
# Mac: Cmd + Shift + R
문제 3: Flask를 찾을 수 없음
증상:
1
ModuleNotFoundError: No module named 'flask'
원인: Flask가 설치되지 않았거나 가상 환경이 활성화되지 않음
해결:
1
2
3
4
5
6
7
8
9
# 1. 가상 환경 활성화 확인
which python # Mac/Linux
where python # Windows
# 2. Flask 설치
pip install flask
# 3. 설치 확인
pip list | grep -i flask
🧪 연습 문제
문제 1: 자기소개 웹사이트 만들기
다음 요구사항을 만족하는 Flask 애플리케이션을 만드세요:
/: 이름과 간단한 소개/hobby: 취미 목록/contact: 연락처 정보
💡 힌트
- 각 경로마다
@app.route()데코레이터 사용 - HTML 문자열로 리스트를 만들 때
<ul><li>태그 사용
✅ 정답
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return """
<h1>홍길동입니다</h1>
<p>Python을 공부하는 개발자입니다.</p>
<nav>
<a href="/hobby">취미</a> |
<a href="/contact">연락처</a>
</nav>
"""
@app.route('/hobby')
def hobby():
return """
<h1>내 취미</h1>
<ul>
<li>코딩</li>
<li>독서</li>
<li>여행</li>
</ul>
<a href="/">홈으로</a>
"""
@app.route('/contact')
def contact():
return """
<h1>연락처</h1>
<p>Email: [email protected]</p>
<p>GitHub: github.com/hong</p>
<a href="/">홈으로</a>
"""
if __name__ == '__main__':
app.run(debug=True)
문제 2: 나이 계산기
URL에서 태어난 년도를 받아 나이를 계산하는 Flask 앱을 만드세요.
/age/1990접속 시 “당신은 34살입니다” 출력
💡 힌트
- 동적 라우트:
@app.route('/age/<int:birth_year>') - 현재 년도:
from datetime import datetime사용
✅ 정답
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from flask import Flask
from datetime import datetime
app = Flask(__name__)
@app.route('/')
def home():
return """
<h1>나이 계산기</h1>
<p>URL 끝에 태어난 년도를 입력하세요</p>
<p>예: /age/1990</p>
"""
@app.route('/age/<int:birth_year>')
def calculate_age(birth_year):
current_year = datetime.now().year
age = current_year - birth_year
return f"""
<h1>나이 계산 결과</h1>
<p>태어난 년도: {birth_year}</p>
<p>현재 년도: {current_year}</p>
<p>당신은 <strong>{age}살</strong>입니다!</p>
<a href="/">다시 계산하기</a>
"""
if __name__ == '__main__':
app.run(debug=True)
📝 요약
이번 Day 81에서 학습한 내용:
- 웹 개발의 기초: 클라이언트-서버 모델, HTTP 요청/응답의 이해
- Flask 시작: 가상 환경 설정, Flask 설치, 프로젝트 구조
- 첫 Flask 앱:
@app.route()데코레이터로 라우트 정의하기 - 개발 서버: 디버그 모드, 에러 핸들링, 동적 라우트
핵심 코드:
1
2
3
4
5
6
7
8
9
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return "Hello, Flask!"
if __name__ == '__main__':
app.run(debug=True)
🔗 관련 자료
📚 다음 학습
Day 82: 라우팅과 URL 처리 ⭐⭐⭐⭐
내일은 URL 패턴 매칭, HTTP 메서드(GET, POST), URL 빌더 등 Flask 라우팅을 깊이 있게 배웁니다!
“모든 위대한 웹사이트는 첫 Flask 앱에서 시작됩니다!” 🚀
Day 81/100 Phase 9: 웹 개발 입문 #100DaysOfPython
