Move API in views, use Namespace from flask-retplus.
This commit is contained in:
parent
86d1f942b0
commit
a5eeede95e
@ -20,10 +20,9 @@ from flask import Flask
|
||||
|
||||
from flask_alembic import Alembic
|
||||
from flask_alembic.cli.click import cli as alembic_cli
|
||||
from flask_restplus import Api
|
||||
from flask_cors import CORS
|
||||
|
||||
from .models import db
|
||||
from .views import api, cors
|
||||
|
||||
# The app
|
||||
app = Flask(__name__, static_folder=None, template_folder=None)
|
||||
@ -42,6 +41,7 @@ alembic = Alembic(app)
|
||||
|
||||
app.cli.add_command(alembic_cli, 'db')
|
||||
|
||||
|
||||
# Database initialization.
|
||||
@app.cli.command()
|
||||
@click.pass_context
|
||||
@ -58,19 +58,6 @@ def initdb(ctx):
|
||||
#alembic.stamp()
|
||||
click.echo("Database created.")
|
||||
|
||||
# API initialization.
|
||||
authorizations = {
|
||||
'apikey': {
|
||||
'type': 'apiKey',
|
||||
'in': 'header',
|
||||
'name': 'Authorization'
|
||||
}
|
||||
}
|
||||
|
||||
api = Api(app, authorizations=authorizations, prefix='/api')
|
||||
CORS(app)
|
||||
|
||||
|
||||
# Load all views.
|
||||
# pylint: disable=wildcard-import,wrong-import-position
|
||||
from .views import * # flake8: noqa
|
||||
api.init_app(app)
|
||||
cors.init_app(app)
|
||||
|
@ -14,9 +14,38 @@
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Accountant. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
import pkgutil
|
||||
from flask_cors import CORS
|
||||
from flask_restplus import Api
|
||||
|
||||
__all__ = []
|
||||
from .accounts import ns as accounts_ns
|
||||
from .operations import ns as operations_ns
|
||||
from .scheduled_operations import ns as scheduled_operations_ns
|
||||
from .users import ns as users_ns
|
||||
|
||||
for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
|
||||
__all__.append(module_name)
|
||||
# API initialization.
|
||||
# pylint: disable=invalid-name
|
||||
authorizations = {
|
||||
'apikey': {
|
||||
'type': 'apiKey',
|
||||
'in': 'header',
|
||||
'name': 'Authorization',
|
||||
},
|
||||
}
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
api = Api(
|
||||
title='Accountant API',
|
||||
version='1.0',
|
||||
description='This is the Accountant API.',
|
||||
authorizations=authorizations,
|
||||
prefix='/api'
|
||||
)
|
||||
|
||||
|
||||
api.add_namespace(accounts_ns)
|
||||
api.add_namespace(operations_ns)
|
||||
api.add_namespace(scheduled_operations_ns)
|
||||
api.add_namespace(users_ns)
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
cors = CORS()
|
||||
|
@ -16,12 +16,9 @@
|
||||
"""
|
||||
import dateutil.parser
|
||||
|
||||
from flask_restplus import Resource, fields, marshal_with_field
|
||||
|
||||
from flask_restplus import Namespace, Resource, fields, marshal_with_field
|
||||
from accountant import db
|
||||
|
||||
from .. import api
|
||||
|
||||
from ..models.accounts import Account
|
||||
from ..models.operations import Operation
|
||||
|
||||
@ -30,7 +27,8 @@ from ..fields import Object
|
||||
from .users import requires_auth
|
||||
|
||||
|
||||
ns = api.namespace('account', description='Account management')
|
||||
# pylint: disable=invalid-name
|
||||
ns = Namespace('account', description='Account management')
|
||||
|
||||
# Account model.
|
||||
account_model = ns.model('Account', {
|
||||
@ -136,14 +134,14 @@ range_parser.add_argument(
|
||||
|
||||
|
||||
@ns.route('/')
|
||||
@api.doc(
|
||||
@ns.doc(
|
||||
security='apikey',
|
||||
responses={
|
||||
401: 'Unauthorized'
|
||||
})
|
||||
class AccountListResource(Resource):
|
||||
@requires_auth
|
||||
@api.response(200, 'OK', [account_model])
|
||||
@ns.response(200, 'OK', [account_model])
|
||||
@marshal_with_field(fields.List(Object(account_model)))
|
||||
def get(self):
|
||||
"""
|
||||
@ -152,19 +150,19 @@ class AccountListResource(Resource):
|
||||
return Account.query().all(), 200
|
||||
|
||||
@requires_auth
|
||||
@api.expect(account_model)
|
||||
@api.response(201, 'Account created', account_model)
|
||||
@api.response(406, 'Invalid account data')
|
||||
@ns.expect(account_model)
|
||||
@ns.response(201, 'Account created', account_model)
|
||||
@ns.response(406, 'Invalid account data')
|
||||
@marshal_with_field(Object(account_model))
|
||||
def post(self):
|
||||
"""
|
||||
Create a new account.
|
||||
"""
|
||||
data = api.payload
|
||||
data = ns.apis[0].payload
|
||||
|
||||
# A new account MUST NOT have an id;
|
||||
if 'id' in data and data['id']:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
406,
|
||||
error_message='Id must not be provided on creation.'
|
||||
)
|
||||
@ -183,7 +181,7 @@ class AccountListResource(Resource):
|
||||
|
||||
|
||||
@ns.route('/<int:id>')
|
||||
@api.doc(
|
||||
@ns.doc(
|
||||
security='apikey',
|
||||
params={
|
||||
'id': 'Id of the account to manage'
|
||||
@ -194,7 +192,7 @@ class AccountListResource(Resource):
|
||||
})
|
||||
class AccountResource(Resource):
|
||||
@requires_auth
|
||||
@api.response(200, 'OK', account_model)
|
||||
@ns.response(200, 'OK', account_model)
|
||||
@marshal_with_field(Object(account_model))
|
||||
def get(self, id):
|
||||
"""
|
||||
@ -203,7 +201,7 @@ class AccountResource(Resource):
|
||||
account = Account.query().get(id)
|
||||
|
||||
if not account:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Account with id %d not found.' % id
|
||||
)
|
||||
@ -213,19 +211,19 @@ class AccountResource(Resource):
|
||||
return account, 200
|
||||
|
||||
@requires_auth
|
||||
@api.expect(account_model)
|
||||
@api.response(200, 'OK', account_model)
|
||||
@api.response(406, 'Invalid account data')
|
||||
@ns.expect(account_model)
|
||||
@ns.response(200, 'OK', account_model)
|
||||
@ns.response(406, 'Invalid account data')
|
||||
@marshal_with_field(Object(account_model))
|
||||
def post(self, id):
|
||||
"""
|
||||
Update an account.
|
||||
"""
|
||||
data = api.payload
|
||||
data = ns.apis[0].payload
|
||||
|
||||
# Check ID consistency.
|
||||
if 'id' in data and data['id'] and data['id'] != id:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
406,
|
||||
error_message='Id must not be provided or changed on update.'
|
||||
)
|
||||
@ -234,7 +232,7 @@ class AccountResource(Resource):
|
||||
account = Account.query().get(id)
|
||||
|
||||
if not account:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Account with id %d not found.' % id
|
||||
)
|
||||
@ -249,7 +247,7 @@ class AccountResource(Resource):
|
||||
return account, 200
|
||||
|
||||
@requires_auth
|
||||
@api.response(204, 'Account deleted', account_model)
|
||||
@ns.response(204, 'Account deleted', account_model)
|
||||
@marshal_with_field(Object(account_model))
|
||||
def delete(self, id):
|
||||
"""
|
||||
@ -260,7 +258,7 @@ class AccountResource(Resource):
|
||||
account = Account.query().get(id)
|
||||
|
||||
if not account:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Account with id %d not found.' % id
|
||||
)
|
||||
@ -273,7 +271,7 @@ class AccountResource(Resource):
|
||||
@ns.route('/<int:id>/solds')
|
||||
class SoldsResource(Resource):
|
||||
@requires_auth
|
||||
@api.doc(
|
||||
@ns.doc(
|
||||
security='apikey',
|
||||
responses={
|
||||
200: ('OK', solds_model),
|
||||
@ -288,7 +286,7 @@ class SoldsResource(Resource):
|
||||
account = Account.query().get(id)
|
||||
|
||||
if not account:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Account with id %d not found.' % id
|
||||
)
|
||||
@ -301,14 +299,14 @@ class SoldsResource(Resource):
|
||||
@ns.route('/<int:id>/balance')
|
||||
class BalanceResource(Resource):
|
||||
@requires_auth
|
||||
@api.doc(
|
||||
@ns.doc(
|
||||
security='apikey',
|
||||
responses={
|
||||
200: ('OK', balance_model),
|
||||
401: 'Unauthorized',
|
||||
404: 'Account not found'
|
||||
})
|
||||
@api.expect(range_parser)
|
||||
@ns.expect(range_parser)
|
||||
@marshal_with_field(Object(balance_model))
|
||||
def get(self, id):
|
||||
"""
|
||||
@ -317,7 +315,7 @@ class BalanceResource(Resource):
|
||||
account = Account.query().get(id)
|
||||
|
||||
if not account:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Account with id %d not found.' % id
|
||||
)
|
||||
@ -332,14 +330,14 @@ class BalanceResource(Resource):
|
||||
@ns.route("/<int:id>/category")
|
||||
class CategoryResource(Resource):
|
||||
@requires_auth
|
||||
@api.doc(
|
||||
@ns.doc(
|
||||
security='apikey',
|
||||
responses={
|
||||
200: ('OK', [category_model]),
|
||||
401: 'Unauthorized',
|
||||
404: 'Account not found'
|
||||
})
|
||||
@api.expect(range_parser)
|
||||
@ns.expect(range_parser)
|
||||
@marshal_with_field(fields.List(Object(category_model)))
|
||||
def get(self, id):
|
||||
"""
|
||||
@ -353,14 +351,14 @@ class CategoryResource(Resource):
|
||||
@ns.route('/<int:id>/ohlc')
|
||||
class OHLCResource(Resource):
|
||||
@requires_auth
|
||||
@api.doc(
|
||||
@ns.doc(
|
||||
security='apikey',
|
||||
responses={
|
||||
200: ('OK', [ohlc_model]),
|
||||
401: 'Unauthorized',
|
||||
404: 'Account not found'
|
||||
})
|
||||
@api.expect(range_parser)
|
||||
@ns.expect(range_parser)
|
||||
@marshal_with_field(fields.List(Object(ohlc_model)))
|
||||
def get(self, id):
|
||||
"""
|
||||
|
@ -16,12 +16,9 @@
|
||||
"""
|
||||
import dateutil.parser
|
||||
|
||||
from flask_restplus import Resource, fields, marshal_with_field
|
||||
|
||||
from flask_restplus import Namespace, Resource, fields, marshal_with_field
|
||||
from accountant import db
|
||||
|
||||
from .. import api
|
||||
|
||||
from ..models.accounts import Account
|
||||
from ..models.operations import Operation
|
||||
|
||||
@ -30,7 +27,8 @@ from .users import requires_auth
|
||||
from ..fields import Object
|
||||
|
||||
|
||||
ns = api.namespace('operation', description='Operation management')
|
||||
# pylint: disable=invalid-name
|
||||
ns = Namespace('operation', description='Operation management')
|
||||
|
||||
# Operation with sold model.
|
||||
operation_model = ns.model('Operation', {
|
||||
@ -106,15 +104,15 @@ account_range_parser.add_argument(
|
||||
|
||||
|
||||
@ns.route('/')
|
||||
@api.doc(
|
||||
@ns.doc(
|
||||
security='apikey',
|
||||
responses={
|
||||
401: 'Unauthorized'
|
||||
})
|
||||
class OperationListResource(Resource):
|
||||
@requires_auth
|
||||
@api.response(200, 'OK', [operation_with_sold_model])
|
||||
@api.expect(parser=account_range_parser)
|
||||
@ns.response(200, 'OK', [operation_with_sold_model])
|
||||
@ns.expect(parser=account_range_parser)
|
||||
@marshal_with_field(fields.List(Object(operation_with_sold_model)))
|
||||
def get(self):
|
||||
"""
|
||||
@ -130,28 +128,28 @@ class OperationListResource(Resource):
|
||||
).all(), 200
|
||||
|
||||
@requires_auth
|
||||
@api.response(201, 'Operation created', operation_model)
|
||||
@api.response(404, 'Account not found')
|
||||
@api.response(406, 'Invalid operation data')
|
||||
@ns.response(201, 'Operation created', operation_model)
|
||||
@ns.response(404, 'Account not found')
|
||||
@ns.response(406, 'Invalid operation data')
|
||||
@marshal_with_field(Object(operation_model))
|
||||
def post(self):
|
||||
"""
|
||||
Create a new operation.
|
||||
"""
|
||||
data = api.payload
|
||||
data = ns.apis[0].payload
|
||||
|
||||
account_id = data['account_id']
|
||||
account = Account.query().get(account_id)
|
||||
|
||||
if not account:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Account with id %d not found.' % account_id
|
||||
)
|
||||
|
||||
# A new operation MUST NOT have an id;
|
||||
if 'id' in data and data['id']:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
406,
|
||||
error_message='Id must not be provided on creation.'
|
||||
)
|
||||
@ -164,7 +162,7 @@ class OperationListResource(Resource):
|
||||
|
||||
|
||||
@ns.route('/<int:id>')
|
||||
@api.doc(
|
||||
@ns.doc(
|
||||
security='apikey',
|
||||
params={
|
||||
'id': 'Id of the operation to manage'
|
||||
@ -175,7 +173,7 @@ class OperationListResource(Resource):
|
||||
})
|
||||
class OperationResource(Resource):
|
||||
@requires_auth
|
||||
@api.response(200, 'OK', operation_model)
|
||||
@ns.response(200, 'OK', operation_model)
|
||||
@marshal_with_field(Object(operation_model))
|
||||
def get(self, id):
|
||||
"""
|
||||
@ -184,7 +182,7 @@ class OperationResource(Resource):
|
||||
operation = db.session.query(Operation).get(id)
|
||||
|
||||
if not operation:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Operation with id %d not found.' % id
|
||||
)
|
||||
@ -192,16 +190,16 @@ class OperationResource(Resource):
|
||||
return operation, 200
|
||||
|
||||
@requires_auth
|
||||
@api.expect(operation_model)
|
||||
@api.response(200, 'OK', operation_model)
|
||||
@api.response(406, 'Invalid operation data')
|
||||
@ns.expect(operation_model)
|
||||
@ns.response(200, 'OK', operation_model)
|
||||
@ns.response(406, 'Invalid operation data')
|
||||
@marshal_with_field(Object(operation_model))
|
||||
def post(self, id):
|
||||
data = api.payload
|
||||
data = ns.apis[0].payload
|
||||
|
||||
# Check ID consistency.
|
||||
if 'id' in data and data['id'] and data['id'] != id:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
406,
|
||||
error_message='Id must not be provided or changed on update.'
|
||||
)
|
||||
@ -209,7 +207,7 @@ class OperationResource(Resource):
|
||||
operation = db.session.query(Operation).get(id)
|
||||
|
||||
if not operation:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Operation with id %d not found.' % id
|
||||
)
|
||||
@ -225,13 +223,13 @@ class OperationResource(Resource):
|
||||
return operation, 200
|
||||
|
||||
@requires_auth
|
||||
@api.response(204, 'Operation deleted', operation_model)
|
||||
@ns.response(204, 'Operation deleted', operation_model)
|
||||
@marshal_with_field(Object(operation_model))
|
||||
def delete(self, id):
|
||||
operation = db.session.query(Operation).get(id)
|
||||
|
||||
if not operation:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Operation with id %d not found.' % id
|
||||
)
|
||||
|
@ -14,14 +14,12 @@
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Accountant. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from flask_restplus import Resource, fields, marshal_with_field
|
||||
from flask_restplus import Namespace, Resource, fields, marshal_with_field
|
||||
|
||||
from sqlalchemy import true
|
||||
|
||||
from accountant import db
|
||||
|
||||
from .. import api
|
||||
|
||||
from ..models.accounts import Account
|
||||
from ..models.operations import Operation
|
||||
from ..models.scheduled_operations import ScheduledOperation
|
||||
@ -31,7 +29,7 @@ from .users import requires_auth
|
||||
from ..fields import Object
|
||||
|
||||
|
||||
ns = api.namespace(
|
||||
ns = Namespace(
|
||||
'scheduled_operation',
|
||||
description='Scheduled operation management'
|
||||
)
|
||||
@ -84,15 +82,15 @@ account_id_parser.add_argument(
|
||||
|
||||
|
||||
@ns.route('/')
|
||||
@api.doc(
|
||||
@ns.doc(
|
||||
security='apikey',
|
||||
responses={
|
||||
401: 'Unauthorized',
|
||||
})
|
||||
class ScheduledOperationListResource(Resource):
|
||||
@requires_auth
|
||||
@api.expect(account_id_parser)
|
||||
@api.response(200, 'OK', [scheduled_operation_model])
|
||||
@ns.expect(account_id_parser)
|
||||
@ns.response(200, 'OK', [scheduled_operation_model])
|
||||
@marshal_with_field(fields.List(Object(scheduled_operation_model)))
|
||||
def get(self):
|
||||
"""
|
||||
@ -103,29 +101,29 @@ class ScheduledOperationListResource(Resource):
|
||||
return ScheduledOperation.query().filter_by(**data).all(), 200
|
||||
|
||||
@requires_auth
|
||||
@api.expect(scheduled_operation_model)
|
||||
@api.response(200, 'OK', scheduled_operation_model)
|
||||
@api.response(404, 'Account not found')
|
||||
@api.response(406, 'Invalid operation data')
|
||||
@ns.expect(scheduled_operation_model)
|
||||
@ns.response(200, 'OK', scheduled_operation_model)
|
||||
@ns.response(404, 'Account not found')
|
||||
@ns.response(406, 'Invalid operation data')
|
||||
@marshal_with_field(Object(scheduled_operation_model))
|
||||
def post(self):
|
||||
"""
|
||||
Add a new scheduled operation.
|
||||
"""
|
||||
data = api.payload
|
||||
data = ns.apis[0].payload
|
||||
|
||||
account_id = data['account_id']
|
||||
account = Account.query().get(account_id)
|
||||
|
||||
if not account:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Account with id %d not found.' % account_id
|
||||
)
|
||||
|
||||
# A new scheduled operation MUST NOT have an id;
|
||||
if 'id' in data and data['id']:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
406,
|
||||
error_message='Id must not be provided on creation.'
|
||||
)
|
||||
@ -142,7 +140,7 @@ class ScheduledOperationListResource(Resource):
|
||||
|
||||
|
||||
@ns.route('/<int:id>')
|
||||
@api.doc(
|
||||
@ns.doc(
|
||||
security='apikey',
|
||||
params={
|
||||
'id': 'Id of the scheduled operation to manage'
|
||||
@ -153,7 +151,7 @@ class ScheduledOperationListResource(Resource):
|
||||
})
|
||||
class ScheduledOperationResource(Resource):
|
||||
@requires_auth
|
||||
@api.response(200, 'OK', scheduled_operation_model)
|
||||
@ns.response(200, 'OK', scheduled_operation_model)
|
||||
@marshal_with_field(Object(scheduled_operation_model))
|
||||
def get(self, id):
|
||||
"""
|
||||
@ -162,7 +160,7 @@ class ScheduledOperationResource(Resource):
|
||||
scheduled_operation = ScheduledOperation.query().get(id)
|
||||
|
||||
if not scheduled_operation:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Scheduled operation with id %d not found.' % id
|
||||
)
|
||||
@ -170,19 +168,19 @@ class ScheduledOperationResource(Resource):
|
||||
return scheduled_operation, 200
|
||||
|
||||
@requires_auth
|
||||
@api.response(200, 'OK', scheduled_operation_model)
|
||||
@api.response(406, 'Invalid scheduled operation data')
|
||||
@api.expect(scheduled_operation_model)
|
||||
@ns.response(200, 'OK', scheduled_operation_model)
|
||||
@ns.response(406, 'Invalid scheduled operation data')
|
||||
@ns.expect(scheduled_operation_model)
|
||||
@marshal_with_field(Object(scheduled_operation_model))
|
||||
def post(self, id):
|
||||
"""
|
||||
Update a scheduled operation.
|
||||
"""
|
||||
data = api.payload
|
||||
data = ns.apis[0].payload
|
||||
|
||||
# Check ID consistency.
|
||||
if 'id' in data and data['id'] and data['id'] != id:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
406,
|
||||
error_message='Id must not be provided or changed on update.'
|
||||
)
|
||||
@ -190,7 +188,7 @@ class ScheduledOperationResource(Resource):
|
||||
scheduled_operation = ScheduledOperation.query().get(id)
|
||||
|
||||
if not scheduled_operation:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Scheduled operation with id %d not found.' % id
|
||||
)
|
||||
@ -210,8 +208,8 @@ class ScheduledOperationResource(Resource):
|
||||
return scheduled_operation, 200
|
||||
|
||||
@requires_auth
|
||||
@api.response(200, 'OK', scheduled_operation_model)
|
||||
@api.response(409, 'Cannot be deleted')
|
||||
@ns.response(200, 'OK', scheduled_operation_model)
|
||||
@ns.response(409, 'Cannot be deleted')
|
||||
@marshal_with_field(Object(scheduled_operation_model))
|
||||
def delete(self, id):
|
||||
"""
|
||||
@ -220,7 +218,7 @@ class ScheduledOperationResource(Resource):
|
||||
scheduled_operation = ScheduledOperation.query().get(id)
|
||||
|
||||
if not scheduled_operation:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
404,
|
||||
error_message='Scheduled operation with id %d not found.' % id
|
||||
)
|
||||
@ -230,7 +228,7 @@ class ScheduledOperationResource(Resource):
|
||||
).count()
|
||||
|
||||
if operations:
|
||||
api.abort(
|
||||
ns.abort(
|
||||
409,
|
||||
error_message='There are still confirmed operations \
|
||||
associated to this scheduled operation.')
|
||||
|
@ -22,16 +22,13 @@ import arrow
|
||||
from functools import wraps
|
||||
|
||||
from flask import request, g
|
||||
from flask_restplus import Resource, fields, marshal_with_field
|
||||
|
||||
from .. import app, api
|
||||
from flask_restplus import Namespace, Resource, fields, marshal_with_field
|
||||
|
||||
from ..fields import Object
|
||||
|
||||
from ..models.users import User
|
||||
|
||||
from .models import user_model, token_model, login_model
|
||||
|
||||
from accountant import db
|
||||
|
||||
|
||||
@ -76,14 +73,14 @@ def requires_auth(f):
|
||||
g.user = user
|
||||
return f(*args, **data)
|
||||
|
||||
api.abort(
|
||||
ns.abort(
|
||||
401,
|
||||
error_message='Please login before executing this request.'
|
||||
)
|
||||
return wrapped
|
||||
|
||||
|
||||
ns = api.namespace('user', description='User management')
|
||||
ns = Namespace('user', description='User management')
|
||||
|
||||
# Token with expiration time and type.
|
||||
token_model = ns.model('Token', {
|
||||
@ -134,25 +131,25 @@ login_model = ns.model('Login', {
|
||||
|
||||
@ns.route('/login')
|
||||
class LoginResource(Resource):
|
||||
@api.marshal_with(token_model)
|
||||
@api.doc(
|
||||
@ns.marshal_with(token_model)
|
||||
@ns.doc(
|
||||
responses={
|
||||
200: ('OK', token_model),
|
||||
401: 'Unauthorized'
|
||||
})
|
||||
@api.expect(login_model)
|
||||
@ns.expect(login_model)
|
||||
def post(self):
|
||||
"""
|
||||
Login to retrieve authentication token.
|
||||
"""
|
||||
data = api.payload
|
||||
data = ns.apis[0].payload
|
||||
|
||||
user = User.query().filter(
|
||||
User.email == data['email']
|
||||
).one_or_none()
|
||||
|
||||
if not user or not user.verify_password(data['password']):
|
||||
api.abort(401, error_message="Bad user or password.")
|
||||
ns.abort(401, error_message="Bad user or password.")
|
||||
|
||||
token = user.generate_auth_token()
|
||||
expiration_time = arrow.now().replace(
|
||||
@ -166,7 +163,7 @@ class LoginResource(Resource):
|
||||
}, 200
|
||||
|
||||
@requires_auth
|
||||
@api.doc(
|
||||
@ns.doc(
|
||||
security='apikey',
|
||||
responses={
|
||||
200: ('OK', user_model)
|
||||
|
Loading…
Reference in New Issue
Block a user