Source code for stakeholders.app

"""
This module contains the app and app factory.
"""


import flask
import requests


[docs]def create_app(requester=requests, host="localhost", port="8079"): """ This is the app factory. It returns an instance of the app. The app is the intermediary between the API and the end-user's web browser. Parameters ---------- requester : Python library The library used to send requests to the API (`requests` for production and `flask.testing.FlaskClient` for testing). We need this contrivance only so we can use Flask's `testing` module for unit testing. host : str The name of the host on which the API runs (`localhost` by default). The app sends requests to the API's endpoints, and this forms part of the base URI. port : str The port on which the API listens (`8079` by default). The app sends requests to the API's endpoints, and this forms part of the base URI. Returns ------- app : Flask application object An instance of the app as a Flask application object. """ API = "http://{}:{}".format(host, port) ADD_STAKEHOLDER = "{}/api/v1/stakeholders/add".format(API) DELETE_STAKEHOLDER = "{}/api/v1/stakeholders/delete".format(API) SHOW_STAKEHOLDERS = "{}/api/v1/stakeholders/show".format(API) UPDATE_STAKEHOLDER = "{}/api/v1/stakeholders/update".format(API) ADD_DELIVERABLE = "{}/api/v1/deliverables/add".format(API) DELETE_DELIVERABLE = "{}/api/v1/deliverables/delete".format(API) SHOW_DELIVERABLES = "{}/api/v1/deliverables/show".format(API) UPDATE_DELIVERABLE = "{}/api/v1/deliverables/update".format(API) ADD_ASSOCIATION = "{}/api/v1/associations/add".format(API) DELETE_ASSOCIATION = "{}/api/v1/associations/delete".format(API) SHOW_ASSOCIATIONS = "{}/api/v1/associations/show".format(API) UPDATE_ASSOCIATION = "{}/api/v1/associations/update".format(API) SHOW_MANAGEMENT_PLAN = "{}/api/v1/management-plan/show".format(API) app = flask.Flask(__name__) @app.route("/") @app.route("/home") @app.route("/index") def index(): """ This is the endpoint for the index. It accepts a `GET` request. It returns HTML. """ return flask.render_template("index.html") @app.route("/stakeholders") def show_stakeholders(): """ This is the endpoint for showing stakeholders. It accepts a `GET` request. It returns HTML. """ # If it exists, then we attempt to obtain the value of the `id` # query parameter. id = flask.request.args.get("id") # If there is no `id`, then we request all stakeholders # from the API. # # Otherwise, we request a single stakeholder from the # API. if id is None: response = requester.get(SHOW_STAKEHOLDERS) else: response = requester.get( "{}?id={}".format(SHOW_STAKEHOLDERS, id) ) # We return `show-stakeholders.html`. return flask.render_template( "show-stakeholders.html", data=response.json() ) @app.route("/stakeholders/add", methods=["GET", "POST"]) def add_stakeholder(): """ This is the endpoint for adding a stakeholder. It accepts a `GET` or a `POST` request. It returns HTML. """ # On receiving a `GET` request, we return # `add-stakeholder.html`, which contains a form for # adding a stakeholder. if flask.request.method == "GET": return flask.render_template("add-stakeholder.html") # On receiving a `POST` request, we forward the # form data in the body of the request to the API. # This contains the end-user's request to add a stakeholder. # # We then redirect the end-user to `/stakeholders`. else: requester.post( ADD_STAKEHOLDER, data=flask.request.form ) return flask.redirect( flask.url_for("show_stakeholders") ) @app.route("/stakeholders/delete", methods=["POST"]) def delete_stakeholder(): """ This is the endpoint for deleting stakeholder. It accepts a `POST` request. It returns HTML. """ # On receiving a `POST` request, we forward the # form data in the body of the request to the API. # This contains the end-user's request to delete a stakeholder. requester.post( DELETE_STAKEHOLDER, data=flask.request.form ) # We redirect the end-user to `/stakeholders`. return flask.redirect( flask.url_for("show_stakeholders") ) @app.route("/stakeholders/update", methods=["GET", "POST"]) def update_stakeholder(): """ This is the endpoint for updating a stakeholder. It accepts a `GET` or a `POST` request. It returns HTML. """ # On receiving a `GET` request, we attempt to obtain the # value of the `id` query parameter. # # If there is no `id`, then we redirect the end-user to # `/stakeholders`. # # Otherwise, we request a single stakeholder from the # API. # # We then return `update-stakeholder.html`. if flask.request.method == "GET": id = flask.request.args.get("id") if id is None: return flask.redirect( flask.url_for("show_stakeholders") ) else: response = requester.get( "{}?id={}".format(SHOW_STAKEHOLDERS, id) ) return flask.render_template( "update-stakeholder.html", data=response.json() ) # On receiving a `POST` request, we forward the # form data in the body of the request to the API. # This contains the end-user's request to update a stakeholder. # # We then redirect the end-user to `/stakeholders`. else: requester.post( UPDATE_STAKEHOLDER, data=flask.request.form ) return flask.redirect( flask.url_for("show_stakeholders") ) @app.route("/deliverables") def show_deliverables(): """ This is the endpoint for showing deliverables. It accepts a `GET` request. It returns HTML. """ # If it exists, then we attempt to obtain the value of the `id` # query parameter. id = flask.request.args.get("id") # If there is no `id`, then we request all deliverables # from the API. # # Otherwise, we request a single deliverable from the # API. if id is None: response = requester.get(SHOW_DELIVERABLES) else: response = requester.get( "{}?id={}".format(SHOW_DELIVERABLES, id) ) # We return `show-deliverables.html`. return flask.render_template( "show-deliverables.html", data=response.json() ) @app.route("/deliverables/add", methods=["GET", "POST"]) def add_deliverable(): """ This is the endpoint for adding a deliverable. It accepts a `GET` or a `POST` request. It returns HTML. """ # On receiving a `GET` request, we return # `add-deliverable.html`, which contains a form for # adding a deliverable. if flask.request.method == "GET": return flask.render_template("add-deliverable.html") # On receiving a `POST` request, we forward the # form data in the body of the request to the API. # This contains the end-user's request to add a deliverable. # # We then redirect the end-user to `/deliverables`. else: requester.post( ADD_DELIVERABLE, data=flask.request.form ) return flask.redirect( flask.url_for("show_deliverables") ) @app.route("/deliverables/delete", methods=["POST"]) def delete_deliverable(): """ This is the endpoint for deleting a deliverable. It accepts a `POST` request. It returns HTML. """ # On receiving a `POST` request, we forward the # form data in the body of the request to the API. # This contains the end-user's request to delete a stakeholder. requester.post( DELETE_DELIVERABLE, data=flask.request.form ) # We redirect the end-user to `/deliverables`. return flask.redirect( flask.url_for("show_deliverables") ) @app.route("/deliverables/update", methods=["GET", "POST"]) def update_deliverable(): """ This is the endpoint for updating a deliverable. It accepts a `GET` or a `POST` request. It returns HTML. """ # On receiving a `GET` request, we attempt to obtain the # value of the `id` query parameter. # # If there is no `id`, then we redirect the end-user to # `/deliverables`. # # Otherwise, we request a single deliverable from the # API. # # We then return `update-deliverable.html`. if flask.request.method == "GET": id = flask.request.args.get("id") if id is None: return flask.redirect( flask.url_for("show_deliverables") ) else: response = requester.get( "{}?id={}".format(SHOW_DELIVERABLES, id) ) return flask.render_template( "update-deliverable.html", data=response.json() ) # On receiving a `POST` request, we forward the # form data in the body of the request to the API. # This contains the end-user's request to update a deliverable. # # We then redirect the end-user to `/deliverables`. else: requester.post( UPDATE_DELIVERABLE, data=flask.request.form ) return flask.redirect( flask.url_for("show_deliverables") ) @app.route("/associations") def show_associations(): """ This is the endpoint for showing associations. It accepts a `GET` request. It returns HTML. """ # If it exists, then we attempt to obtain the value of the `id` # query parameter. id = flask.request.args.get("id") # If there is no `id`, then we request all associations # from the API. # # Otherwise, we request a single association from the # API. if id is None: response = requester.get(SHOW_ASSOCIATIONS) else: response = requester.get( "{}?id={}".format(SHOW_ASSOCIATIONS, id) ) # We return `show-associations.html`. return flask.render_template( "show-associations.html", data=response.json() ) @app.route("/associations/add", methods=["GET", "POST"]) def add_association(): """ This is the endpoint for adding an association. It accepts a `GET` or a `POST` request. It returns HTML. """ # On receiving a `GET` request, we request stakeholders # and deliverables from the API. # # We then return `add-association.html`. if flask.request.method == "GET": stakeholders = requester.get(SHOW_STAKEHOLDERS) deliverables = requester.get(SHOW_DELIVERABLES) responses = { "stakeholders": stakeholders.json(), "deliverables": deliverables.json(), } return flask.render_template( "add-association.html", data=responses ) # On receiving a `POST` request, we forward the # form data in the body of the request to the API. # This contains the end-user's request to add an association. # # We then redirect the end-user to `/associations`. else: requester.post( ADD_ASSOCIATION, data=flask.request.form ) return flask.redirect( flask.url_for("show_associations") ) @app.route("/associations/delete", methods=["POST"]) def delete_association(): """ This is the endpoint for deleting an association. It accepts a `POST` request. It returns HTML. """ # On receiving a `POST` request, we forward the # form data in the body of the request to the API. # This contains the end-user's request to delete an association. requester.post( DELETE_ASSOCIATION, data=flask.request.form ) # We redirect the end-user to `/associations`. return flask.redirect( flask.url_for("show_associations") ) @app.route("/associations/update", methods=["GET", "POST"]) def update_association(): """ This is the endpoint for updating an association. It accepts a `GET` or a `POST` request. It returns HTML. """ # On receiving a `GET` request, we attempt to obtain the # value of the `id` query parameter. # # If there is no `id`, then we redirect the end-user to # `/associations`. # # Otherwise, we request all stakeholders, all deliverables, # and a single association from the API. # # We then return `update-association.html`. if flask.request.method == "GET": id = flask.request.args.get("id") if id is None: return flask.redirect( flask.url_for("show_associations") ) else: stakeholders = requester.get(SHOW_STAKEHOLDERS) deliverables = requester.get(SHOW_DELIVERABLES) associations = requester.get( "{}?id={}".format(SHOW_ASSOCIATIONS, id) ) responses = { "stakeholders": stakeholders.json(), "deliverables": deliverables.json(), "associations": associations.json() } return flask.render_template( "update-association.html", data=responses ) # On receiving a `POST` request, we forward the # form data in the body of the request to the API. # This contains the end-user's request to update an association. # # We then redirect the end-user to `/associations`. else: requester.post( UPDATE_ASSOCIATION, data=flask.request.form ) return flask.redirect( flask.url_for("show_associations") ) @app.route("/management-plan") def show_management_plan(): """ This is the endpoint for showing the management plan. It accepts a `GET` request. It returns HTML. """ # We request the management plan from the API. response = requester.get(SHOW_MANAGEMENT_PLAN) # We then return `show-management-plan.html`. return flask.render_template( "show-management-plan.html", data=response.json() ) return app