Skip to content

Commit

Permalink
Added API via Flask-RestX
Browse files Browse the repository at this point in the history
  • Loading branch information
app-generator committed Dec 7, 2024
1 parent 47ff565 commit c96a75f
Show file tree
Hide file tree
Showing 20 changed files with 953 additions and 4 deletions.
2 changes: 1 addition & 1 deletion apps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def register_extensions(app):


def register_blueprints(app):
for module_name in ('authentication', 'home'):
for module_name in ('authentication', 'home', 'api'):
module = import_module('apps.{}.routes'.format(module_name))
app.register_blueprint(module.blueprint)

Expand Down
Empty file removed apps/api/.gitkeep
Empty file.
12 changes: 12 additions & 0 deletions apps/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# -*- encoding: utf-8 -*-
"""
Copyright (c) 2019 - present AppSeed.us
"""

from flask import Blueprint

blueprint = Blueprint(
'api_blueprint',
__name__,
url_prefix='/api'
)
85 changes: 85 additions & 0 deletions apps/api/controller/base_contoller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import flask
import traceback
from flask import jsonify
from apps.api.exception import InvalidUsage

app = flask.current_app

class BaseController:

# Set Json response
def send_response(self, data, status_code=200):
res = {
"data": data,
'status': status_code
}
resp = jsonify(res)
return resp


# Set success response.
def success(self, data, message ="", code =200):
"""form final respose format
Args:
data (dict/list): for single record it would be dictionary and for multiple records it would be list.
message (str): operation response message. Defaults to "".
code (int): Http response code. Defaults to 200.
Returns:
dictionary of response data
{
data: [],
message: "",
status: 200,
}
"""
res = {
"data": data,
"message": message,
'status': code
}
resp = jsonify(res)
return resp

# Set error response.
def error(self, e, code=422):
msg = str(e)
if isinstance(e, InvalidUsage):
msg = e.message

# app.logger.error(traceback.format_exc())
res = {
# 'error':{
# 'description': traceback.format_exc()
# },
"message": msg,
'status': code
}
return res, code


def errorGeneral(self, e, code=422):
msg = str(e)
if isinstance(e, InvalidUsage):
msg = e.message
res = {
"message": msg,
'status': code
}
return res, code
# msg = 'An exception occurred: {}'.format(error)
# res = {
# 'errors':msg,
# 'status': code
# }
# return res


def simple_response(self, message, status_code):
res = {
"message": message,
'status': status_code
}
resp = jsonify(res)
return resp
114 changes: 114 additions & 0 deletions apps/api/controller/product_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
from flask import request
from flask_restx import Resource
from apps.api.exception import InvalidUsage
from apps.models import Product
from apps.api.schemas.product_schema import ProductSchema, ProductUpdateSchema
from apps.api.controller.base_contoller import BaseController
from apps.api.service.product_service import ProductService
from apps.helpers import token_required
from apps.messages import Messages
message = Messages.message

# base controller
BaseController = BaseController()
# schemas
product_schema = ProductSchema()
products_schema = ProductSchema(many=True)
product_update_schema = ProductUpdateSchema()
# services
product_service = ProductService()


class ProductCreateList(Resource):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

@classmethod
@token_required
def post(self):
try:
request_data = request.json
# validate data
product_schema.load(request_data)
product = product_service.create(self.id, request_data)
data = product_schema.dump(product)

return BaseController.success(data, message['record_created_successfully'])
except InvalidUsage as e:
return BaseController.error(e, 422)
except BaseException as e:
return BaseController.errorGeneral(e)

@classmethod
def get(self):
try:
products = Product.query.order_by(Product.id.desc()).all()
response = products_schema.dump(products)

return BaseController.send_response(response, 200)
except InvalidUsage as e:
return BaseController.error(e, 422)
except BaseException as e:
return BaseController.errorGeneral(e)



class ProductList(Resource):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

@classmethod
def get(self, id):
try:
result = Product.find_by_id(id)
# check record exists or not
if result is None:
return BaseController.error(message['not_exists'], 422)

response = product_schema.dump(result)

return BaseController.send_response(response, 200)
except InvalidUsage as e:
return BaseController.error(e, 422)
except BaseException as e:
return BaseController.errorGeneral(e)

@classmethod
@token_required
def put(self, id):
try:
request_data = request.json
product = Product.find_by_id(id)
# check record exists or not
if product is None:
return BaseController.error(message['not_exists'], 422)

# validate data
product_update_schema.load(request_data)
product = product_service.update(self.id, id, request_data)
data = product_update_schema.dump(product)

return BaseController.success(data, message['record_updated'], 200)
except InvalidUsage as e:
return BaseController.error(e, 422)
except BaseException as e:
return BaseController.errorGeneral(e)

@classmethod
@token_required
def delete(self, id):
try:
product = Product.find_by_id(id)
# check record exists or not
if product is None:
return BaseController.error(message['not_exists'], 422)

product.delete()

return BaseController.simple_response(message['deleted_successfully'], 200)
except InvalidUsage as e:
return BaseController.error(e, 422)
except BaseException as e:
return BaseController.errorGeneral(e)
114 changes: 114 additions & 0 deletions apps/api/controller/sale_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
from flask_restx import Resource
from flask import request
from apps.api.exception import InvalidUsage
from apps.models import Sale
from apps.api.schemas.sale_schema import SaleSchema, SaleUpdateSchema
from apps.api.controller.base_contoller import BaseController
from apps.api.service.sale_service import SaleService
from apps.helpers import token_required
from apps.messages import Messages
message = Messages.message

# base controller
BaseController = BaseController()
# schemas
sale_schema = SaleSchema()
sales_schema = SaleSchema(many=True)
sale_update_schema = SaleUpdateSchema()
# services
sale_service = SaleService()


class SaleCreateList(Resource):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

@classmethod
@token_required
def post(self):
try:
request_data = request.json
# validate data
sale_schema.load(request_data)
sale = sale_service.create(self.id, request_data)
data = sale_schema.dump(sale)

return BaseController.success(data, message['record_created_successfully'], 201)
except InvalidUsage as e:
return BaseController.error(e, 422)
except BaseException as e:
return BaseController.errorGeneral(e)

@classmethod
def get(self):
try:
sales = Sale.query.order_by(Sale.id.desc()).all()
response = sales_schema.dump(sales)

return BaseController.send_response(response, 200)
except InvalidUsage as e:
return BaseController.error(e, 422)
except BaseException as e:
return BaseController.errorGeneral(e)



class SaleList(Resource):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

@classmethod
def get(self, id):
try:
result = Sale.find_by_id(id)
# check record exists or not
if result is None:
return BaseController.error(message['not_exists'], 422)

response = sale_schema.dump(result)

return BaseController.send_response(response, 200)
except InvalidUsage as e:
return BaseController.error(e, 422)
except BaseException as e:
return BaseController.errorGeneral(e)

@classmethod
@token_required
def put(self, id):
try:
request_data = request.json
sale = Sale.find_by_id(id)
# check record exists or not
if sale is None:
return BaseController.error(message['not_exists'], 422)

# validate data
sale_update_schema.load(request_data)
sale = sale_service.update(id, request_data)
data = sale_update_schema.dump(sale)

return BaseController.success(data, message['record_updated'], 200)
except InvalidUsage as e:
return BaseController.error(e, 422)
except BaseException as e:
return BaseController.errorGeneral(e)

@classmethod
@token_required
def delete(self, id):
try:
sale = Sale.find_by_id(id)
# check record exists or not
if sale is None:
return BaseController.error(message['not_exists'], 422)

sale.delete()

return BaseController.send_response(message['deleted_successfully'], 200)
except InvalidUsage as e:
return BaseController.error(e, 422)
except BaseException as e:
return BaseController.errorGeneral(e)
15 changes: 15 additions & 0 deletions apps/api/exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class InvalidUsage(Exception):
status_code = 400

def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload

def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message

return rv
19 changes: 19 additions & 0 deletions apps/api/routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- encoding: utf-8 -*-
"""
Copyright (c) 2019 - present AppSeed.us
"""
from apps.api import blueprint
from apps.api.controller.product_controller import ProductCreateList, ProductList
from apps.api.controller.sale_controller import SaleCreateList, SaleList
from flask_restx import Api

# from flask_restx import Api
api = Api(blueprint, title="API", description="API")

# Product api's end points.
api.add_resource(ProductCreateList, '/products/')
api.add_resource(ProductList, '/products/<int:id>')

# Sale api's end points.
api.add_resource(SaleCreateList, '/sales/')
api.add_resource(SaleList, '/sales/<int:id>')
Loading

0 comments on commit c96a75f

Please sign in to comment.