[수업 목표]
- Flask 프레임워크를 활용해서 API를 만들 수 있다.
- '화성에 땅사기' API를 만들고 클라이언트에 연결한다.
- '스파르타피디아' API를 만들고 클라이언트와 연결한다.
01. 4주차 오늘 배울 것
1) 오늘 배울 것 이야기- 4주차: Flask, 화성땅공동구매, 스파르타피디아
우리는 컴퓨터가 한 대 잖아요... 그래서 같은 컴퓨터에다 서버도 만들고, 요청도 할 거예요.
즉, 클라이언트 = 서버가 되는 것이죠.
이것을 바로 "로컬 개발환경"이라고 한답니다!
02. Flask 시작하기 - 서버만들기
sparta → projects → prac 폴더에서 시작!
flask 패키지 다운로드
3) Flask 기초: 기본 실행
- Flask 프레임워크: 서버를 구동시켜주는 편한 코드 모음. 서버를 구동하려면 필요한 복잡한 일들을 쉽게 가져다 쓸 수 있습니다
- 프레임워크를 쓰지 않으면 태양초를 빻아서 고추장을 만드는 격! 프레임워크는 3분 요리/소스 세트라고 생각하면 되겠습니다!
파일 이름은 아무렇게나 해도 상관없지만, 통상적으로 flask 서버를 돌리는 파일은 app.py라고 이름 짓습니다!
flask 패키지 쓸 수 있게 해주는 기본 세팅
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'This is Home!'
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)
이걸 넣고 실행하면 local host로 들어가짐!
@app.route('/mypage')
def mypage():
return 'This is Mypage!'
이걸 넣고 실행하면 local host/mypage로 들어가짐!
03. Flask 시작하기 - HTML파일 주기
1) Flask 기초: 기본 폴더구조 - 항상 이렇게 세팅하고 시작!
Flask 서버를 만들 때, 항상,
프로젝트 폴더 안에,
ㄴstatic 폴더 (이미지, css파일을 넣어둡니다)
ㄴtemplates 폴더 (html파일을 넣어둡니다)
ㄴapp.py 파일
우리는 주로 templates만 쓸 것임
@app.route('/')
def home():
return '<button>나는 버튼이다</button>'
return 안에 다가 한없에 html을 할 수는 없다.
템플릿에 html 파일 index.html을 만들어준다.
app.py에 flask 옆에 콤마 render_template라고 써주고
from flask import Flask, render_template
app = Flask(__name__)
아래에 index.html과 연결한다 이런 코드를 써주면
@app.route('/')
def home():
return render_template('index.html')
이런식으로 만들어진다
localhost를 통해서 보여지는 페이지는 서버에서 나한테 준것, 인터넷하고 연결하면 다른 사람들도 볼 수 있다
html 파일을 연 것은 그냥 내 컴퓨터에 있는 파일을 연 것
04. Flask시작하기 - 본격 API 만들기
GET, POST 방식으로 프론트 엔드(html)와 백엔드(app.py에 flask를 이용해 만드는 서버)에서 요청을 서로 주고 받는 것을 할거다.
2주차에는 html 파일에서 jquery의 중 하나인 ajax를 이용하여 데이터를 받는 GET 방식을 이용해보았다.
항상 그랬듯이 jquery쓰려면 링크를 head에 넣어줘야한다.
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
늘 그랬듯이 script를 헤드안에 만들고 그 안에 ajax 기본 코드를 넣어준다 근데 그 기본코드를 함수 안에 넣어준다.
-GET 요청 확인 Ajax 코드
이 코드는 데이터를 요청하러 창구에 갈때 url에 있는 주민등록번호와 같은 의미있는 번호를 가져가준다
그리고 데이터를 잘 전달했으면 console창에 돌아온 데이터를 찍어준다.
<script>
function hey() {
$.ajax({
type: "GET",
url: "/test?title_give=봄날은간다",
data: {},
success: function (response) {
console.log(response)
}
})
}
</script>
body 함수를 실행할 수 있게 해주는 버튼을 만든다
<button onclick="hey()">여기서 버튼 만들면 쉬워</button>
-GET 요청 API 코드
app.py에 넣어준다
1. title_give라는 것을 ajax에서 url로 받아와서
2.title_receive라는 변수에 넣었고 그 변수를 print 해준다.
3.ajax에서 온 데이터는 봄날은 간다이기 때문에 그렇게 찍힌다.
4.그리고 여기 API에서 성공하면 'msg': '이 요청은 GET!' 이라는 데이터를 ajax로 보내주고
5. 콘솔창에 API에서 보낸 데이터가 찍힌다. (msg: "이 요청은 GET! "result: "success")
@app.route('/test', methods=['GET'])
def test_get():
title_receive = request.args.get('title_give')
print(title_receive)
return jsonify({'result':'success', 'msg': '이 요청은 GET!'})
request와 jsonify라는 이름도 맨 첫줄에 넣어준다.
from flask import Flask, render_template, request, jsonify
외워서 쓰는 것 아니지만 어떤 식으로 돌아가는 것인지 이해는 조금 필요하다
-POST 요청확인 Ajax 코드
GET 요청에서는 데이터를 별로 안 가져가지만
기능 특성상 보통 POST 요청이 데이터를 많이 가져간다.
위에 GET 요청 코드를 보면 data부분이 비어있다.
function hey1() {
$.ajax({
type: "POST",
url: "/test",
data: {title_give: '봄날은간다'},
success: function (response) {
console.log(response)
}
})
}
-POST 요청 API 코드
1. title_give라는 것을 ajax에서 data로 받아와서
2.title_receive라는 변수에 넣었고 그 변수를 print 해준다.
3.ajax에서 온 데이터는 봄날은 간다이기 때문에 실행창에 그렇게 찍힌다.
4.그리고 여기 API에서 성공하면 {msg: '이 요청은 POST!', result: 'success'} 이라는 데이터를 ajax로 보내주고
5. 콘솔창에 API에서 보낸 데이터가 찍힌다.{msg: '이 요청은 POST!', result: 'success'}
@app.route('/test', methods=['POST'])
def test_post():
title_receive = request.form['title_give']
print(title_receive)
return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
여기서 줄을 잘 못 바꿨다가 오류가 났다 .
Ajax을 이렇게 바꾸면
success: function (response) {
console.log(response['msg'])
}
콘솔창에 이 요청은 POST! 이것만 뜬다.
05. [화성땅 공동구매] - 프로젝트 세팅
sparta → projects → mars 폴더에서 시작!
templates, static 경로 파일 , app.py 파일, templates 안에 index.html 파일 만듦
flask, pymongo,dnspython 패키지 다운로드
06. [화성땅 공동구매] - 뼈대 준비하기
app.py에 강사님이 만들어 놓은 코드 넣기
index.html에 강사님이 만들어 놓은 코드 넣기
app.py에 강사님 주신 코드를 넣었는데, 줄이 안 맞아져있어서 바로 실행했을 때는 오류가 떴다.
빨간줄이 나타난 곳의 줄을 수정해주고 다시 실행했더니 제대로 실행됐다.
07. [화성땅 공동구매] - POST 연습(주문 저장)
1) API 만들고 사용하기 - 이름, 주소, 평수 저장하기(Create → POST)
1. 요청 정보 : URL= /mars, 요청 방식 = POST
2. 클라(ajax) → 서버(flask) : name, address, size
3. 서버(flask) → 클라(ajax) : 메시지를 보냄 (주문 완료!)
서버 쪽을 먼저 만든다. app.py파일
세가지 데이터가 들어올 수 있게 한다.
name_receive = request.form['name_give']
address_receive = request.form['address_give']
size_receive = request.form['size_give']
받아서 데이터 베이스에 저장할 수 있게 한다.
저장해놓은 dbprac파일 찾아서 열어준다. 참고할 수 있게
doc = {
'name':name_receive,
'address':address_receive,
'size':size_receive
}
db.mars.insert_one(doc)
클라이언트 쪽을 만든다. html 파일
들어오는 데이터에 이름을 정해준다 .
강사님은 ajax가 시작하기 전에 함수 바로 아래에서 정해주었다.
function save_order() {
let name = $('#name').val()
let address = $('#address').val()
let size = $('#size').val()
그 다음 data 자리에서 key:value 짝 맞추어서 받은 데이터 자리를 만든다.
$.ajax({
type: 'POST',
url: '/mars',
data: {
name_give:name,
address_give:address,
size_give:size
},
success: function (response) {
alert(response['msg'])
}
});
이 함수가 성공적으로 끝났을 때 새로고침 해준다.
success: function (response) {
alert(response['msg'])
window.location.reload()
}
새로고침 코드 - ajax에다가 써주는 거다
window.location.reload()
예전에도 여기서 오류가 났었는데 이번에도 오류가 난다.
저번 오류는 mongdb에서 부산집 ip에서 접근 가능하게 설정해놓고 마산집으로 가서 ip가 바뀌면서 접근이 안되어 오류가 났다. 그래서 allow from anywhere로 바꾸어주었다.
하지만 이번에는 이미 allow from anywhere 상태이다.
그렇다면 다른 오류라는 얘기다. 즉문즉답 페이지에서 나와 오류창이 똑같이 뜨면서 같은 질문을 한 사람이 있어서 참고하였다. certifi 패키지를 다운 받고 위에 pymongo 임포트 하는 내용을 아래와 같이 바꾸어주었다.
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://test:sparta@cluster0.nban6ul.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
이유는 인터넷 환경에 따라 보안관련 추가설정을 해주어야 할 때가 있어서 certfi라는 보안관련 패키지를 받아준 것 이다.
혼자 웹페이지를 연습하는데 계속 오류가 났었다. 이유는 app,py에서 POST와 GET 요청을 2개씩 만들어주었는데
함수 이름을 두개 다 같은 것으로 해놓아서 요류가 났다.
09. [스파르타피디아] - 프로젝트 세팅
sparta → projects → movie 폴더에서 시작!
파일 기본 설정 하기
패키지 다운받기
총 6개 Flask, pymongo, dnspython, bs4, certifi,requests
10. [스파르타피디아] - 조각 기능 구현해보기
프로젝트를 하기 전에 프로젝트에 필요한 기술들을 먼저 구현해 본다.
1) 프로젝트 준비 - URL에서 페이지 정보 가져오기 (meta태그 스크래핑)
meta 태그에 대해 알아보기
- 메타 태그는, <head></head> 부분에 들어가는, 눈으로 보이는 것(body) 외에 사이트의 속성을 설명해주는 태그들입니다.
- 예) 구글 검색 시 표시 될 설명문, 사이트 제목, 카톡 공유 시 표시 될 이미지 등
- 우리는 그 중 og:image / og:title / og:description 을 크롤링 할 예정입니다.
크롤링 기본코드
3주차에 크롤링 하면서 써봤다.
import requests
from bs4 import BeautifulSoup
url = 'https://movie.naver.com/movie/bi/mi/basic.naver?code=191597'
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get(url,headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
# 여기에 코딩을 해서 meta tag를 먼저 가져와보겠습니다.
meta property는 검사창에서 요소를 확인해보면
head안에 여러가지로 들어있는것을 알 수 있다.
제목만 크롤링하려고 한다면 저번에 selector를 복사했던 방식과 다른 방식으로 아래와 같이 이름을 우리가 직접 지정해준다.
title = soup.select_one('meta[property="og:title"]')
print(title)
결과는 이렇게 나온다.
<meta content="보스 베이비 2" property="og:title"/>
title = soup.select_one('meta[property="og:title"]')['content']
image = soup.select_one('meta[property="og:image"]')['content']
desc = soup.select_one('meta[property="og:description"]')['content']
보스 베이비 2 https://movie-phinf.pstatic.net/20210622_174/1624324910624JhEq2_JPEG/movie_image.jpg?type=m665_443_2 베이비 주식회사의 레전드 보스 베이비에서 인생 만렙 CEO가 된 ‘테드’.베이비인 줄 알았던 조카 ‘티...
11. [스파르타피디아] - 뼈대 준비하기
app.py에 붙여넣기
index.html에 붙여넣기
12. [스파르타피디아] - POST 연습(포스팅하기)
1. 요청 정보 : URL= /movie, 요청 방식 = POST
2. 클라(ajax) → 서버(flask) : url, star, comment
3. 서버(flask) → 클라(ajax) : 메시지를 보냄 (포스팅 완료!)
flask 코드
movie_post 함수 안에 리뷰로 쓴 데이터들을 받아오도록 써준다.
그 아래에 meta property 가져왔던 것들을 복사 붙여넣기 해준다.
두가지 데이터를 합쳐서 mongodb에 넣는다.
성공하면 msg를 보낸다.
@app.route("/movie", methods=["POST"])
def movie_post():
url_receive = request.form['url_give']
star_receive = request.form['star_give']
comment_receive = request.form['comment_give']
import requests
from bs4 import BeautifulSoup
url = url_receive
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get(url, headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
title = soup.select_one('meta[property="og:title"]')['content']
image = soup.select_one('meta[property="og:image"]')['content']
desc = soup.select_one('meta[property="og:description"]')['content']
doc = {
'star':star_receive,
'comment':comment_receive,
'title':title,
'image':image,
'desc':desc
}
db.reviews.insert_one(doc)
return jsonify({'msg':'기록 완료!'})
강사님은 bs4를 제일 윗 줄에다가 더 해줬다.
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
import requests
from bs4 import BeautifulSoup
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://test:sparta@cluster0.nban6ul.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
teacher didn't write url = url_receive he change the thing in get() to ur_receive
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get(url_receive, headers=headers)
ajax 코드
내가 남긴 리뷰가 POST 기능으로 전달될 수 있도록 data 부분에 이름 지어서 보내준다.
내가 보낸 자료가 성공적으로 전달 됐으면 flask에서 보내는 msg를 띄워준다.
function posting() {
let url = $('#url').val()
let star = $('#star').val()
let comment = $('#comment').val()
$.ajax({
type: 'POST',
url: '/movie',
data: {
url_give:url,
star_give:star,
comment_give:comment
},
success: function (response) {
alert(response['msg'])
}
});
}
13. [스파르타피디아] - GET 연습(보여주기)
1. 요청 정보 : URL= /movie, 요청 방식 = GET
2. 클라(ajax) → 서버(flask) : (없음)
3. 서버(flask) → 클라(ajax) : 전체 영화를 보내주기
서버 에서는 mongodb에서 모든 자료를 받아오고 클라이언트로부터는 받아올게 없다.
그 자료를 'reviews'라는 이름을 지어서 서버에서 클라이언트로 보내준다.
서버 코드
@app.route("/movie", methods=["GET"])
def movie_get():
all_reviews = list(db.reviews.find({}, {'_id': False}))
print(all_reviews)
return jsonify({'reviews': all_reviews})
클라이언트 코드
$(document).ready(function () {
listing();
});
function listing() {
$.ajax({
type: 'GET',
url: '/movie',
data: {},
success: function (response) {
let rows = response['reviews']
for (let i = 0; i < rows.length; i++) {
let comment = rows[i]['comment']
let desc = rows[i]['desc']
let image = rows[i]['image']
let star = rows[i]['star']
let title = rows[i]['title']
let star_image = '⭐'.repeat(star)
let temp_html = `
<div class="col">
<div class="card h-100">
<img src="${image}"
class="card-img-top">
<div class="card-body">
<h5 class="card-title">${title}</h5>
<p class="card-text">${desc}</p>
<p>${star_image}</p>
<p class="mycomment">${comment}</p>
</div>
</div>
</div>
`
$('#cards-box').append(temp_html)
}
}
})
}
window.location.reload()를 처음에 GET Ajax 아래에 넣어주었더니 화면이 계속 껌뻑껌뻑 거렸다.
아마도 그 앞에
$(document).ready(function () {
listing();
});
이 함수를 해놔서 로딩이 완료되면 listing을 띄워라, 그리고 그 listing 함수 아래에 화면을 reload 해라고 해놓아서 계속 무한 반복이 되어서 그런 것 같다.
POST ajax 아래에 window.location.reload()를 붙여놓으면 그런 문제가 없다.
14. 4주차 끝 & 숙제 설명
1주차에 완성한 팬명록을 완성해주세요!
두 가지 기능을 수행해야 합니다. 1) 응원 남기기(POST): 정보 입력 후 '응원 남기기' 버튼클릭 시 주문목록에 추가 2) 응원 보기(GET): 페이지 로딩 후 하단 응원 목록이 자동으로 보이기
서버 POST 방식 코드
@app.route("/fan", methods=["POST"])
def support_post():
name_receive = request.form['name_give']
support_receive = request.form['support_give']
print(name_receive, support_receive)
doc = {
'name':name_receive,
'support':support_receive
}
db.supports.insert_one(doc)
return jsonify({'msg':'응원 완료!'})
클라이언트 POST 방식 코드
function posting() {
let support = $('#floatingTextarea2').val()
let name = $('#floatingInput').val()
$.ajax({
type: 'POST',
url: '/fan',
data: {
support_give:support,
name_give:name,
},
success: function (response) {
alert(response['msg'])
window.location.reload()
}
});
}
server GET method code
@app.route("/fan", methods=["GET"])
def support_get():
support_list = list(db.supports.find({}, {'_id': False}))
return jsonify({'supports': support_list})
클라이언트 GET 방식 코드
$(document).ready(function () {
listing();
});
function listing() {
$.ajax({
type: 'GET',
url: '/fan',
data: {},
success: function (response) {
console.log(response)
let rows = response['supports']
for (let i = 0; i < rows.length; i++) {
let name = rows[i]['name']
let support = rows[i]['support']
let temp_html = `
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>${support}</p>
<footer class="blockquote-footer">${name}</footer>
</blockquote>
</div>
</div>
`
$('#cards-box').append(temp_html)
}
}
})
}
'개발자 되는 중 > 개발 공부' 카테고리의 다른 글
스파르타 코딩 SQL 개발일지 1주차 (복습) (0) | 2022.10.20 |
---|---|
스파르타 코딩 웹 개발 개발일지 5주차 (복습) (0) | 2022.10.17 |
스파르타 코딩 웹개발 개발일지 3주차 (복습) (0) | 2022.10.12 |
스파르타 코딩 웹개발 개발일지 2주차 (복습) (0) | 2022.10.11 |
스파르타 코딩 웹개발 개발일지 1주차 (복습) (0) | 2022.10.04 |