앞선 3-1과 3-2에서 소개한 함수를 사용해 NUGU Play Builder와 통신하는 서버를 구축했다. 우리는 RESTful API 서버를 구축하는 데에 python flask를 사용했다.
먼저 3-1과 3-2에서 각각 생성한 관광 정보 API를 불러오는 함수와 DB에 접근하는 함수를 import해주었다.
from getEventList import content, action
from dbconnect import predicted_pop
아래 코드는 flask 서버를 구축하기 위해 필요한 메인 요소들을 모아놓은 코드이다.
from flask_restful import Api, Resource
from flask import Flask, jsonify, request
import datetime
app = Flask(__name__)
api = Api(app)
class GetParams(Resource):
def post(self):
data = request.get_json()
location = data['action']['parameters']['location']['value']
ymonth = data['action']['parameters']['ymonth']['value']
mday = data['action']['parameters']['mday']['value']
api_date = makedate(ymonth, mday, has_dash = False)
c = content(location, api_date, api_date)
db_date = makedate(ymonth, mday, has_dash = True)
val = translate_code(str(location))
result_list = action(c)
foot_traffic = predicted_pop(val, str(db_date))
response = make_response(result_list, foot_traffic, one_item = False)
print(response)
return jsonify(response)
class GetParams1(Resource):
def post(self):
data = request.get_json()
location = data['action']['parameters']['location']['value']
ymonth = data['action']['parameters']['ymonth']['value']
mday = data['action']['parameters']['mday']['value']
api_date = makedate(ymonth, mday, has_dash = False)
c = content(location, api_date, api_date)
db_date = makedate(ymonth, mday, has_dash = True)
val = translate_code(str(location))
result_list = action(c)
foot_traffic = predicted_pop(val, str(db_date))
response = make_response(result_list, foot_traffic, one_item = True)
print(response)
return jsonify(response)
api.add_resource(GetParams, '/eventList', '/eventItem2', '/eventItem3',
'/2_1', '/2_2', '/3_1', '/3_2', '/3_3')
api.add_resource(GetParams1, '/eventItem1', '/yes')
if __name__ == '__main__':
app.run(debug=True)
* flask_restful: Flask를 사용해 REST API를 생성하기 위한 모듈
* flask: python으로 작성된 마이크로 웹프레임워크
실제로 request를 받아와 response를 만드는 main building block이다. 우리는 NUGU Play Builder에서 보내는 post request를 처리해야 하기 때문에 post 메소드만을 사용했다.
여기서 관광정보 api에서 가져온 값이 1개인 경우와, 2개 이상인 경우 처리해야 하는 방식이 달라지므로, 같은 기능을 하는 Resource Block을 두 개 생성했다.
class 내부의 코드를 살펴보면, 먼저 get_json()
을 통해 NUGU Play Builder로부터 온 request 정보를 받고, 이 request 내의 값들에 접근해 사용자가 발화한 location
, ymonth
, mday
정보를 각각 저장한다.
ymonth
, mday
, has_dash
값을 makedate
함수에 넣으면, 행사 정보 및 유동인구 정보를 얻기 위한 date 값을 각각 생성해 주고, location
값을 translate_code
함수에 넣어 DB 접근을 할 때 필요한 구 코드로 변환한다.
각각 구한 변수들을 make_response
함수에 넣어 response
값을 얻고, 이를 jsonify
를 이용해 json file로 변환한 후, return해 준다.
api.add_resource
는 생성한 Resource Block을 URL에 따라 route해 준다. NUGU Play Builder에서 보내는/eventList1
과 /yes
URL은 행사 정보가 1개일 때 불러지므로, GetParams1
로, 나머지 URL은 GetParams
로 route해 주었다.
여기서부터는 우리가 직접 정의한 함수들을 설명하겠다.
def makedate(ymonth, mday, has_dash):
now = datetime.datetime.now()
year = now.strftime('%Y')
if len(ymonth) == 1:
ymonth = '0' + ymonth
if len(mday) == 1:
mday = '0' + mday
if has_dash:
date = year +'-'+ ymonth +'-'+ mday
return date
else:
date = year + ymonth + mday
return date
NUGU Play Builder의 request로부터 가져온 ymonth
와 mday
파라미터를 각 함수에 넣을 수 있는 형태로 바꿔주기 위한 makedate
함수를 정의하였다.
이 makedate
함수는 ymonth
, mday
, has_dash
값을 입력값으로 받고, datetime
모듈을 통해 현재 년도를 계산한다. 이 때, ymonth
값과 mday
값이 한자리수일 경우, 앞에 0을 붙여 두자리 수로 만들어 주고, TourAPI에서는 날짜 중간에 대시(-)가 없는 형식을, MySQL에서는 대시(-)가 있는 형식을 요구하므로, has_dash에 따라 date
값을 만들어 반환한다.
NUGU Play Builder에서는 사용자가 발화한 지역구에 따라 location
entity의 값을 request에 넣어 보내주는데, 이 때 TourAPI에서의 지역구 코드와, 생활인구 데이터의 지역구 코드가 다르기 때문에, 이를 변환해주기 위한 함수를 생성했다.
def translate_code(val):
return {
'1': '11680', '2': '11740', '3': '11305', '4': '11500', '5': '11620',
'6': '11215', '7': '11530', '8': '11545', '9': '11350', '10': '11320',
'11': '11230', '12': '11590', '13': '11440', '14': '11410', '15': '11650',
'16': '11200', '17': '11290', '18': '11710', '19': '11470', '20': '11560',
'21': '11170', '22': '11380', '23': '11110', '24': '11140', '25': '11260'
}.get(val)
make_response
함수는 3-1, 3-2에 입력값을 넣고 처리한 결과를 NUGU Play Builder에 다시 보내기 위한 response(응답값)을 만들기 위한 함수이다. 기본적으로 필요한 response를 dictionary형태로 미리 정의한 뒤, 3-1, 3-2에서 정의한 함수에 날짜와 지역구를 넣어 얻은 결과를 output
key에 추가한다.
def make_response(result_list, foot_traffic, one_item):
response = {
"version": "2.0",
"resultCode": "OK",
"output": {
"list": "0"
}
}
if len(result_list) == 0:
return response
elif len(result_list)>0:
response["output"]["list"] = str(len(result_list))
result_output = {}
for index, result in enumerate(result_list, 1):
for key, value in result.items():
if key in ['title', 'place', 'cost', 'time']:
if one_item:
result_output[key + str(index)] = value[0]
else:
result_output[key + str(index)] = value
response["output"] = dict(response["output"], **result_output)
response["output"]["traffic"] = str(foot_traffic)
return response