- Flask
- flask를 사용해 기본적인 앱 작성하기
- Example : Coffee Shop Menu API 구축
- 과제 : CRUD(Create, Read, Update, Delete) 구현하기
Flask는 Python 기반 마이크로 웹 프레임워크이다. Django 같은 프레임워크라고 생각하면 좋다. 굉장히 가볍고 작은 프로젝트에 효율적이다.
flask를 설치하기 전에, 먼저 가상환경을 세팅하고자 한다. 다양한 모듈들을 한 환경에 설치해 관리하면 프로젝트끼리 상충되는 버전이 있을수도 있고 이래저래 귀찮은 일이 생길 수 있기 때문에 각 프로젝트마다 가상환경을 따로 관리하는 것이 편하다.
pip install virtualenv
cmd창을 열어 위 virtualenv를 다운로드 해주고 원하는 폴더에서 가상환경을 작동시킨다
virtualenv "가상환경이름"
source "가상환경이름"/bin/activate
위 명령어 역시 cmd창에서 작동시키면 이제 가상환경이 작동된 상태이다.
pip install flask
설치가 완료되었다. 이제 python파일을 통해 flask를 이용할 수 있다.
from flask import Flask # flask 모듈로부터 Flask클래스를 불러온다.
app = Flask(__name__)
@app.route('/') # @ -> 데코레이터 #'/' 이 주소를 요청받으면 밑의 함수를 실행시킨다는 의미
def hello_flask():
return "Hello World!"
if __name__ == '__main__':
app.run() # app이 module로서가 아니라 직접 실행될때 실행하라는 의미
위 코드까지 작성한 후 다시 cmd창에서
flaks run
이라고 실행하면
Running on http://127.0.0.1:5000/
이라는 문구가 출력되는 것을 확인할 수 있다. 위 주소를 방문하게 되면 Hello World! 라고 적힌 페이지가 열리게 된다. 그렇다면 위 페이지는 어떤 방식으로 작동하게 된 것일까?
Web은 Client와 Server 사이의 소통이다. 웹의 동작방식은 다음과 같다.
1. Client가 Server에 정보를 요청한다. (HTTP Request) 2. Server는 요청받은 정보에 대한 처리를 진행한다. 3. Server가 Client에게 요청에 대해 응답한다. (HTTP Responce)
Client로부터 어떤 정보를 받았을 때 무슨 응답을 해줄지 결정해야 하는데 이를 돕는 것이 Flask와 Django이다.
(URL URI)
(get, post, put 등등.. -> Method)
Example. ->
POST/shoes는 자원에 새로운 정보를 생성한다.
GET/shoes 는 DB에서 shoes가 있는지 확인 후 해당 자원 반환
(서버 입장에서) 아이템을 GET하기 위해서 POST를 진행할 필요가 없다.
from flask import Flask, jsonify, request
# jsonify: dict을 js에서 사용하는 저장방식으로 바꾸어줌.
# request: HTTP Request를 다루는 모듈
app = Flask(__name__)
menus = [
{"id":1, "name":"Espresso", "price":3800},
{"id":2, "name":"Americano", "price":4100},
{"id":3, "name":"CafeLatte", "price":4600},
]
@app.route('/') # @ -> 데코레이터 #'/' 이 주소를 요청받으면 밑의 함수를 실행시킨다는 의미
def hello_flask():
return "Hello World!"
# GET /menus # 자료를 가지고 올 때 사용
@app.route('/menus') # @app.route('주소', methods=['GET']) <- 기본형
def get_menus():
return jsonify({"menus" : menus}) # jsonify를 사용해서 dict을 바꿔준다.
# POST /menus # 자료를 자원에 추가할 때 사용
@app.route('/menus', methods=['POST'])
def create_menu(): # request는 JSON이라고 가정
# 전달받은 자료를 menus 자원에 추가
request_data = request.get_json() # request_data -> dict형태 ({'name' : ..., 'price' : ...})
new_menu = {
'id' : 4,
'name' : request_data['name'],
'price' : request_data['price'],
}
menus.append(new_menu)
return jsonify(new_menu)
if __name__ == '__main__':
app.run() # app이 module로서가 아니라 직접 실행될때 실행하라는 의미
위 코드를 작성한 후, 위 주소값에 menus를 붙이면 GET 메소드가 실행된 것을 확인할 수 있다.
Running on http://127.0.0.1:5000/menus
POST 메소드는 일반적인 웹 브라우저로 테스트하기에는 적절치 않다. 따라서 다른 프로그램의 도움을 받는데 보통 사용되는 툴은 POSTMAN이다.
https://www.postman.com/downloads/
위 주소를 통해 POSTMAN을 다운로드할 수 있다.
GET Method를 호출했을 때
POST Method를 호출하고 다시 GET Method를 호출했을 때
PUT Method를 호출했을 때(id=2)
DELETE Method를 호출했을 때(id=3)
메뉴 관리 CRUD 구현하기
@app.route('/<name>') # URL에 <>를 붙임으로서 이를 함수의 인자로 대입할 수 있습니다. def my_view_func(name): return name
Solution
from flask import Flask, jsonify, request
app = Flask(__name__)
menus = [
{"id":1, "name":"Espresso", "price": 3800},
{"id":2, "name":"Americano", "price": 4300},
{"id":3, "name":"Caffe Latte", "price": 5000},
]
@app.route('/')
def hello_flask():
return "Hello World!"
# GET /menus | 자료를 가지고 온다
@app.route('/menus')
def get_menus():
return jsonify({"menus": menus})
# POST /menus | 자료를 자원에 추가한다
@app.route('/menus', methods = ['POST'])
def create_menu():
# 전달받은 자료를 menus 자원에 추가
request_data = request.get_json()
new_menu = {
"id": 4,
"name": request_data['name'],
"price": request_data['price'],
}
menus.append(new_menu)
return jsonify(new_menu)
# UPDATE by PUT
@app.route('/menus/<int:id>', methods = ['PUT'])
def update_menu(id):
request_data = request.get_json()
for i in menus:
if i['id'] == id:
i["name"] = request_data['name']
i["price"] = request_data['price']
return jsonify(menus)
# DELETE by DELETE
@app.route('/menus/<int:id>', methods = ['DELETE'])
def delete_menu(id):
for i in menus:
if i['id'] == id:
menus.remove(i)
return jsonify(menus)
if __name__ == '__main__':
app.run()
# POST /menus | 자료를 자원에 추가한다
@app.route('/menus', methods = ['POST'])
def create_menu():
# 전달받은 자료를 menus 자원에 추가
request_data = request.get_json()
new_menu = {
"id": len(menus)+1, # post요청마다 길이보다 +1 높은 번호를 부여한다.
"name": request_data['name'],
"price": request_data['price'],
}
menus.append(new_menu)
return jsonify(new_menu)
from flask import Flask, jsonify, request
app = Flask(__name__)
menus = [
{"id":1, "name":"Espresso", "price": 3800},
{"id":2, "name":"Americano", "price": 4300},
{"id":3, "name":"Caffe Latte", "price": 5000},
]
@app.route('/')
def hello_flask():
return "Hello World!"
# GET /menus
@app.route('/menus')
def get_menus():
return jsonify({"menus": menus})
# POST /menus
@app.route('/menus', methods = ['POST'])
def create_menu():
request_data = request.get_json()
new_menu = {
"id": len(menus)+1,
"name": request_data['name'],
"price": request_data['price'],
}
menus.append(new_menu)
return jsonify(new_menu)
# PUT
@app.route('/menus/<int:id>', methods = ['PUT'])
def update_menu(id):
request_data = request.get_json()
new_menu = {
"id" : id,
"name" : request_data['name'],
"price" : request_data['price']
}
menus[find_index_by_id(menus, id)] = new_menu # # id가 존재한다면 업데이트한다.
return jsonify(menus)
# DELETE
@app.route('/menus/<int:id>', methods = ['DELETE'])
def delete_menu(id):
del_index = find_index_by_id(menus, id) # id가 존재한다면 삭제한다.
del_menu = menus[del_index]
del(menus[del_index])
return del_menu
def find_index_by_id(a, b): # index가 존재할 때 반환하는 코드
for i, item in enumerate(a):
if item['id'] == b:
return i
raise ValueError(f"ID {b} not found in the list")
if __name__ == '__main__':
app.run()