Flask RESTful API - POST /stores/create (매장등록)
2019. 7. 2. 22:50ㆍPython/Flask
반응형
POST /stores/create
매장명, 지번주소 또는 도로명 주소정보를 알고 있는경우 Kakao 주소검색 API를 이용하여서 매장의 위치 정보를 저장한다.
Resource URL
http://localhost:5000/stores/create
Request
{
"store_name":"스타벅스 김포장기커낼점",
"abbr_address":"",
"road_address":"경기 김포시 김포한강2로 41",
"phone":"031-986-3530"
}
Response
{
"message":"스타벅스 김포장기커낼점 매장 정보가 등록 되었습니다."
}
소스코드 작성
소스코드 작성은 다음과 같이 작성한다.
- Kakao API 연동을 위한 인터페이스 파일 작성 - C:\istarbucks_api\code\inf\kakao_api.py
- 모델파일작성 - C:\istarbucks_api\code\models\store.py
- 사용자로부터 전달 받은 URL 처리 및 모델 연동을 위한 resource 파일 작성 - C:\istarbucks_api\code\resources\store.py
- app.py 수정 - C:\istarbucks_api\code\app.py
kakao_api.py
Kakao API Local REST API 연동을 통하여 주소에 해당하는 장소정보 검색, 검색어에 해당하는 장소 목록을 조회한다.
from urllib.parse import urlparse from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.support.select import Select from selenium.webdriver.common.keys import Keys import requests import json def find_place(x,y,radius,keyword,page): """ 검색어에 해당하는 장소 목록 조회 param x: 경도(longitude) param y: 위도(latitued) param radius: 반경 param keyword: 장소명 param page: 페이지 :return: result: 검색어에 해당하는 장소 목록 """ if page is None: page = 1 key = "발급받은인증키" # API URL url = "https://dapi.kakao.com/v2/local/search/keyword.json?y={}&x={}&radius={}&query={}&page={}".format(y,x,radius,keyword,page) # API 호출 result = requests.get(urlparse(url).geturl(),headers={"Authorization":"KakaoAK "+ key}) return result.json() def find_address(keyword): """ 검색어에 해당하는 주소 정보 조회 param keyword: 주소 :return: result: 지번주소,도로명주소 정보 """ key = "발급받은인증키" # API URL url = "https://dapi.kakao.com/v2/local/search/address.json?query={}".format(keyword) # API 호출 result = requests.get(urlparse(url).geturl(),headers={"Authorization":"KakaoAK "+ key}) return result.json()
store.py - Model
앞에서 생성한 store table의 맵핑되는 모델 파일을 작성한다. 뒤에 나오는 예제에서는 메소드만 추가해 나갈 것이다.
from db_init import db from geoalchemy2.types import Geometry class StoreModel(db.Model): # 물리 테이블명 __tablename__ = "store" # 컬럼 맵핑 store_id = db.Column(db.Integer, primary_key=True) store_name = db.Column(db.String(50)) abbr_address = db.Column(db.String(100)) road_address = db.Column(db.String(50)) phone = db.Column(db.String(13)) store_url = db.Column(db.String(100)) grade = db.Column(db.Float) lat = db.Column(db.Float) lon = db.Column(db.Float) geo = db.Column(Geometry(geometry_type='POINT')) def __init__(self, store_id, store_name, abbr_address, road_address, phone, store_url, grade, lat, lon, geo): self.store_id = store_id self.store_name = store_name self.abbr_address = abbr_address self.road_address = road_address self.phone = phone self.store_url = store_url self.grade = grade self.lat = lat self.lon = lon self.geo = geo def save(store): """ 매장 정보 저장/수정 :param store: 매장 정보 객체 """ db.session.merge(store) db.session.commit() @classmethod def convert_geom(self,point): """ 반경검색을 위해서 좌표계를 2097로 변환하기 위한 함수 param point: PONT('경도 위도') """ q = 'SELECT ST_Transform(ST_GeomFromText(\'{}\', 4326), 2097)'.format(point) geom = db.session.execute(q).first() return geom[0] def __str__(self): return "[" + str(self.__class__) + "]: " + str(self.__dict__)
store.py - Resource
from flask_restful import Resource, reqparse from flask import jsonify from flask_marshmallow import Marshmallow from models.store import StoreModel from inf.kakao_api import * from models.store import StoreModel """ JSON 처리를 위한 Mashmallow 메타 설정 """ ma = Marshmallow() """ 단일 매장 목록 조회 시 사용할 메타 """ class StoreSchema(ma.Schema): class Meta: # Fields to expose fields = ('store_id', 'store_name','abbr_address','road_address','phone','store_url','grade','lat','lon') """ 매장 목록 조회 시 사용할 메타 """ class StoresSchema(ma.Schema): class Meta: # Fields to expose fields = ('store_id', 'store_name','abbr_address','road_address','phone','store_url','grade','lat','lon','distance') """ POST /stores/create - 매장 등록 """ class StoreRegister(Resource): # 입력 파라미터 설정 parser = reqparse.RequestParser() parser.add_argument('store_name', type=str, required=True, help="This field cannot be blank." ) parser.add_argument('abbr_address', type=str, required=True, help="This field cannot be blank." ) parser.add_argument('road_address', type=str, required=True, help="This field cannot be blank." ) parser.add_argument('phone', type=str, required=True, help="This field cannot be blank." ) def post(self): # Request Parameter를 dictionary 형태로 저장 data = StoreRegister.parser.parse_args() # 매장명 store_name = data['store_name'] # 지번주소 abbr_address = data['abbr_address'] # 도로명주소 road_address = data['road_address'] # 전화번호 phone = data['phone'] # Kakao API를 검색을 통해 위치 정보를 입수한다. response = find_address(road_address) # API 응답값중에 조회 된 데이터 수를 반환해주는데 정상적으로 조회 되는 경우는 1이상이므로 # total_count 값을 체크하여서 저장 여부를 판단한다. result_cnt = response['meta']['total_count'] if result_cnt == 0: return {'message':'주소 정보가 올바르지 않습니다. 다시한번 확인 하여 주십시오.'},404 else: # 기본정보를 입력 받았더라도 API 검색결과 데이터로 다시 설정 하여준다. # documents element data = response['documents'][0] # 지번주소 abbr_address = data['address']['address_name'] # 도로명주소 road_address = data['road_address']['address_name'] # 위도 x = data['x'] # 경도 y = data['y'] # Geometry 정보 설정 point = 'POINT({} {})'.format(x, y) # point 정보를 바로 저장 할 시 우리나라 좌표계와 맞지 않으므로 좌표계를 변환 처리 한다. geo = StoreModel.convert_geom(point) # 매장 정보 저장 StoreModel.save(StoreModel(None,store_name,abbr_address,road_address,phone,None,None,x,y,geo)) return {'message':'{} 매장 정보가 등록 되었습니다.'.format(store_name)},201
app.py
import os import psycopg2 from flask import Flask from flask_restful import Api from flask_sqlalchemy import SQLAlchemy from config import app_config from resources.store import StoreRegister # set_env.bat 에서 설정한 application 이름 설정 app = Flask(os.getenv('FLASK_APP')) # set_env.bat 에서 설정한 FLASK_ENV는 development env_name = os.getenv('FLASK_ENV') """ app_config 는 config.py 에서 정의 app_config 이면 위에서 development를 설정하였기 때문에 config.py 의 Development 클래스의 정보가 설정 되게 된다. """ app.config.from_object(app_config[env_name]) # 데이터 변경사항에 대해 커밋 전후로 알림 여부 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # Query Debug 여부 app.config['SQLALCHEMY_ECHO'] = False """ API Resource 등록 --------------------------------------------------------- POST /stores/create - 매장 등록 PATCH /stores - 벌크 매장 등록 GET /stores/search - 매장목록 조회 GET /stores/<int:store_id> - 매장정보조회 DELETE /stores/<int:store_id> - 매장정보삭제 """ api = Api(app) api.add_resource(StoreRegister, '/stores/create') if __name__ == "__main__": from db_init import db db.init_app(app) app.run(debug=True,port=5000)
테스트
POSTMAN을 이용하여서 테스트를 진행 한다.
아래 그림에서 보면 Body 부분에 입력 파라미터를 설정 하면 된다.
매장등록 결과 DB 조회
반응형
'Python > Flask' 카테고리의 다른 글
Flask RESTful API - GET /stores/search (매장검색) (0) | 2019.07.03 |
---|---|
Flask RESTful API - PATCH /stores (현재 위치 기준 지정한 반경내 모든 매장 정보 등록) (0) | 2019.07.03 |
Flask RESTful API - 서버 환경 설정 (0) | 2019.07.01 |
Flask RESTful API - 매장관리 API URL 및 테이블 설계 (0) | 2019.07.01 |
Flask RESTful API - Hello Flask! (0) | 2019.07.01 |