# [프로젝트 진행하며]
[버킷리스트 프로젝트] 수행과정에서 유념해야 할 부분은 1) 프로젝트 진행순서와 2) 어떤 내용이 app.py에 들어가고 어떤 내용이 index.html에 들어가는지 3) 언제 console.log(a) / print(a) / window.location.reload() 찍어주는지 체크하는 것이다.
3회독 [버킷리스트 프로젝트]에서는 이 세 가지에 조금 더 유념하며 프로젝트를 진행하려 한다.
[수업 목표]
Flask 프레임워크를 활용해 API를 만들 수 있다
[버킷리스트] 프로젝트를 생성해 API를 만들고 클라이언트에 연결한다
[팬명록] 프로젝트를 생성해 API를 만들고 클라이언트에 연결한다
AWS Elastic Beanstalk으로 직접 만든 웹 서비스를 배포한다
01. 5주차 오늘 배울 것
1) 5주차 : 미니프로젝트 3, 4, 배포까지
02. AWS 가입하기 및 보안설정하기 : 아마존 클라우드
03. 미니프로젝트 [버킷리스트] - 프로젝트 세팅
🔥 sparta → proejcts → 04.bucket 폴더에서 시작!
[프로젝트 세팅 - Flask 폴더 구조 만들기]
# bucket 폴더 구조
prac
|— app.py (서버) 파일 ----- 1 > 새터미널 > (가상환경 생성) python -m venv venv
|— venv ----- 2 > 새터미널 (venv)활성화
----- 3 > 패키지 설정 pip install flask pymongo dnspython
|— templates (Flask의 규칙) 폴더 ----- 4 >
|— index.html (클라이언트 파일) 파일 ----- 5 >
04. [버킷리스트] - 뼈대 준비하기
# [뼈대 코드] 버킷리스트 - app.py
from flask import Flask , render_template , request , jsonify
app = Flask ( __name__ )
@ app . route ( '/' )
def home ():
return render_template ( 'index.html' )
@ app . route ( "/bucket" , methods =[ "POST" ])
def bucket_post ():
sample_receive = request . form [ 'sample_give' ]
print ( sample_receive )
return jsonify ({ 'msg' : 'POST 연결 완료!' })
@ app . route ( "/bucket" , methods =[ "GET" ])
def bucket_get ():
return jsonify ({ 'msg' : 'GET 연결 완료!' })
if __name__ == '__main__' :
app . run ( '0.0.0.0' , port = 5000 , debug = True )
# [뼈대 코드] 버킷리스트 - - index.html
<! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" />
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" />
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" />
< link
rel = "stylesheet"
integrity = "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin = "anonymous"
/>
< script
integrity = "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin = "anonymous"
></ script >
< link
rel = "stylesheet"
/>
< title > 인생 버킷리스트 </ title >
< style >
* {
font-family : "Gowun Dodum" , sans-serif ;
}
.mypic {
width : 100% ;
height : 200px ;
background-image : linear-gradient (
0deg ,
rgba ( 0 , 0 , 0 , 0.5 ),
rgba ( 0 , 0 , 0 , 0.5 )
),
background-position : center ;
background-size : cover ;
color : white ;
display : flex ;
flex-direction : column ;
align-items : center ;
justify-content : center ;
}
.mypic > h1 {
font-size : 30px ;
}
.mybox {
width : 95% ;
max-width : 700px ;
padding : 20px ;
box-shadow : 0px 0px 10px 0px lightblue ;
margin : 20px auto ;
}
.mybucket {
display : flex ;
flex-direction : row ;
align-items : center ;
justify-content : space-between ;
}
.mybucket > input {
width : 70% ;
}
.mybox > li {
display : flex ;
flex-direction : row ;
align-items : center ;
justify-content : center ;
margin-bottom : 10px ;
min-height : 48px ;
}
.mybox > li > h2 {
max-width : 75% ;
font-size : 20px ;
font-weight : 500 ;
margin-right : auto ;
margin-bottom : 0px ;
}
.mybox > li > h2.done {
text-decoration : line-through ;
}
</ style >
< script >
$ ( document ). ready ( function () {
show_bucket ();
});
function show_bucket () {
fetch ( '/bucket' ). then ( res => res . json ()). then ( data => {
console . log ( data )
alert ( data [ "msg" ]);
})
}
function save_bucket () {
let formData = new FormData ();
formData . append ( "sample_give" , "샘플데이터" );
fetch ( '/bucket' , { method : "POST" , body : formData ,}). then (( response ) => response . json ()). then (( data ) => {
alert ( data [ "msg" ]);
window . location . reload ();
});
}
</ script >
</ head >
< body >
< div class = "mypic" >
< h1 > 나의 버킷리스트 </ h1 >
</ div >
< div class = "mybox" >
< div class = "mybucket" >
< input
id = "bucket"
class = "form-control"
type = "text"
placeholder = "이루고 싶은 것을 입력하세요"
/>
< button onclick = " save_bucket () " type = "button" class = "btn btn-outline-primary" > 기록하기 </ button >
</ div >
</ div >
< div class = "mybox" id = "bucket-list" >
< li >
< h2 > ✅ 호주에서 스카이다이빙 하기 </ h2 >
</ li >
</ div >
</ body >
</ html >
# [프로젝트 준비] - mongoDB Atlas 창 띄워두기 : https://cloud.mongodb.com/
05. [버킷리스트] - POST : 버킷리스트 기록
# API 만들고 사용하기 - 버킷리스트 기록 API (Create→POST : 데이터 생성)
1) 데이터 명세
1. 요청 정보 : URL= /bucket , 요청 방식 = POST
2. 클라(fetch) → 서버(flask) : bucket
3. 서버(flask) → 클라(fetch) : 메시지 보냄 (버킷리스트 저장 완료!)
2) 클라이언트와 서버 연결 확인하기
[서버 코드 - app.py ]
@ app . route ( "/bucket" , methods =[ "POST" ])
def bucket_post ():
sample_receive = request . form [ 'sample_give' ]
print ( sample_receive )
return jsonify ({ 'msg' : 'POST 연결 완료!' })
[클라이언트 코드 - index.html ]
function save_bucket() {
let formData = new FormData();
formData.append("sample_give", "샘플데이터");
fetch('/bucket', {method: "POST",body: formData,}).then((response) => response.json()).then((data) => {
alert(data['msg'])
});
}
< button onclick = " save_bucket () " type = "button" class = "btn btn-outline-primary" > 기록하기 </ button >
3) 서버 만들기
- app.py에 데이터베이스 연결
- 일전에 만들어둔 dbprac.py 에서 코드 불러오기
from pymongo import MongoClient
client = MongoClient ( '내 URL' )
db = client .dbsparta
- bucket 정보를 받아서, 저장 : bucket_receive = request.form['bucket_give']
@ app . route ( "/bucket" , methods =[ "POST" ])
def bucket_post ():
bucket_receive = request . form [ 'bucket_give' ]
doc = {
'bucket' : bucket_receive
}
db .bucket. insert_one ( doc )
return jsonify ({ 'msg' : '저장 완료!' })
4) 클라이언트 만들기
- bucket 정보 보내기 : index.html > script 안에 let bucket = $('#bucket').val()
: formData에 데이터 넣고, 보내줌
function save_bucket () {
let bucket = $ ( '#bucket' ). val ()
let formData = new FormData ();
formData . append ( "bucket_give" , bucket );
fetch ( '/bucket' , { method : "POST" , body : formData ,}). then (( response ) => response . json ()). then (( data ) => {
alert ( data [ "msg" ]);
window . location . reload ();
});
}
: window.location.reload() (저장 / 새로고침) 확인
5) 완성 확인하기
- locallhost:5000 데이터 입력 > DB 확인
06. [버킷리스트] - GET (버킷리스트 보여주기)
# API 만들고 사용하기 - 버킷리스트 조회 API (Read→GET : 데이터 조회)
1) 데이터 명세
1. 요청 정보 : URL= /bucket , 요청 방식 = GET
2. 클라(fetch) → 서버(flask) : 없음
3. 서버(flask) → 클라(fetch) : 전체 버킷을 보여주기
2) 클라이언트와 서버 연결 확인하기
[서버 코드 - app.py ]
@ app . route ( "/bucket" , methods =[ "GET" ])
def bucket_get ():
return jsonify ({ 'msg' : 'GET 연결 완료!' })
[클라이언트 코드 - index.html ]
< script >
$ ( document ). ready ( function () {
show_bucket ();
});
function show_bucket () {
fetch ( '/bucket' ). then ( res => res . json ()). then ( data => {
console . log ( data )
alert ( data [ 'msg' ])
})
}
3) 서버 만들기
- [app.py] Bucket 에 버킷리스트 담아서 내려주기
@ app . route ( "/bucket" , methods =[ "GET" ])
def bucket_get ():
all_buckets = list ( db .bucket. find ({},{ '_id' : False }))
return jsonify ({ 'result' : all_buckets })
4) 클라이언트 만들기
- [app.py] 버킷리스트 : 리스트 형식
function show_bucket () {
fetch ( '/bucket' ). then ( res => res . json ()). then ( data => {
let rows = data [ 'result' ]
$ ( '#bucket-list' ). empty ()
rows . forEach (( a ) => {
let bucket = a [ 'bucket' ]
let temp_html = `<li>
<h2>✅ ${ bucket } </h2>
</li>`
$ ( '#bucket-list' ). append ( temp_html )
})
})
}
(1) forEach 문으로 반복하면서 데이터를 뽑아내기!
(2) 가져온 데이터 temp_html로 뼈대에 데이터를 담아 제이쿼리로 append 해주기
(3) (forEach 돌리기 전에) 기존 html 코드들을 지워줄 수 있도록 empty() 사용하기
5) 완성 확인하기
- 동작 테스트: locallhost:5000 화면 [새로고침] > DB에 저장된 리뷰가 화면에 올바르게 나타나는지 확인!
# 완성 코드 확인하기
[완성 코드] app.py - 버킷리스트 서버
from flask import Flask , render_template , request , jsonify
app = Flask ( __name__ )
from pymongo import MongoClient
client = MongoClient ('내 mongoDB URL' )
db = client .dbsparta
@ app . route ( '/' )
def home ():
return render_template ( 'index.html' )
@ app . route ( "/bucket" , methods =[ "POST" ])
def bucket_post ():
bucket_receive = request . form [ 'bucket_give' ]
doc = {
'bucket' : bucket_receive
}
db .bucket. insert_one ( doc )
return jsonify ({ 'msg' : '저장 완료!' })
@ app . route ( "/bucket" , methods =[ "GET" ])
def bucket_get ():
all_buckets = list ( db .bucket. find ({},{ '_id' : False }))
return jsonify ({ 'result' : all_buckets })
if __name__ == '__main__' :
app . run ( '0.0.0.0' , port = 5000 , debug = True )
[완성 코드] index.html - 버킷리스트 클라이언트
<! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" />
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" />
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" />
< link
rel = "stylesheet"
integrity = "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin = "anonymous"
/>
< script
integrity = "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin = "anonymous"
></ script >
< link
rel = "stylesheet"
/>
< title > 인생 버킷리스트 </ title >
< style >
* {
font-family : "Gowun Dodum" , sans-serif ;
}
.mypic {
width : 100% ;
height : 200px ;
background-image : linear-gradient (
0deg ,
rgba ( 0 , 0 , 0 , 0.5 ),
rgba ( 0 , 0 , 0 , 0.5 )
),
background-position : center ;
background-size : cover ;
color : white ;
display : flex ;
flex-direction : column ;
align-items : center ;
justify-content : center ;
}
.mypic > h1 {
font-size : 30px ;
}
.mybox {
width : 95% ;
max-width : 700px ;
padding : 20px ;
box-shadow : 0px 0px 10px 0px lightblue ;
margin : 20px auto ;
}
.mybucket {
display : flex ;
flex-direction : row ;
align-items : center ;
justify-content : space-between ;
}
.mybucket > input {
width : 70% ;
}
.mybox > li {
display : flex ;
flex-direction : row ;
align-items : center ;
justify-content : center ;
margin-bottom : 10px ;
min-height : 48px ;
}
.mybox > li > h2 {
max-width : 75% ;
font-size : 20px ;
font-weight : 500 ;
margin-right : auto ;
margin-bottom : 0px ;
}
.mybox > li > h2.done {
text-decoration : line-through ;
}
</ style >
< script >
$ ( document ). ready ( function () {
show_bucket ();
});
function show_bucket () {
fetch ( '/bucket' ). then ( res => res . json ()). then ( data => {
let rows = data [ 'result' ]
$ ( '#bucket-list' ). empty ()
rows . forEach (( a ) => {
let bucket = a [ 'bucket' ]
let temp_html = `<li>
<h2>✅ ${ bucket } </h2>
</li>`
$ ( '#bucket-list' ). append ( temp_html )
})
})
}
function save_bucket () {
let bucket = $ ( '#bucket' ). val ()
let formData = new FormData ();
formData . append ( "bucket_give" , bucket );
fetch ( '/bucket' , { method : "POST" , body : formData ,}). then (( response ) => response . json ()). then (( data ) => {
alert ( data [ "msg" ]);
window . location . reload ();
});
}
</ script >
</ head >
< body >
< div class = "mypic" >
< h1 > 나의 버킷리스트 </ h1 >
</ div >
< div class = "mybox" >
< div class = "mybucket" >
< input
id = "bucket"
class = "form-control"
type = "text"
placeholder = "이루고 싶은 것을 입력하세요"
/>
< button onclick = " save_bucket () " type = "button" class = "btn btn-outline-primary" > 기록하기 </ button >
</ div >
</ div >
< div class = "mybox" id = "bucket-list" >
< li >
< h2 > ✅ 호주에서 스카이다이빙 하기 </ h2 >
</ li >
</ div >
</ body >
</ html >