This is a starter template for your flask application. Instead of starting your application from bootstraps, have a starting point for your application.
- JWT authentication.
- Role-base access to API endpoint.
- Audit log for API.
- Pre-existing user management API
- Swagger-UI for development support
- app/
- database/
- logs/
- .gitignore
- main.py
- README.md
- requirements.txt
- The starting point of the application is
main.py
where you can change thehost, port, debug
for the application. - The
database/
folder contains the the startingschema
anddata
to work on. - The
logs/
folder contains daily log. - The
app/
is themain_module
of the application.
- app/
-- app_config/
-- config.py ## application config (databse, logs, jwt etc.)
-- decorators/
-- authorizer.py ## @decorator for authorization
-- enum/
-- user_role_enum.py ## USER_ROLES enum for authorization
-- orm/
-- routes/
-- user/
-- dao_service.py ## operation related to data-models
-- payload.py ## payload model for swagger documentation
-- response.py ## response model for swagger documentation
-- routes.py
-- validator.py
-
The
orm
directory holds all the data-models(sqlAlchemy)
for the project. -
The
routes
directory holds all the routes for the application. Each sub-folder represent different route module for application. -
Now you can continue creating routes by implementing
routes.py
logger = get_logger(__name__)
ns = api.namespace(
name=os.path.dirname(__file__).split(os.sep)[-1].replace('_', '-'),
description='API connected to user module',
ordered=False
)
- This above section setting up the
logger
to log and create the/user
route module (as the sub-folder name wasuser
).
@ns.route('/add', methods=['POST'])
class AddUser(Resource):
@ns.doc(security=SECURITY)
@ns.expect(*add_user_payload())
@ns.response(SUCCESS_CODE, INSERT_SUCCESS_MESSAGE, add_user_response())
@jwt_required()
@is_authorized([USER_ROLE.ADMIN])
def post(self, jwt_data):
@ns.route
creates/user/add
route where the request typePOST
@ns.doc(security=SECURITY)
Provide swagger-documentation, if API is authenticated.@ns.expect(*add_user_payload())
- This
@ns.expect
block create documentation regarding the need of API(payload & queryParams)
. All these payload related functions should be put inpayload.py
- This
@ns.response(SUCCESS_CODE, INSERT_SUCCESS_MESSAGE, add_user_response())
- This
@ns.response
block create documentation regarding the response of the API. All these response related functions should be put inresponse.py
- Change the
success status
andmessage
according to your application.
- This
@jwt_required()
to make API authenticated and also pass additional parameterjwt_data
to the mapped method.@is_authorized([USER_ROLE.ADMIN])
make sure which users are privileged to access the API based onUSER_ROLE
enum.
Depending on the API type the method name of the class is mapped to the corresponding API. For example
/add
API request type isPOST
so it will be mapped to thepost(self, jwt_data)
method of the class.
It is recommended to create individual class for each individual endpoints inside the
routes.py
try:
validator = AddUserValidator()
payload = validator.load(request.get_json())
user_id = add_user(payload)
return {'code': SUCCESS_CODE, 'message': INSERT_SUCCESS_MESSAGE}
except ValidationError as e:
return {
'code': VALIDATION_ERROR_CODE,
'message': VALIDATION_ERROR_MESSAGE,
'errors': e.normalized_messages()
}
- To validate request payload we use
marshmallow
package. - In the bellow example
AddUserValidator()
holds the validation logic and if invalid throwsValidationError
. - All the validation related classes should be put in
validator.py