Use flask-restful and flask-sqlalchemy

master
Nikola Forró 7 years ago
parent d115eb47b6
commit 6d3a47dbae

@ -1,60 +1,147 @@
import os
import flask
import flask_cors
import flask_restful
import flask_restful.fields
import flask_restful.reqparse
import flask_sqlalchemy
import sqlalchemy
from quote import engine, Base, Session, Quote, QuoteSchema
DB_PATH = os.path.expandvars('$HOME/quotes/quotes.db')
app = flask.Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_PATH}'
app.config['ERROR_404_HELP'] = False
db = flask_sqlalchemy.SQLAlchemy(app)
db.create_all()
api = flask_restful.Api(app)
flask_cors.CORS(app)
Base.metadata.create_all(engine)
@app.route('/quotes')
def get_quotes():
args = flask.request.args
filter = args.get('filter', type=str)
sort_by = args.get('sort_by', type=str)
sort_order = args.get('sort_order', type=str)
page_number = args.get('page_number', type=int)
page_size = args.get('page_size', type=int)
session = Session()
try:
q = session.query(Quote)
if filter:
q = q.filter(Quote.text.ilike('%{}%'.format(filter)))
class Quote(db.Model):
__tablename__ = 'quotes'
id = db.Column(db.Integer, primary_key=True)
video_id = db.Column(db.Integer)
date = db.Column(db.Date)
game = db.Column(db.String)
text = db.Column(db.String)
created_at = db.Column(db.DateTime)
updated_at = db.Column(db.DateTime)
quote_fields = {
'id': flask_restful.fields.Integer(),
'video_id': flask_restful.fields.Integer(),
'date': flask_restful.fields.DateTime(dt_format='iso8601'),
'game': flask_restful.fields.String(),
'text': flask_restful.fields.String(),
'created_at': flask_restful.fields.DateTime(dt_format='iso8601'),
'updated_at': flask_restful.fields.DateTime(dt_format='iso8601'),
}
quote_parser = flask_restful.reqparse.RequestParser()
quote_parser.add_argument('id', type=int)
quote_parser.add_argument('video_id', type=int)
quote_parser.add_argument('date', type=flask_restful.inputs.date, required=True)
quote_parser.add_argument('game', type=str, required=True)
quote_parser.add_argument('text', type=str, required=True)
filter_parser = flask_restful.reqparse.RequestParser()
filter_parser.add_argument('filter', type=str)
filter_parser.add_argument('sort_by', type=str)
filter_parser.add_argument('sort_order', type=str)
filter_parser.add_argument('page_number', type=int)
filter_parser.add_argument('page_size', type=int)
class QuoteResource(flask_restful.Resource):
@flask_restful.marshal_with(quote_fields)
def get(self, id):
q = db.session.query(Quote).filter(Quote.id == id)
quote = q.first()
if not quote:
flask_restful.abort(404, message='Quote {0} does not exist'.format(id))
return quote, 200
@flask_restful.marshal_with(quote_fields)
def put(self, id):
args = quote_parser.parse_args()
now = sqlalchemy.func.now()
q = db.session.query(Quote).filter(Quote.id == id)
quote = q.first()
if not quote:
quote = Quote(id=id, created_at=now)
quote.video_id = args['video_id'] # FIXME: NULL
quote.date = args['date']
quote.game = args['game']
quote.text = args['text']
quote.updated_at = now
db.session.add(quote)
db.session.commit()
return quote, 200
def delete(self, id):
q = db.session.query(Quote).filter(Quote.id == id)
quote = q.first()
if not quote:
flask_restful.abort(404, message='Quote {0} does not exist'.format(id))
db.session.delete(quote)
db.session.commit()
return None, 204
class QuotesResource(flask_restful.Resource):
@flask_restful.marshal_with(quote_fields)
def get(self):
args = filter_parser.parse_args()
q = db.session.query(Quote)
if args['filter']:
q = q.filter(Quote.text.ilike('%{}%'.format(args['filter'])))
count = q.count()
if sort_by:
col = getattr(Quote, sort_by, None)
if args['sort_by']:
col = getattr(Quote, args['sort_by'], None)
if col:
if sort_order:
order_by = getattr(col, sort_order, None)
if args['sort_order']:
order_by = getattr(col, args['sort_order'], None)
if order_by:
q = q.order_by(order_by())
else:
q = q.order_by(col)
if page_size:
q = q.limit(page_size)
if page_number and page_size:
q = q.offset(page_number * page_size)
data = QuoteSchema(many=True).dump(q).data
finally:
session.close()
return flask.jsonify(data), 200, {'X-Total-Count': count}
@app.route('/quotes', methods=['POST'])
def add_quote():
q = QuoteSchema().load(flask.request.get_json())
quote = Quote(**q.data)
session = Session()
try:
session.add(quote)
session.commit()
data = QuoteSchema().dump(quote).data
except:
session.rollback()
raise
finally:
session.close()
return flask.jsonify(data), 201
if args['page_size']:
q = q.limit(args['page_size'])
if args['page_number'] and args['page_size']:
q = q.offset(args['page_number'] * args['page_size'])
quotes = q.all()
return quotes, 200, {'X-Total-Count': count}
@flask_restful.marshal_with(quote_fields)
def post(self):
args = quote_parser.parse_args()
if not args['id']:
flask_restful.abort(400, message='Missing required parameter id')
now = sqlalchemy.func.now()
q = db.session.query(Quote).filter(Quote.id == args['id'])
quote = q.first()
if not quote:
quote = Quote(id=args['id'], created_at=now)
quote.video_id = args['video_id'] # FIXME: NULL
quote.date = args['date']
quote.game = args['game']
quote.text = args['text']
quote.updated_at = now
db.session.add(quote)
db.session.commit()
url = api.url_for(QuoteResource, id=quote.id, _external=True, _scheme='https')
return quote, 201, {'Location': url}
api.add_resource(QuoteResource, '/quotes/<int:id>')
api.add_resource(QuotesResource, '/quotes')

@ -1,48 +0,0 @@
import os
import marshmallow
import sqlalchemy
import sqlalchemy.orm
import sqlalchemy.ext.declarative
from datetime import datetime
DB_PATH = os.path.expandvars('$HOME/quotes/quotes.db')
engine = sqlalchemy.create_engine(f'sqlite:///{DB_PATH}')
Session = sqlalchemy.orm.sessionmaker(bind=engine)
Base = sqlalchemy.ext.declarative.declarative_base()
class Quote(Base):
__tablename__ = 'quotes'
id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
video_id = sqlalchemy.Column(sqlalchemy.Integer)
date = sqlalchemy.Column(sqlalchemy.Date)
game = sqlalchemy.Column(sqlalchemy.String)
text = sqlalchemy.Column(sqlalchemy.String)
created_at = sqlalchemy.Column(sqlalchemy.DateTime)
updated_at = sqlalchemy.Column(sqlalchemy.DateTime)
def __init__(self, id, video_id, date, game, text):
self.id = id
self.video_id = video_id
self.date = date
self.game = game
self.text = text
self.created_at = datetime.now()
self.updated_at = datetime.now()
class QuoteSchema(marshmallow.Schema):
id = marshmallow.fields.Integer()
video_id = marshmallow.fields.Integer()
date = marshmallow.fields.Date()
game = marshmallow.fields.Str()
text = marshmallow.fields.Str()
created_at = marshmallow.fields.DateTime()
updated_at = marshmallow.fields.DateTime()
Loading…
Cancel
Save