Skip to content

Instantly share code, notes, and snippets.

@olawalejarvis
Last active July 10, 2020 14:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olawalejarvis/cf02f37653ff6a63008a915b7a757276 to your computer and use it in GitHub Desktop.
Save olawalejarvis/cf02f37653ff6a63008a915b7a757276 to your computer and use it in GitHub Desktop.
blog_api
#src/app.py
from flask import Flask
from .config import app_config
def create_app(env_name):
"""
Create app
"""
# app initiliazation
app = Flask(__name__)
app.config.from_object(app_config[env_name])
@app.route('/', methods=['GET'])
def index():
"""
example endpoint
"""
return 'Congratulations! Your first endpoint is workin'
return app
#src/app.py
#####################
# existing code remains #
########################
from flask_bcrypt import Bcrypt # add this new line
from .config import app_config
bcrypt = Bcrypt() # add this new line
def create_app(env_name):
"""
Create app
"""
#####################
# existing code remain #
######################
# initializing bcrypt
bcrypt.init_app(app) # add this new line
@app.route('/', methods=['GET'])
def index():
"""
example endpoint
"""
return 'Congratulations! Your first endpoint is working'
return app
#src/app.py
from flask import Flask
from .config import app_config
from .models import db, bcrypt # add this new line
def create_app(env_name):
"""
Create app
"""
# app initiliazation
app = Flask(__name__)
app.config.from_object(app_config[env_name])
# initializing bcrypt
bcrypt.init_app(app) # add this line
db.init_app(app) # add this line
#####################
# existing code remain #
######################
return app
#src/app.py
from flask import Flask
from .config import app_config
from .models import db, bcrypt
# import user_api blueprint
from .views.UserView import user_api as user_blueprint # add this line
def create_app(env_name):
"""
Create app
"""
# app initiliazation
#####################
# existing code remain #
######################
app.register_blueprint(user_blueprint, url_prefix='/api/v1/users') # add this line
@app.route('/', methods=['GET'])
def index():
"""
example endpoint
"""
return 'Congratulations! Your first endpoint is working'
return app
#src/shared/Authentication
import jwt
import os
import datetime
from flask import json
from ..models.UserModel import UserModel
class Auth():
"""
Auth Class
"""
@staticmethod
def generate_token(user_id):
"""
Generate Token Method
"""
try:
payload = {
'exp': datetime.datetime.utcnow() + datetime.timedelta(days=1),
'iat': datetime.datetime.utcnow(),
'sub': user_id
}
return jwt.encode(
payload,
os.getenv('JWT_SECRET_KEY'),
'HS256'
).decode("utf-8")
except Exception as e:
return Response(
mimetype="application/json",
response=json.dumps({'error': 'error in generating user token'}),
status=400
)
@staticmethod
def decode_token(token):
"""
Decode token method
"""
re = {'data': {}, 'error': {}}
try:
payload = jwt.decode(token, os.getenv('JWT_SECRET_KEY'))
re['data'] = {'user_id': payload['sub']}
return re
except jwt.ExpiredSignatureError as e1:
re['error'] = {'message': 'token expired, please login again'}
return re
except jwt.InvalidTokenError:
re['error'] = {'message': 'Invalid token, please try again with a new token'}
return re
#src/shared/Authentication
import jwt
import os
import datetime
from flask import json, Response, request, g
from ..models.UserModel import UserModel
class Auth():
"""
Auth Class
"""
#####################
# existing code remain #
######################
# decorator
@staticmethod
def auth_required(func):
"""
Auth decorator
"""
@wraps(func)
def decorated_auth(*args, **kwargs):
if 'api-token' not in request.headers:
return Response(
mimetype="application/json",
response=json.dumps({'error': 'Authentication token is not available, please login to get one'}),
status=400
)
token = request.headers.get('api-token')
data = Auth.decode_token(token)
if data['error']:
return Response(
mimetype="application/json",
response=json.dumps(data['error']),
status=400
)
user_id = data['data']['user_id']
check_user = UserModel.get_one_user(user_id)
if not check_user:
return Response(
mimetype="application/json",
response=json.dumps({'error': 'user does not exist, invalid token'}),
status=400
)
g.user = {'id': user_id}
return func(*args, **kwargs)
return decorated_auth
# src/models/BlogpostModel.py
from . import db
import datetime
class BlogpostModel(db.Model):
"""
Blogpost Model
"""
__tablename__ = 'blogposts'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(128), nullable=False)
contents = db.Column(db.Text, nullable=False)
created_at = db.Column(db.DateTime)
modified_at = db.Column(db.DateTime)
def __init__(self, data):
self.title = data.get('title')
self.contents = data.get('contents')
self.created_at = datetime.datetime.utcnow()
self.modified_at = datetime.datetime.utcnow()
def save(self):
db.session.add(self)
db.session.commit()
def update(self, data):
for key, item in data.items():
setattr(self, key, item)
self.modified_at = datetime.datetime.utcnow()
db.session.commit()
def delete(self):
db.session.delete(self)
de.session.commit()
@staticmethod
def get_all_blogposts():
return BlogpostModel.query.all()
@staticmethod
def get_one_blogpost(id):
return BlogpostModel.query.get(id)
def __repr__(self):
return '<id {}>'.format(self.id)
# src/models/BlogpostModel.py
#####################
# existing code remains #
########################
from marshmallow import fields, Schema
class BlogpostModel(db.Model):
"""
Blogpost Model
"""
__tablename__ = 'blogposts'
#####################
# existing code remains #
########################
contents = db.Column(db.Text, nullable=False)
owner_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) # add this new line
#####################
# existing code remains #
########################
def __init__(self, data):
#####################
# existing code remains #
########################
self.owner_id = data.get('owner_id) # add this new line
self.created_at = datetime.datetime.utcnow()
self.modified_at = datetime.datetime.utcnow()
#####################
# existing code remains #
########################
def __repr__(self):
return '<id {}>'.format(self.id)
# add this new class
class BlogpostSchema(Schema):
"""
Blogpost Schema
"""
id = fields.Int(dump_only=True)
title = fields.Str(required=True)
contents = fields.Str(required=True)
owner_id = fields.Int(required=True)
created_at = fields.DateTime(dump_only=True)
modified_at = fields.DateTime(dump_only=True)
#/src/views/BlogpostView.py
from flask import request, g, Blueprint, json, Response
from ..shared.Authentication import Auth
from ..models.BlogpostModel import BlogpostModel, BlogpostSchema
blogpost_api = Blueprint('blogpost_api', __name__)
blogpost_schema = BlogpostSchema()
@blogpost_api.route('/', methods=['POST'])
@Auth.auth_required
def create():
"""
Create Blogpost Function
"""
req_data = request.get_json()
req_data['owner_id'] = g.user.get('id')
data, error = blogpost_schema.load(req_data)
if error:
return custom_response(error, 400)
post = BlogpostModel(data)
post.save()
data = blogpost_schema.dump(post).data
return custom_response(data, 201)
def custom_response(res, status_code):
"""
Custom Response Function
"""
return Response(
mimetype="application/json",
response=json.dumps(res),
status=status_code
)
#/src/views/BlogpostView.py
# app initiliazation
#####################
# existing code remain #
######################
@blogpost_api.route('/', methods=['POST'])
@Auth.auth_required
def create():
"""
Create Blogpost Function
"""
# app initiliazation
#####################
# existing code remain #
######################
return custom_response(data, 201)
# add this function
@blogpost_api.route('/', methods=['GET'])
def get_all():
"""
Get All Blogposts
"""
posts = BlogpostModel.get_all_blogposts()
data = blogpost_schema.dump(posts, many=True).data
return custom_response(data, 200)
# app initiliazation
#####################
# existing code remain #
######################
#/src/views/BlogpostView.py
# app initiliazation
#####################
# existing code remain #
######################
@blogpost_api.route('/', methods=['POST'])
@Auth.auth_required
def create():
"""
Create Blogpost Function
"""
# app initiliazation
#####################
# existing code remain #
######################
return custom_response(data, 201)
# app initiliazation
#####################
# existing code remain #
######################
@blogpost_api.route('/<int:blogpost_id>', methods=['GET'])
def get_one(blogpost_id):
"""
Get A Blogpost
"""
post = BlogpostModel.get_one_blogpost(blogpost_id)
if not post:
return custom_response({'error': 'post not found'}, 404)
data = blogpost_schema.dump(post).data
return custom_response(data, 200)
# app initiliazation
#####################
# existing code remain #
######################
#/src/views/BlogpostView.py
# app initiliazation
#####################
# existing code remain #
######################
@blogpost_api.route('/', methods=['POST'])
@Auth.auth_required
def create():
"""
Create Blogpost Function
"""
# app initiliazation
#####################
# existing code remain #
######################
return custom_response(data, 201)
# app initiliazation
#####################
# existing code remain #
######################
@blogpost_api.route('/<int:blogpost_id>', methods=['PUT'])
@Auth.auth_required
def update(blogpost_id):
"""
Update A Blogpost
"""
req_data = request.get_json()
post = BlogpostModel.get_one_blogpost(blogpost_id)
if not post:
return custom_response({'error': 'post not found'}, 404)
data = blogpost_schema.dump(post).data
if data.get('owner_id') != g.user.get('id'):
return custom_response({'error': 'permission denied'}, 400)
data, error = blogpost_schema.load(req_data, partial=True)
if error:
return custom_response(error, 400)
post.update(data)
data = blogpost_schema.dump(post).data
return custom_response(data, 200)
#/src/views/BlogpostView.py
# app initiliazation
#####################
# existing code remain #
######################
@blogpost_api.route('/', methods=['POST'])
@Auth.auth_required
def create():
"""
Create Blogpost Function
"""
# app initiliazation
#####################
# existing code remain #
######################
return custom_response(data, 201)
# app initiliazation
#####################
# existing code remain #
######################
@blogpost_api.route('/<int:blogpost_id>', methods=['DELETE'])
@Auth.auth_required
def delete(blogpost_id):
"""
Delete A Blogpost
"""
post = BlogpostModel.get_one_blogpost(blogpost_id)
if not post:
return custom_response({'error': 'post not found'}, 404)
data = blogpost_schema.dump(post).data
if data.get('owner_id') != g.user.get('id'):
return custom_response({'error': 'permission denied'}, 400)
post.delete()
return custom_response({'message': 'deleted'}, 204)
# /src/config.py
import os
class Development(object):
"""
Development environment configuration
"""
DEBUG = True
TESTING = False
JWT_SECRET_KEY = os.getenv('JWT_SECRET_KEY')
SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL')
class Production(object):
"""
Production environment configurations
"""
DEBUG = False
TESTING = False
SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL')
JWT_SECRET_KEY = os.getenv('JWT_SECRET_KEY')
app_config = {
'development': Development,
'production': Production,
}
import os
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from src.app import create_app, db
env_name = os.getenv('FLASK_ENV')
app = create_app(env_name)
migrate = Migrate(app=app, db=db)
manager = Manager(app=app)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
flask = "*"
flask-sqlalchemy = "*"
"psycopg2" = "*"
flask-migrate = "*"
flask-script = "*"
marshmallow = "*"
flask-bcrypt = "*"
pyjwt = "*"
[dev-packages]
[requires]
python_version = "3.6"
# /run.py
import os
from src.app import create_app
if __name__ == '__main__':
env_name = os.getenv('FLASK_ENV')
app = create_app(env_name)
# run app
app.run()
import unittest
import os
import json
from ..app import create_app, db
class UsersTest(unittest.TestCase):
"""
Users Test Case
"""
def setUp(self):
"""
Test Setup
"""
self.app = create_app("testing")
self.client = self.app.test_client
self.user = {
'name': 'olawale',
'email': 'olawale@mail.com',
'password': 'passw0rd!'
}
with self.app.app_context():
# create all tables
db.create_all()
def test_user_creation(self):
""" test user creation with valid credentials """
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(self.user))
json_data = json.loads(res.data)
self.assertTrue(json_data.get('jwt_token'))
self.assertEqual(res.status_code, 201)
def test_user_creation_with_existing_email(self):
""" test user creation with already existing email"""
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(self.user))
self.assertEqual(res.status_code, 201)
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(self.user))
json_data = json.loads(res.data)
self.assertEqual(res.status_code, 400)
self.assertTrue(json_data.get('error'))
def test_user_creation_with_no_password(self):
""" test user creation with no password"""
user1 = {
'name': 'olawale',
'email': 'olawale1@mail.com',
}
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(user1))
json_data = json.loads(res.data)
self.assertEqual(res.status_code, 400)
self.assertTrue(json_data.get('password'))
def test_user_creation_with_no_email(self):
""" test user creation with no email """
user1 = {
'name': 'olawale',
'pasword': 'olawale1@mail.com',
}
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(user1))
json_data = json.loads(res.data)
self.assertEqual(res.status_code, 400)
self.assertTrue(json_data.get('email'))
def test_user_creation_with_empty_request(self):
""" test user creation with empty request """
user1 = {}
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(user1))
json_data = json.loads(res.data)
self.assertEqual(res.status_code, 400)
def test_user_login(self):
""" User Login Tests """
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(self.user))
self.assertEqual(res.status_code, 201)
res = self.client().post('/api/v1/users/login', headers={'Content-Type': 'application/json'}, data=json.dumps(self.user))
json_data = json.loads(res.data)
self.assertTrue(json_data.get('jwt_token'))
self.assertEqual(res.status_code, 200)
def test_user_login_with_invalid_password(self):
""" User Login Tests with invalid credentials """
user1 = {
'password': 'olawale',
'email': 'olawale@mail.com',
}
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(self.user))
self.assertEqual(res.status_code, 201)
res = self.client().post('/api/v1/users/login', headers={'Content-Type': 'application/json'}, data=json.dumps(user1))
json_data = json.loads(res.data)
self.assertFalse(json_data.get('jwt_token'))
self.assertEqual(json_data.get('error'), 'invalid credentials')
self.assertEqual(res.status_code, 400)
def test_user_login_with_invalid_email(self):
""" User Login Tests with invalid credentials """
user1 = {
'password': 'passw0rd!',
'email': 'olawale1111@mail.com',
}
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(self.user))
self.assertEqual(res.status_code, 201)
res = self.client().post('/api/v1/users/login', headers={'Content-Type': 'application/json'}, data=json.dumps(user1))
json_data = json.loads(res.data)
self.assertFalse(json_data.get('jwt_token'))
self.assertEqual(json_data.get('error'), 'invalid credentials')
self.assertEqual(res.status_code, 400)
def test_user_get_me(self):
""" Test User Get Me """
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(self.user))
self.assertEqual(res.status_code, 201)
api_token = json.loads(res.data).get('jwt_token')
res = self.client().get('/api/v1/users/me', headers={'Content-Type': 'application/json', 'api-token': api_token})
json_data = json.loads(res.data)
self.assertEqual(res.status_code, 200)
self.assertEqual(json_data.get('email'), 'olawale@mail.com')
self.assertEqual(json_data.get('name'), 'olawale')
def test_user_update_me(self):
""" Test User Update Me """
user1 = {
'name': 'new name'
}
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(self.user))
self.assertEqual(res.status_code, 201)
api_token = json.loads(res.data).get('jwt_token')
res = self.client().put('/api/v1/users/me', headers={'Content-Type': 'application/json', 'api-token': api_token}, data=json.dumps(user1))
json_data = json.loads(res.data)
self.assertEqual(res.status_code, 200)
self.assertEqual(json_data.get('name'), 'new name')
def test_delete_user(self):
""" Test User Delete """
res = self.client().post('/api/v1/users/', headers={'Content-Type': 'application/json'}, data=json.dumps(self.user))
self.assertEqual(res.status_code, 201)
api_token = json.loads(res.data).get('jwt_token')
res = self.client().delete('/api/v1/users/me', headers={'Content-Type': 'application/json', 'api-token': api_token})
self.assertEqual(res.status_code, 204)
def tearDown(self):
"""
Tear Down
"""
with self.app.app_context():
db.session.remove()
db.drop_all()
if __name__ == "__main__":
unittest.main()
# src/models/UserModel.py
from marshmallow import fields, Schema
import datetime
from . import db
class UserModel(db.Model):
"""
User Model
"""
# table name
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(128), nullable=False)
email = db.Column(db.String(128), unique=True, nullable=False)
password = db.Column(db.String(128), nullable=True)
created_at = db.Column(db.DateTime)
modified_at = db.Column(db.DateTime)
# class constructor
def __init__(self, data):
"""
Class constructor
"""
self.name = data.get('name')
self.email = data.get('email')
self.password = data.get('password')
self.created_at = datetime.datetime.utcnow()
self.modified_at = datetime.datetime.utcnow()
def save(self):
db.session.add(self)
db.session.commit()
def update(self, data):
for key, item in data.items():
setattr(self, key, item)
self.modified_at = datetime.datetime.utcnow()
db.session.commit()
def delete(self):
db.session.delete(self)
db.session.commit()
@staticmethod
def get_all_users():
return UserModel.query.all()
@staticmethod
def get_one_user(id):
return UserModel.query.get(id)
def __repr(self):
return '<id {}>'.format(self.id)
# src/models/UserModel.py
#####################
# existing code remain #
######################
from ..app import bcrypt # add this line
class UserModel(db.Model):
"""
User Model
"""
# table name
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
#####################
# existing code remain #
######################
# class constructor
def __init__(self, data):
"""
Class constructor
"""
self.name = data.get('name')
self.email = data.get('email')
self.password = self.__generate_hash(data.get('password')) # add this line
#####################
# existing code remain #
######################
def update(self, data):
for key, item in data.items():
if key == 'password': # add this new line
self.password = self.__generate_hash(value) # add this new line
setattr(self, key, item)
self.modified_at = datetime.datetime.utcnow()
db.session.commit()
#####################
# existing code remain #
######################
# add this new method
def __generate_hash(self, password):
return bcrypt.generate_password_hash(password, rounds=10).decode("utf-8")
# add this new method
def check_hash(self, password):
return bcrypt.check_password_hash(self.password, password)
#####################
# existing code remain #
######################
# src/models/UserModel.py
from marshmallow import fields, Schema
#####################
# existing code remains #
########################
from .BlogpostModel import BlogpostSchema
class UserModel(db.Model):
"""
User Model
"""
# table name
__tablename__ = 'users'
#####################
# existing code remains #
########################
modified_at = db.Column(db.DateTime)
blogposts = db.relationship('BlogpostModel', backref='users', lazy=True) # add this new line
#####################
# existing code remains #
########################
def __repr(self):
return '<id {}>'.format(self.id)
# add this class
class UserSchema(Schema):
"""
User Schema
"""
id = fields.Int(dump_only=True)
name = fields.Str(required=True)
email = fields.Email(required=True)
password = fields.Str(required=True)
created_at = fields.DateTime(dump_only=True)
modified_at = fields.DateTime(dump_only=True)
blogposts = fields.Nested(BlogpostSchema, many=True)
#/src/views/UserView
from flask import request, json, Response, Blueprint
from ..models.UserModel import UserModel, UserSchema
from ..shared.Authentication import Auth
user_api = Blueprint('users', __name__)
user_schema = UserSchema()
@user_api.route('/', methods=['POST'])
def create():
"""
Create User Function
"""
req_data = request.get_json()
data, error = user_schema.load(req_data)
if error:
return custom_response(error, 400)
# check if user already exist in the db
user_in_db = UserModel.get_user_by_email(data.get('email'))
if user_in_db:
message = {'error': 'User already exist, please supply another email address'}
return custom_response(message, 400)
user = UserModel(data)
user.save()
ser_data = user_schema.dump(user).data
token = Auth.generate_token(ser_data.get('id'))
return custom_response({'jwt_token': token}, 201)
def custom_response(res, status_code):
"""
Custom Response Function
"""
return Response(
mimetype="application/json",
response=json.dumps(res),
status=status_code
)
#/src/views/UserView
from flask import request, json, Response, Blueprint
from ..models.UserModel import UserModel, UserSchema
from ..shared.Authentication import Auth
user_api = Blueprint('user_api', __name__)
user_schema = UserSchema()
@user_api.route('/', methods=['POST'])
def create():
"""
Create User Function
"""
#####################
# existing code remain #
######################
return custom_response({'jwt_token': token}, 201)
@user_api.route('/login', methods=['POST'])
def login():
req_data = request.get_json()
data, error = user_schema.load(req_data, partial=True)
if error:
return custom_response(error, 400)
if not data.get('email') or not data.get('password'):
return custom_response({'error': 'you need email and password to sign in'}, 400)
user = UserModel.get_user_by_email(data.get('email'))
if not user:
return custom_response({'error': 'invalid credentials'}, 400)
if not user.check_hash(data.get('password')):
return custom_response({'error': 'invalid credentials'}, 400)
ser_data = user_schema.dump(user).data
token = Auth.generate_token(ser_data.get('id'))
return custom_response({'jwt_token': token}, 200)
#####################
# existing code remain #
######################
#/src/views/UserView
from flask import request, json, Response, Blueprint
from ..models.UserModel import UserModel, UserSchema
from ..shared.Authentication import Auth
user_api = Blueprint('user_api', __name__)
user_schema = UserSchema()
@user_api.route('/', methods=['POST'])
def create():
"""
Create User Function
"""
#####################
# existing code remain #
######################
return custom_response({'jwt_token': token}, 201)
# add this new method
@user_api.route('/', methods=['GET'])
@Auth.auth_required
def get_all():
users = UserModel.get_all_users()
ser_users = user_schema.dump(users, many=True).data
return custom_response(ser_users, 200)
@user_api.route('/login', methods=['POST'])
def login():
#####################
# existing code remain #
######################
return custom_response({'jwt_token': token}, 200)
def custom_response(res, status_code):
"""
Custom Response Function
"""
return Response(
mimetype="application/json",
response=json.dumps(res),
status=status_code
)
#/src/views/UserView
from flask import request, json, Response, Blueprint, g
from ..models.UserModel import UserModel, UserSchema
from ..shared.Authentication import Auth
user_api = Blueprint('user_api', __name__)
user_schema = UserSchema()
#####################
# existing code remains #
########################
@user_api.route('/<int:user_id>', methods=['GET'])
@Auth.auth_required
def get_a_user(user_id):
"""
Get a single user
"""
user = UserModel.get_one_user(user_id)
if not user:
return custom_response({'error': 'user not found'}, 404)
ser_user = user_schema.dump(user).data
return custom_response(ser_user, 200)
@user_api.route('/me', methods=['PUT'])
@Auth.auth_required
def update():
"""
Update me
"""
req_data = request.get_json()
data, error = user_schema.load(req_data, partial=True)
if error:
return custom_response(error, 400)
user = UserModel.get_one_user(g.user.get('id'))
user.update(data)
ser_user = user_schema.dump(user).data
return custom_response(ser_user, 200)
@user_api.route('/me', methods=['DELETE'])
@Auth.auth_required
def delete():
"""
Delete a user
"""
user = UserModel.get_one_user(g.user.get('id'))
user.delete()
return custom_response({'message': 'deleted'}, 204)
@user_api.route('/me', methods=['GET'])
@Auth.auth_required
def get_me():
"""
Get me
"""
user = UserModel.get_one_user(g.user.get('id'))
ser_user = user_schema.dump(user).data
return custom_response(ser_user, 200)
#####################
# existing code remains #
########################
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment