forked from monatis/qrestaurantapp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
api.py
76 lines (67 loc) · 2.79 KB
/
api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
from flask import Blueprint, request
from flask_restplus import Api, Resource, fields, abort
from functools import wraps
from werkzeug.security import safe_str_cmp
from database import db_session as db
from models import Category
api_token = "k03d50-S71b022208"
api_bp = Blueprint('api', __name__, url_prefix='/api/v1')
authorizations = {
'Bearer': {
'type': 'apiKey',
'in': 'header',
'name': 'Authorization',
'description': 'For accessing the API, a valid JWT token must be passed in all the queries in "Authorization" header. A valid JWT token is generated by the API and returned as answer of a call to "POST /api/v1/login" with a valid username and a password. The valid syntax for the "Authorization" header is: "Bearer xxx" where "xxx" is the JWT token which you obtained from "POST /api/v1/login".'
}
}
apiv1 = Api(api_bp, version='1.0',
title='QRestaurant API',
description='Documentation to the RESTful API for QRestaurant. Version V1.0',
doc='/docs',
authorizations=authorizations,
security='Bearer'
)
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = request.headers.get('Authorization')
if not auth: # no header set
abort(401)
jwt_token = auth.split(" ")
if len(jwt_token) is not 2:
abort(401)
if not safe_str_cmp(jwt_token[1], api_token):
abort(401)
return f(*args, **kwargs)
return decorated
category_ns = apiv1.namespace('categories', description='Categories operations')
CategoryModel = apiv1.model('Category', {
'id': fields.Integer(readOnly=True, description='Category unique identifier'),
'name': fields.String(required=True, description='Category display name'),
'created_at': fields.String(readOnly=True, description='Category creation date string'),
'updated_at': fields.String(readOnly=True, description='Category modification date string')}
)
@category_ns.route('/')
class CategoryList(Resource):
@category_ns.marshal_list_with(CategoryModel)
@requires_auth
def get(self):
return db.query(Category).all()
@category_ns.expect(CategoryModel, validate=True)
@category_ns.marshal_with(CategoryModel, code=201)
@requires_auth
def post(self):
"""Add a new category. Only 'name' is required and others are ignored"""
return apiv1.payload, 201
@category_ns.route('/<int:id>')
class CategorySingle(Resource):
@category_ns.response(404, 'Category not found')
@category_ns.marshal_with(CategoryModel)
@requires_auth
def get(self, id):
"""Get a single category by id. Returns 404 not found if category does not exist"""
c = db.query(Category).filter_by(id=id).first()
if c is not None:
return c
else:
return apiv1.abort(404)