메뉴 닫기

Flask에서 RestAPI 구현을 간단하게, Flask-Restless로 더 간단하게

RestAPI로 sqlite 데이타베이스 테이블 User를 다루어보자.

Flask와 Flask-Restless로 RestAPI를 구현하고
SQLAlchemy로 테이블 User를 모델로 정의하여 다룬다.

테이블 User를 모델로 정의한다는 것은 SQLAlchemy를 이용해 class로 작성한다는 것을 말한다.
User를 모델로 정의한 코드이다.

app = Flask(__name__)
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20))
    regDate = db.Column(db.Date)
    email = db.Column(db.String(50))

    def __init__(self, name, regDate, email):
        self.name = name
        self.regDate = datetime.datetime.strptime(regDate, "%d%m%Y").date()
        self.email = email

먼저 Flask 개발환경 구성을 위해서 설치부터 하자.

$ cat requirement.txt
Flask
Flask-Restless
Flask-SQLAlchemy

$ sudo pip install -r requirement.txt

Flask와 Flask-SQLAlchemy로 RestAPI를 구성하면 웹서버에 들어오는 요청을 정의하여 @app.route에 등록하고 처리하는 부분을 정의해야 한다.

@app.route('/user/', methods = ['GET'])
def index():
    return jsonify({'users': User.query.all()})

@app.route('/user/<int:id>/')
def get_user(id):
    return jsonify({'user': User.query.get(id)})

@app.route('/user/', methods = ['POST'])
def create_user():
    if not request.json or not 'name' in request.json:
        abort(400)
    user = User(request.json.name, request.json.get('regDate', ''), request.json.get('email',''))
    db.session.add(user)
    db.session.commit()
    return jsonify( { 'user': user } ), 201

@app.route('/user/<int:id>', methods = ['DELETE'])
def delete_user(id):
    db.session.delete(Users.query.get(id))
    db.session.commit()
    return jsonify( { 'result': True } )

@app.route('/user/<int:id>', methods = ['PUT'])
def update_user(id):
    user = User.query.get(id)
    user.name = request.json.get('name', user.name)
    user.regDate = request.json.get('regDate',user.name)
    user.email = request.json.get('email', user.email)
    db.session.commit()
    return jsonify( { 'user': user } )

위의 설명한 것을 한번에 정리하면 아래와 같다.

$cat restapi_simple-0.1.py

from flask import Flask, jsonify, abort, request
from flask.ext.sqlalchemy import SQLAlchemy
import os

app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))

SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.sqlite')
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20))
    regDate = db.Column(db.Date)
    email = db.Column(db.String(50))

    def __init__(self, name, regDate, email):
        self.name = name
        self.regDate = datetime.datetime.strptime(regDate, "%d%m%Y").date()
        self.email = email

@app.route('/user/', methods = ['GET'])
def index():
    return jsonify({'users': User.query.all()})

@app.route('/user/<int:id>/')
def get_user(id):
    return jsonify({'user': User.query.get(id)})

@app.route('/user/', methods = ['POST'])
def create_user():
    if not request.json or not 'name' in request.json:
        abort(400)
    user = User(request.json.name, request.json.get('regDate', ''), request.json.get('email',''))
    db.session.add(user)
    db.session.commit()
    return jsonify( { 'user': user } ), 201

@app.route('/user/<int:id>', methods = ['DELETE'])
def delete_user(id):
    db.session.delete(Users.query.get(id))
    db.session.commit()
    return jsonify( { 'result': True } )

@app.route('/user/<int:id>', methods = ['PUT'])
def update_user(id):
    user = User.query.get(id)
    user.name = request.json.get('name', user.name)
    user.regDate = request.json.get('regDate',user.name)
    user.email = request.json.get('email', user.email)
    db.session.commit()
    return jsonify( { 'user': user } )



if __name__ == '__main__':
    db.create_all()
        app.run()

Flask로 RestAPI를 정의하는 대신에 Flask-RestLess를 통해 정의 해보았다.
@app.route 부분이 사라지고 APIManager로 대체한다.

# Create the Flask-Restless API manager.
manager = APIManager(app, flask_sqlalchemy_db=db)

# Create API endpoints, which will be available at /api/<tablename> by
# default. Allowed HTTP methods can be specified as well.
manager.create_api(User, methods=['GET', 'POST', 'DELETE'])

한 파일로 정리하면 다음과 같다.

$cat restapi_simple-0.2.py

from flask import Flask, jsonify, abort, request
from flask.ext.restless import APIManager
from flask.ext.sqlalchemy import SQLAlchemy
import os

basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.sqlite')
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')

app = Flask(__name__)
db = SQLAlchemy(app)



class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20))
    regDate = db.Column(db.Date)
    email = db.Column(db.String(50))

    def __init__(self, name, regDate, email):
        self.name = name
        self.regDate = datetime.datetime.strptime(regDate, "%d%m%Y").date()
        self.email = email



# Create the database tables.
db.create_all()

# Create the Flask-Restless API manager.
manager = APIManager(app, flask_sqlalchemy_db=db)

# Create API endpoints, which will be available at /api/<tablename> by
# default. Allowed HTTP methods can be specified as well.
manager.create_api(User, methods=['GET', 'POST', 'DELETE'])


if __name__ == '__main__':
        app.run()

인프라가 코딩되고 있다. 그러한 흐름에 적응하기 위해서 엔지니어는 자신의 인프라를 코딩할수 있어야 한다. 짧은 코드를 통해 익숙해졌으면 한다. 처음 가는 길이라 이리저리 헤매는 것이 당연하듯 자주 가는 길은 눈 감고도 간다. 실제로 눈감고 걷다가 도로 한가운데 중앙선을 걸고 있는 나를 발견하기도 했지만, 그런 만용도 줄 수 있는다는 게 익숙하다는 느낌, 이것만큼은 해봤다는 경험이다. 몇줄도 안된다. 경험해보라.

1 Comment

  1. 김재연

    안녕하세요 🙂 유용한 글을 잘읽었습니다. 제가 지금 Flask를 이용해서 rest web server를 만들고 있습니다.
    위에 주신 코드로 post와 전체리스트를 불러오는 get을 구현했는데요. post를 통해 database로 값이 전송이 되지만, get을 요청하면 “TypeError: is not JSON serializable” 이렇게 에러가 발생합니다… 이 부분을 어떻게 수정해야되는지 조언을 듣고싶습니다 ㅜ foodsksms@gmail.com – 김재연 –

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다