본문 바로가기
국비교육기관/플젝

2차 플젝_Ajax와 Flask 연동

by 밀키스 2021. 6. 27.

21.06.27

 

  • 위와 같은 화면에서 나이, 성별, 효능을 체크한 뒤에 제품 조회 버튼을 누르면 해당 정보를 Flask로 보낸다.
  • 이때 정보를 보낼 때에는 Ajax를 활용한다.
  • Flask는 정보를 받으면 학습된 머신러닝 모델에 의해 답을 도출하고, 해당 값을 다시 Ajax에게 보낸다.
  • Ajax는 통신이 성공하고, 값을 받으면 쿼리 스트링 형식으로 조회 페이지로 이동한다.

 

 


 Flask 

from flask import Flask
from flask import request
import pandas as pd
from flask_cors import CORS
import pickle
app = Flask(__name__)
# 내가 만든 모델을 "test.pkl"이란 파일에 저장, 해당 모델을 불러온다
test = pickle.load(open('test.pkl', 'rb'))
#POST 방식으로 값을 불러올경우 인코딩 과정 없이 받게 해줌
CORS(app)
@app.route("/", methods = ["GET", "POST"])
def connect():
    value="hello"
    if request.method == 'POST':
        train_tes = []
        #POST 형식으로 전송된 값을 value에 저장
        value = dict(request.form)
        #저장된 값을 DataFrame으로 변환한다.
        df = pd.DataFrame(value, index=[0])
        #pickle을 통해 불러온 모델에 불러온 값을 학습시켜 모델 값을 받는다.
        value = str(int(test.predict(df)))
        print(value)
    #학습시킨 값을 return.
    return value
        
if __name__ == "__main__" :
    app.run()

Flask를 활용하는 전체 코드는 위가 전부다. 3등분해서 하나씩 보자.

 

 


from flask import Flask
from flask import request
import pandas as pd
from flask_cors import CORS
import pickle
  • 값을 통신하기 위한 Flask, 값을 받기 위한 request를 import
  • Pandas는 내가 받은 데이터를 DataFrame형식으로 모델에 학습하기 위해서 필요하다.
  • CORSCross-Origin Resource Sharing의 약자로, 다른 Origin과 통신할 때에 나는 에러 중 하나인데, 이에 대한 부분은 좀 더 자세히 알아보자.
  • pickle은 내가 학습시킨 모델을 하나의 파일로서 쓰는 방법이다.
    • 내가 모델을 쓸 때마다 다시 학습시키고 하지 않아도 된다는 거다!!

 

 


app = Flask(__name__)
# 내가 만든 모델을 "test.pkl"이란 파일에 저장, 해당 모델을 불러온다
test = pickle.load(open('test.pkl', 'rb'))
#POST 방식으로 값을 불러올경우 인코딩 과정 없이 받게 해줌
CORS(app)
@app.route("/", methods = ["GET", "POST"])

#=================================================================

if __name__ == "__main__" :
    app.run()
  • 우선 가운데 나온 def 부분은 짜르고 위와 아랫부분만 리뷰
  • app이란 변수에 Flask를 사용하기 위해 할당해주는데, 이때 __name__ 해당 모듈의 이름을 반환한다.
    • 만일 내가 직접 해당 파일을 실행하면 __name____main__을 반환하고, import하는것 처럼 외부에서 불러들여 사용하게 되면 해당 파일의 이름이 출력된다.
    • 때문에 아래에 해당하는 __name__ == "__main__" 이 부분은 해당 파일을 직접 실행했느냐를 묻는 부분이라 생각하면 된다.
  • pickle은 내가 학습시킨모델을 불러오기 위해 사용하였다. test.pkl 이란 파일에 모델을 저장했고, 해당 파일을 불러오기 위해 'rb' 라는 키워드를 사용한 것.
    • pickle을 저장하고, 불러올 때는 바이트 형식으로 이뤄진다.
    • rbread binary의 약자이며, 내가 만일 모델을 저장하고 싶을 때는 wb라는 키워드를 사용하는데, 뜻은 write binary이다.
  • CORS는 내용이 많을것 같으니... 아래에서 다시 다루자
  • @Decorator라 불리며, 간단하기 말하자면 @ 다음에 나오는 대상을 앞, 뒤로 꾸며줄 수 있게 한다.
    • 만일, test라는 이름으로 define했을 때, @test라 하면 그 다음 구문부터 해당 함수에 뭔가 추가할 작업을 입력하는 것.
    • 즉, 위의 코드는 @app 으로 내가 Flask를 할당하고 나서, 계속해서 어떤 작업을 행할건지 이어나가 작성하는 것이다.
    • 딱 이정도까지만 이해하자 어렵다....
  • route안에 첫번째는 경로를 입력하며, 2번째는 내가 통신에 있어 사용할 방식들을 입력하였다.
    • / 는 뭐... 최상위 경로랄까?? 웹 페이지에서 내가 사용하는 기본 주소를 나타낸다. : http://localhost:포트번호/

 

 


def connect():
    value="hello"
    if request.method == 'POST':
        train_tes = []
        #POST 형식으로 전송된 값을 value에 저장
        value = dict(request.form)
        #저장된 값을 DataFrame으로 변환한다.
        df = pd.DataFrame(value, index=[0])
        #pickle을 통해 불러온 모델에 불러온 값을 학습시켜 모델 값을 받는다.
        value = str(int(test.predict(df)))
        print(value)
    #학습시킨 값을 return.
    return value
  • 우선 내가 Ajax로 부터 POST 형식으로 값을 받을 것이다.
  • 여기서 request.method전송 방식을 리턴해주는 구문인데, Ajax가 POST 형식으로 값을 전송하기 때문에, 위와 같이 조건문을 걸어주었을 때, true를 반환할 것이다.
  • 보낸 데이터가 POST 형식일 때, request.form 이란 구문으로 데이터를 받아올 수 있다.
    • GET방식인 경우에는, request.args 로 데이터를 받아올 수 있다.
    • 아래에 Ajax 관해 쓰겠지만 JSON(객체) 형식으로 데이터를 보냈다. 때문에 받자마자 Dictionary로 변환한다.
  • 받은 데이터는 학습시키기 위해서 DataFrame으로 변환해준다.
    • index는 딕셔너리로 DF를 만들 때에, 안의 value값들이 모두 Scalar라서 에러가 발생할 수 있어 줬다.
    • 안주면 "If using all scalar values, you must pass an index" 라는 에러가 난다. 그래서 일단 아무거나 줬다.
    • 만일 저렇게 하기 싫다면 value에 해당하는 값들을 모두 리스트 형식으로 주면 된다.( ex - {1:[2], 3:[4]} )
  • 나는 test라는 변수 안에 pickle을 통해 학습된 모델을 담았다.( 위에서 언급했다.) 해당 모델을 통해 predict 값을 가져온다.
    • 음... 근데 굳이 int형으로 바꾸고 나서 다시 String으로 바꿔준 이유는 기억이 안나는데..... 무튼 좀 독특했던것 중 하나는 int형 데이터를 return이 안되더라. 어... 이건 모르겠다. 나중에 찾자

 

 


위와 같이 작성하여 Ajax를 통해 입력 받은 데이터를 기반으로 내가 만든 모델을 통해 predict 값을 받을 수 있다.

 

 


 Ajax 

var val_test = $('input:checkbox[name=chk1]');
let check_dic = {"나이" : <%=age_t%>};

for (let i = 0; i < val_test.length; i++) {
  if ($(val_test[i]).is(':checked')) {
  	check_dic[$(val_test[i]).val()] = '1';
  } else {
  	check_dic[$(val_test[i]).val()] = '0';
  }
}

$.ajax({
  type : 'post',
  url : 'http://127.0.0.1:5000/',
  data : check_dic,
  dataType : 'json',
  success : function(res) {
  	window.location.href = "page3.jsp?model=" + res;
  },
  error : function() {
  	alert('요청 실패쓰');
  }
})

플라스크와 연동하기 위한 부분, 2개로 나눠 리뷰한다.

 

 


var val_test = $('input:checkbox[name=chk1]');
let check_dic = {
	"나이" : <%=age_t%>
	};
for (let i = 0; i < val_test.length; i++) {
  if ($(val_test[i]).is(':checked')) {
  	check_dic[$(val_test[i]).val()] = '1';
  } else {
  	check_dic[$(val_test[i]).val()] = '0';
  }
}
  • val_test 라는 변수에 타입이 checkbox 인 input 태그 중에서, name 값이 chk1 인걸 전부 담는다.
  • check_dic 이란 이름의 객체를 선언해줬다. 나중에 모델의 학습을 위함. 이때 나이의 경우는 text 타입이라 그냥 바로 입력해줬다.
  • 반복문을 통해 내가 원하는 방식으로 객체를 만들어 나간다.
    • 체크박스를 모두 담았던 val_test의 길이만큼 반복문 실행
    • val_test의 i번째가 체크되었는지 안되었는지는, is(':checked')라는 구문을 사용하면 boolean 형태로 받을 수 있다
    • 체크되면 1, 아니면 0을 준다.
    • check_dic키 값을 val_test의 i번째 값으로 지정한다. 해당 값은 input 태그의 value 값인데, 나는 그 값들을 모두 체크리스트 이름과 동일하게 줬다. ( ex - 피로회복, 눈건강 등등 )
    • 객체에 값을 추가하는 방법 중 하나이다.

 

 


$.ajax({
  type : 'post',
  url : 'http://127.0.0.1:5000/',
  data : check_dic,
  dataType : 'json',
  success : function(res) {
  	window.location.href = "page3.jsp?model=" + res;
  },
  error : function() {
  	alert('요청 실패쓰');
  }
})
  • Ajax의 통신 방법post, 연결한 url은 플라스크로 지정해주며, 보낼 데이터는 내가 만든 객체인 check_dic이다.
  • 객체를 전송하기 때문에 보낼 데이터의 타입json 형태로 지정한다.
  • success는 내가 통신에 성공했을 경우의 동작을 지정해주며, function안의 res 는 내가 return 받은 데이터의 이름이다.
    • 값을 전송 받으면 바로 다음 페이지로 이동하는데 이때 쿼리 스트링 형식으로 model이란 이름과 함께 리턴 받은 데이터를 전송해주었다.
반응형

댓글