[ AWS 가입하기 및 보안설정하기 ]
AWS 사이트: https://504836820716.signin.aws.amazon.com/console
https://console.aws.amazon.com/console/home
console.aws.amazon.com
▶ IAM
아이디를 생성하면 IAM계정을 사용
IAM은 AWS의 서비스를 안전하게 제어할 수 있는 계정 내의 계정
- AWS 계정을 처음 가입할 때는 루트 계정이라는 하나의 아이디로 생성되는데 이것을 바로 사용하면 굉장히 위험함
- 이유는 바로 루트 계정이 AWS에서 결제와 관련된 모든 접근 권한이 승인되어 있기 때문
- 원래라면 다른 서비스도 마찬가지이지만 AWS는 그 서비스가 굉장히 다양하고 폭넓고 가격도 다양함
- 그래서 루트계정으로 일상적인 작업을 하지 않는것을 AWS가 강력히 권장
- AWS의 가이드라인에 맞춰 IAM계정을 생성하고, 관리하는 것으로 큰 과금을 막고, 해킹당하더라도 적은 피해와 구제받을 수 있는 초석을 갖추자(당하지 않더라도 예방을 철저하게)
보안 자격증명에 들어가 액세스 관리 사용자 그룹에서 권한 정책을 AdministratorAccess으로 하여 사용자 그룹을 만듬
액세스 관리 사용자에서
- 사용자 이름을 입력
- AWS 자격 증명 유형 선택에서 암호-AWS 관리 콘솔 액세스를 선택
- 콘솔 비밀번호를 사용자 지정 비밀 번호로 선택하고 입력
- 비밀번호 재설정 필요에 체크를 해제하고 다음:권한을 클릭
- 생성한 그룹에 체크한 후 다음 클릭
- 태그 추가 항목 바로 다음 클릭
- 검토에서 이름과 그룹을 확인한 후 다음 클릭
- 사용자 생성에 성공하면 링크를 복사후 링크로 들어가면 이름과 비밀번호를 입력하고 로그인
[ 버킷리스트 ]
▶ 프로젝트 세팅
- templates 폴더는 반드시 고정
- app.py는 변경해도 좋지만, 라이브러리 이름과 같은 것을 이름으로 사용하면 안됨
- index.html은 변경해도 좋지만, 첫 페이지는 일반적으로 index.html을 사용
▶ 가상환경 생성, 활성화, 패키지 설치
- 화면 상단 Terminal > New Terminal 을 클릭
- python -m venv venv 입력 후 엔터
- 화면 오른쪽 아래의 파이썬 버전을 선택! venv로 골라주기
- 터미널 오른쪽의 십자버튼을 클릭
- (venv) 라고 뜨면 활성화까지 완료
- pip을 이용하여 패키지 설치. 여러개를 설치할 때는 띄어쓰기로 구분
- pip install flask pymongo dnspython
▶ 뼈대 준비하기
- 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
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"
></script>
<link
href=" https://fonts.googleapis.com/css2?family=Gowun+Dodum&display=swap "
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)
),
url(" https://images.unsplash.com/photo-1601024445121-e5b82f020549?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1189&q=80 ");
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창 띄어두기
▶ POST 연습하기(버킷리스트 기록API, Create → POST)
1. 데이터 명세
- 요청 정보 : URL= /bucket, 요청 방식 = POST
- 클라(fetch) → 서버(flask) : bucket
- 서버(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. 서버부터 만들기
- 데이터베이스 연결
-
더보기from pymongo import MongoClient
client = MongoClient('내 URL')
db = client.dbsparta
-
- bucket 정보를 받아서, 저장
-
더보기@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 정보를 formData에 넣고 보내줌. 저장되면, 새로고침(reload)
-
더보기function save_bucket() {
let bucket = $("#bucket").val();
let formData = new FormData();
formData.append("bucket_give", bucket);
fetch('/bucket', {method: "POST", body: formData,}).then((res) => res.json()).then((data) => {
alert(data["msg"]);
window.location.reload();
});
}
-
5. 완성 확인하기
- 데이터를 입력하고 DB에 잘 들어갔는지 확인
▶ GET 연습하기(버킷리스트 조회 API, Read→ GET)
1. 데이터 명세
- 요청 정보 : URL= /bucket, 요청 방식 = GET
- 클라(fetch) → 서버(flask) : 없음
- 서버(flask) → 클라(fetch) : 전체 버킷을 보여주기
2. 클라이언트와 서버 연결 확인하기
- 서버코드 - app.py
-
더보기@app.route("/bucket", methods=["GET"])
def bucket_get():
return jsonify({'msg': 'GET 연결 완료!'})
-
- 클라이언트코드 - index.html
-
더보기$(document).ready(function () {
show_bucket();
});
function show_bucket() {
fetch('/bucket').then(res => res.json()).then(data => {
console.log(data)
alert(data['msg'])
})
}
-
3. 서버로부터 만들기
- bucket에 버킷리스트를 담아서 내려주기
-
더보기@app.route("/bucket", methods=["GET"])
def bucket_get():
all_buckets = list(db.bucket.find({}, {'_id': False}))
return jsonify({'result': all_buckets})
-
4. 클라이언트 만들기
- 버킷리스트는 리스트 형식임으로 forEach문으로 반복하면서 데이터를 뽑아낸후 제이쿼리로 append, 기존코드 지우기로 empty()사용
-
더보기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)
})
})
}
-
5. 완성 확인하기
- 동작 테스트: 화면을 새로고침 했을 때, 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
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"
></script>
<link
href=" https://fonts.googleapis.com/css2?family=Gowun+Dodum&display=swap "
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)
),
url(" https://images.unsplash.com/photo-1601024445121-e5b82f020549?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1189&q=80 ");
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((res) => res.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>
-
[ 팬명록]
▶ 프로젝트 세팅
- templates 폴더는 반드시 고정
- app.py는 변경해도 좋지만, 라이브러리 이름과 같은 것을 이름으로 사용하면 안됨
- index.html은 변경해도 좋지만, 첫 페이지는 일반적으로 index.html을 사용
▶ 가상환경 생성, 활성화, 패키지 설치
- 화면 상단 Terminal > New Terminal 을 클릭
- python -m venv venv 입력 후 엔터
- 화면 오른쪽 아래의 파이썬 버전을 선택! venv로 골라주기
- 터미널 오른쪽의 십자버튼을 클릭
- (venv) 라고 뜨면 활성화까지 완료
- pip을 이용하여 패키지 설치. 여러개를 설치할 때는 띄어쓰기로 구분
- pip install flask pymongo dnspython
▶ 뼈대 준비하기
- app.py 준비
-
더보기from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route("/guestbook", methods=["POST"])
def guestbook_post():
sample_receive = request.form['sample_give']
print(sample_receive)
return jsonify({'msg': 'POST 연결 완료!'})
@app.route("/guestbook", methods=["GET"])
def guestbook_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
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"
></script>
<title>초미니홈피 - 팬명록</title>
<link
href=" https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@200;300;400;500;600;700;900&display=swap "
rel="stylesheet"
/>
<style>
* {
font-family: "Noto Serif KR", serif;
}
.mypic {
width: 100%;
height: 300px;
background-image: linear-gradient(
0deg,
rgba(0, 0, 0, 0.5),
rgba(0, 0, 0, 0.5)
),
url("https://cdn.topstarnews.net/news/photo/201807/456143_108614_510.jpg");
background-position: center 30%;
background-size: cover;
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.mypost {
width: 95%;
max-width: 500px;
margin: 20px auto 20px auto;
box-shadow: 0px 0px 3px 0px black;
padding: 20px;
}
.mypost > button {
margin-top: 15px;
}
.mycards {
width: 95%;
max-width: 500px;
margin: auto;
}
.mycards > .card {
margin-top: 10px;
margin-bottom: 10px;
}
</style>
<script>
$(document).ready(function () {
set_temp();
show_comment();
});
function set_temp() {
fetch("http://spartacodingclub.shop/sparta_api/weather/seoul").then((res) => res.json()).then((data) => {
console.log(data)
});
}
function save_comment() {
let formData = new FormData();
formData.append("sample_give", "샘플데이터");
fetch('/guestbook', {method: "POST",body: formData,}).then((res) => res.json()).then((data) => {
//console.log(data)
alert(data["msg"]);
});
}
function show_comment() {
fetch('/guestbook').then((res) => res.json()).then((data) => {
alert(data["msg"])
})
}
</script>
</head>
<body>
<div class="mypic">
<h1>십센치(10cm) 팬명록</h1>
<p>현재기온: <span id="temp">36</span>도</p>
</div>
<div class="mypost">
<div class="form-floating mb-3">
<input type="text" class="form-control" id="name" placeholder="url" />
<label for="floatingInput">닉네임</label>
</div>
<div class="form-floating">
<textarea
class="form-control"
placeholder="Leave a comment here"
id="comment"
style="height: 100px"
></textarea>
<label for="floatingTextarea2">응원댓글</label>
</div>
<button onclick="save_comment()" type="button" class="btn btn-dark">
댓글 남기기
</button>
</div>
<div class="mycards" id="comment-list">
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
</div>
</body>
</html>
-
- mongoDB Atlas창 띄어두기
▶ 조각기능. 날씨 API 적용하기
1. OpenAPI를 활용하여 조각기능 구현하기
- 서울 날씨 OpenAPI
- index.html 날씨 API 뼈대 코드
-
더보기$(document).ready(function () {
set_temp();
show_comment();
});
function set_temp() {
fetch("http://spartacodingclub.shop/sparta_api/weather/seoul").then((res) => res.json()).then((data) => {
console.log(data)
});
}
-
2. OpenAPI도 API이므로 6가지 스텝밟아 사용하기
6가지 스텝이란
- 데이터명세
-
더보기1. 요청정보 : URL = "http://spartacodingclub.shop/sparta_api/weather/seoul", 요청방식 = GET2. 클라(fetch) → 서버(OpenAPI) : 없음3. 서버(OpenAPI) → 클라(fetch) : 서울 날씨 정보를 불러옴
-
- 클라이언트와 서버 연결확인
- console.log()로 접속하는 데이터가 잘 오는지 확인
- 서버만들기?
- OpenAPI는 이미 DB가 구축된 서버이기 때문에 가져다가 보여줄 클라이언트만 만들면 됨
- 클라이언트 만들기
-
더보기function set_temp() {
fetch("http://spartacodingclub.shop/sparta_api/weather/seoul").then((res) => res.json()).then((data) => {
let temp = data['temp']
$("#temp").text(temp)
})
-
- 완성 확인하기
- 동작 테스트: 화면을 새로고침 했을 때, 화면에 올바르게 나타나는지 확인
▶ POST 연습하기(응원 게시하기 API, Create → POST)
1. 데이터 명세
- 요청 정보 : URL= /guestbook, 요청 방식 = POST
- 클라(fetch) → 서버(flask) : name, comment
- 서버(flask) → 클라(fetch) : 메시지를 보냄 (응원 완료!)
2. 클라이언트와 서버 연결 확인하기
- 서버코드 - app.py
-
더보기@app.route("/guestbook", methods=["POST"])
def guestbook_post():
sample_receive = request.form['sample_give']
print(sample_receive)
return jsonify({'msg': 'POST 연결 완료!'})
-
- 클라이언트 코드 - index.html
-
더보기function save_comment() {
let formData = new FormData();
formData.append("sample_give", "샘플데이터");
fetch('/guestbook', {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. 서버부터 만들기
- 데이터베이스 연결
-
더보기from pymongo import MongoClient
client = MongoClient('내 URL')
db = client.dbsparta
-
- name, comment 정보를 받아서, 저장
-
더보기@app.route("/guestbook", methods=["POST"])
def guestbook_post():
name_receive = request.form["name_give"]
comment_receive = request.form["comment_give"]
doc = {
'name': name_receive,
'comment': comment_receive
}
db.fan.insert_one(doc)
return jsonify({'msg':'응원 완료!'})
-
4. 클라이언트 만들기
- name, comment 정보를 formData에 넣고 보내줌. 저장되면, 새로고침(reload)
-
더보기function save_comment() {
let name = $("#name").val();
let comment = $("#comment").val();
let formData = new FormData();
formData.append("name_give", name);
formData.append("comment_give", comment);
fetch('/guestbook', {method: "POST",body: formData,}).then((res) => res.json()).then((data) => {
alert(data["msg"]);
window.location.reload();
});
}
-
5. 완성 확인하기
- 데이터를 입력하고 DB에 잘 들어갔는지 확인
▶ GET 연습하기(응원리스트 조회 API, Read→ GET)
1. 데이터 명세
- 요청 정보 : URL= /guestbook, 요청 방식 = GET
- 클라(fetch) → 서버(flask) : 없음
- 서버(flask) → 클라(fetch) : 전체 응원 목록을 보여주기
2. 클라이언트와 서버 연결 확인하기
- 서버코드 - app.py
-
더보기@app.route("/guestbook", methods=["GET"])
def guestbook_get():
return jsonify({'msg': 'GET 연결 완료!'})
-
- 클라이언트코드 - index.html
-
더보기$(document).ready(function () {
set_temp()
show_bucket()
});
function show_comment() {
fetch('/guestbook').then(res => res.json()).then(data => {
console.log(data)
alert(data['msg'])
})
}
-
3. 서버로부터 만들기
- fan에 name, comment를 담아서 내려주기
-
더보기@app.route("/guestbook", methods=["GET"])
def guestbook_get():
all_comments = list(db.fan.find({},{'_id':False}))
return jsonify({'result':all_comments})
-
4. 클라이언트 만들기
- 응원 목록을 forEach문으로 반복하면서 데이터를 뽑아낸후 제이쿼리로 append, 기존코드 지우기로 empty()사용
-
더보기function show_comment() {
fetch('/guestbook').then((res) => res.json()).then((data) => {
let rows = data['result']
$("#comment-list").empty()
rows.forEach((a) => {
let name = a['name']
let comment = a['comment']
let temp_html = `<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>${comment}</p>
<footer class="blockquote-footer">${name}</footer>
</blockquote>
</div>
</div>`
$("#comment-list").append(temp_html)
})
})
}
-
5. 완성 확인하기
- 동작 테스트: 화면을 새로고침 했을 때, 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("/guestbook", methods=["POST"])
def guestbook_post():
name_receive = request.form["name_give"]
comment_receive = request.form["comment_give"]
doc = {
'name': name_receive,
'comment': comment_receive
}
db.fan.insert_one(doc)
return jsonify({'msg':'응원 완료!'})
@app.route("/guestbook", methods=["GET"])
def guestbook_get():
all_comments = list(db.fan.find({},{'_id':False}))
return jsonify({'result':all_comments})
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
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"
></script>
<title>초미니홈피 - 팬명록</title>
<link
href=" https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@200;300;400;500;600;700;900&display=swap "
rel="stylesheet"
/>
<style>
* {
font-family: "Noto Serif KR", serif;
}
.mypic {
width: 100%;
height: 300px;
background-image: linear-gradient(
0deg,
rgba(0, 0, 0, 0.5),
rgba(0, 0, 0, 0.5)
),
url("https://cdn.topstarnews.net/news/photo/201807/456143_108614_510.jpg");
background-position: center 30%;
background-size: cover;
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.mypost {
width: 95%;
max-width: 500px;
margin: 20px auto 20px auto;
box-shadow: 0px 0px 3px 0px black;
padding: 20px;
}
.mypost > button {
margin-top: 15px;
}
.mycards {
width: 95%;
max-width: 500px;
margin: auto;
}
.mycards > .card {
margin-top: 10px;
margin-bottom: 10px;
}
</style>
<script>
$(document).ready(function () {
set_temp();
show_comment();
});
function set_temp() {
fetch("http://spartacodingclub.shop/sparta_api/weather/seoul").then((res) => res.json()).then((data) => {
let temp = data['temp']
$("#temp").text(temp)
})
}
function save_comment() {
let name = $("#name").val();
let comment = $("#comment").val();
let formData = new FormData();
formData.append("name_give", name);
formData.append("comment_give", comment);
fetch('/guestbook', {method: "POST",body: formData,}).then((res) => res.json()).then((data) => {
alert(data["msg"]);
window.location.reload();
});
}
function show_comment() {
fetch('/guestbook').then((res) => res.json()).then((data) => {
let rows = data['result']
$("#comment-list").empty()
rows.forEach((a) => {
let name = a['name']
let comment = a['comment']
let temp_html = `<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>${comment}</p>
<footer class="blockquote-footer">${name}</footer>
</blockquote>
</div>
</div>`
$("#comment-list").append(temp_html)
})
})
}
</script>
</head>
<body>
<div class="mypic">
<h1>십센치(10cm) 팬명록</h1>
<p>현재기온: <span id="temp">36</span>도</p>
</div>
<div class="mypost">
<div class="form-floating mb-3">
<input type="text" class="form-control" id="name" placeholder="url" />
<label for="floatingInput">닉네임</label>
</div>
<div class="form-floating">
<textarea
class="form-control"
placeholder="Leave a comment here"
id="comment"
style="height: 100px"
></textarea>
<label for="floatingTextarea2">응원댓글</label>
</div>
<button onclick="save_comment()" type="button" class="btn btn-dark">
댓글 남기기
</button>
</div>
<div class="mycards" id="comment-list">
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
</div>
</body>
</html>
-
[ og 태그 ]
static 폴더 아래에 이미지 파일을 넣고, 각자 프로젝트 HTML의 <head>~</head> 사이에 아래 내용을 작성하면 og 태그를 개인 프로젝트에 사용할 수 있음
- og:image
- og:title
- og:description
<meta property="og:title" content="내 사이트의 제목" />
<meta property="og:description" content="보고 있는 페이지의 내용 요약" />
<meta property="og:image" content="이미지URL" />
[ 내 프로젝트를 서버에 올리기 ]
▶ 웹서비스 런칭에 필요한 개념
1. 로컬 서버에서 클라우드 서버로
컴퓨터가 한개니깐 서버와 클라이언트를 하나의 컴퓨터에서 동작시켰음
하지만 이젠 내 컴퓨터를 켜놓지 않아도 접근할 수 있는 웹 서비스를 목표
웹 서비스를 런칭하기 위해 클라이언트의 요청에 항상 응답해줄 수 있는 서버에 프로젝트를 실행시켜줄 것임
언제나 요청에 응답하려면
- 컴퓨터가 항상 켜져있고 프로그램이 실행되어 있어야 함
- 모두가 접근할 수 있는 공개 주소인 공개 IP주소(Public IP Address)로 나의 웹 서비스에 접근 할 수 있도록 해야함
서버는 그냥 컴퓨터이기 때문에 외부 접속이 가능하게 설정한 다음에 내 컴퓨터를 서버로 사용할 수도 있음
2. 컴퓨터 구매하기
내 컴퓨터 대신 계속 켜놓을 컴퓨터를 구매해야함 그것을 '서버'라고 부름
우리는 컴퓨터를 직접 사는 것이 아닌 AWS라는 클라우드 서비스에서 컴퓨터를 빌릴 것임
AWS(Amazon Web Service)는 우리가 배포할 수 있도록 컴퓨터를 빌려주는 곳
Amazon이 구축해놓은 데이터센터의 컴퓨터 한개를 빌려서 배포를 하는 것
3. 업로드 하기
마지막으로 만든 코딩 파일들을 업로드하고 실행시켜두면 끝
▶ AWS Elastic Beanstalk
AWS는 컴퓨터를 빌려주는 서비스부터 배포와 관련된 정말 많은 서비스를 제공
그렇지만 배포는 초보자가 하기에 쉽지 않음(신경써야 하는 내용이 많고 복잡하기 때문)
그래서 초보자를 위해서 빠르게 배포할 수 있는 서비스를 제공
그것이 바로 AWS Elastic Beanstalk
엘라스틱 빈스톡의 장점
- AWS에서 제공하는 쉬운 배포 서비스
- 코드를 압축하여 업로드하고, AWS의 다양한 서비스를 알아서 연결해줌
- 배포링크를 통해 쉽게 공유가 가능하고, 코드 업데이트 기능까지 제공해줌
[ AWS Elastic Beanstalk으로 배포하기]
▶ 배포 명령어 모음
- 터미널 준비하기 -
mkdir deploy
cp app.py deploy/application.py
cp -r templates deploy/templates
pip freeze > deploy/requirements.txt
cd deploy
- application.py 세팅하기 -
application = app = Flask(__name__)
app.run()
- 패키지 설치하기 -
pip install awsebcli
- 보안 자격증명 -
eb init
- 초기 설정 -
eb create myweb
- 코드 수정 & 업데이트 -
eb deploy myweb
▶ 배포하기
1. 액세스 키 가져오기
AWS Elastic Beanstalk: https://ap-northeast-2.console.aws.amazon.com/elasticbeanstalk/home?region=ap-northeast-2#/welcome
https://ap-northeast-2.console.aws.amazon.com/elasticbeanstalk/home?region=ap-northeast-2#/welcome
ap-northeast-2.console.aws.amazon.com
내 컴퓨터에서 로그인을 하려면 보안 자격이 필요함
- AWS 콘솔에 들어가 , 오른쪽 위 부분의 계정이름을 클릭
- 보안 자격 증명을 클릭
- 보안 자격 증명에서 액세스 키를 열고, 새 엑세스 키 만들기 클릭
- 액세스 키 보기를 눌러 액세스 키 ID와 보안 액세스 키를 복사하여 보관
2. 터미널 명령어로 준비완료하기
- mkdir deploy: deploy라는 폴더를 하나 만듬
- cp app.py deploy/application.py: app.py라는 파일을 deploy 폴더에 application.py라는 이름으로 바꿔서 복제함
- cp -r templates deploy/templates: templates라는 폴더를 deploy 폴더 안에 통째로 복제함
- pip freeze > deploy/requirements.txt: 내가 pip 명령어로 설치한 라이브러리들의 목록을 deploy 폴더 안에 requirements.txt 파일에 기록함
- cd deploy: deploy 폴더 안으로 들어감(폴더 더블클릭과 똑같은 기능)
3. 약간의 파일 설정 바꿔주기
AWS 공식문서 참조: https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/create-deploy-python-flask.html
Elastic Beanstalk에 Flask 애플리케이션 배포 - AWS Elastic Beanstalk
애플리케이션을 실행하기 전 application.debug = True를 추가하여 오류가 발생하는 경우 디버그 출력을 활성화합니다. 개발할 때는 이렇게 하는 것이 좋지만, 디버그 출력을 통해 애플리케이션의 내
docs.aws.amazon.com
Elastic Beanstalk 배포를 위해 필요한 것이 있음
- application.py ← app.py에서 이름을 바꿔줘야 함
- templates폴더와 index.html
- requirements.txt ← 우리가 설치한 패키지들의 이름이 담긴 txt파일이에요!
- 폴더 안에 venv가 있으면 안됨!
application.py 설정(그대로 파일을 가져다 쓴다면)
- app.py를 application.py로 바꿔줘야 함
- application을 읽을 수 있도록 코드를 바꿔줘야 함
- app.run() 내용을 지움
from flask import Flask, render_template, request, jsonify
application = 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("/guestbook", methods=["POST"])
def guestbook_post():
name_receive = request.form["name_give"]
comment_receive = request.form["comment_give"]
doc = {
'name': name_receive,
'comment': comment_receive
}
db.fan.insert_one(doc)
return jsonify({'msg':'응원 완료!'})
@app.route("/guestbook", methods=["GET"])
def guestbook_get():
all_comments = list(db.fan.find({},{'_id':False}))
return jsonify({'result':all_comments})
if __name__ == '__main__':
app.run()
4. awsebcli 패키지 설치하기
터미널을 여러
pip install awsebcli
을 입력하고 엔터
5. awsebcli로 AWS Elastic Beanstalk 배포하기
- 1. Eb init
- 내 컴퓨터에서 Elastic Veanstalk을 초기 설정을 진행
- 다운로드가 완료되었다면, eb init을 입력하고 엔터
- 아래와 같이 따라 하면 됨
-
더보기Select a default region : 10 (seoul)
AWS Access Key ID [None]: 발급된 액세스 키 ID (복사 붙여넣기)
AWS Secret Access Key [None]: 발급된 비밀 액세스 키 (복사 붙여넣기)
Enter Application Name (default is "deploy") : enter
It appears you are using Python. Is this correct? : Y
Select a platform branch (default is 1) : enter
Do you want use Codecommit? : N
---
Cannot setup CodeCommit because there is no Source Control setup, continuing with initialization
Do you want to set up SSH for your instances? : Y
Select a keypair : [Create new Keypair]
Type a keypair name : enter
Enter passphrase : enter
Enter same passphrase again : enter
- 2. Eb create
- 명령어를 입력해서 배포를 함
- eb create 환경이름을 입력하고 엔터
- 생성까지 몇분 걸림
- 3. 배포 환경 접속하기
- 화면에서 배포주소를 클릭해 내가 배포한 웹 서비스를 확인
- AWS 접속 → AWS 콘솔 연결하기 → Elastic Beanstalk
- 생성한 환경 일므 확인 → OK 표시가 되어있는지 확인
- 4. Eb deploy
- 코드를 수정하고 쉽게 업데이트
- deploy 폴더에서 변경할 코드를 적고 저장
- 터미널을 열고 eb deploy 환경이름을 입력하고 엔터
- 조금 기다리면 적용됨
▶ 주의사항
1. eb create를 할때마다 서버를 구매한다는 사실
Elastic Beanstalk은 eb create 환경이름 명령어를 입력할 때 마다 서버를 구매
- 실수로 잘못 만들었다면, 서버를 여러 개를 빌린 것이 되는 것
- 서버를 한 번에 두 개 이상 구매하고 놔두면, 요금이 발생하게 됨
- 혹시라도 설정이 달라 제대로 배포가 되지 않았다면, create 명령어를 여러 번 입력했다면 꼭! 환경을 종료해주어야 함
2. Elastic Beanstalk 환경 종료하기
Elastic Beanstalk 환경을 종료하면, 배포 종료와 동시에 서버도 반납함
- AWS접속 → AWS 콘솔 접속 → Elastic Veanstalk에 들어감
- 종료하고 싶은 환경의 체크박스를 클릭하고, 오른쪽 위의 작업 환경 종료하기 클릭
- 종료할 환경의 이름을 다시 한번 입력하고 확인
'항해99' 카테고리의 다른 글
JavaScript 문법 종합반 1주차 (0) | 2023.05.22 |
---|---|
JavaScript 문법 뽀개기 (0) | 2023.04.18 |
웹개발 종합반_4주차 (0) | 2023.04.10 |
웹개발 종합반_3주차 (0) | 2023.04.07 |
웹개발 종합반_2주차 (0) | 2023.04.03 |
댓글