Source code for smif.http_api.register

import logging
import jinja2.exceptions
from flask import jsonify, render_template
from smif.exception import (
    SmifDataExistsError,
    SmifDataMismatchError,
    SmifDataNotFoundError,
)
from smif.http_api.crud import (
    DimensionAPI,
    ModelRunAPI,
    ScenarioAPI,
    SectorModelAPI,
    SmifAPI,
    SosModelAPI,
)


[docs]def register_routes(app): """Register plain routing""" @app.route("/") @app.route("/jobs/") @app.route("/jobs/<path:path>") @app.route("/configure") @app.route("/configure/<path:path>") def home(path=None): """Render single page""" try: return render_template("index.html") except jinja2.exceptions.TemplateNotFound as ex: logging.error(ex, exc_info=True) return """<!doctype html> <style>html, body { font-family: sans-serif; }</style> <h1>Error: smif app template not found</h1> <p>If you are running from a development build of smif, you may need to build the app:</p> <code><pre> cd ./src/smif/app npm install npm run build </pre> </code> <p>Otherwise, please report the issue, including as much detail as possible, on <a href="https://github.com/nismod/smif/issues">GitHub</a>.</p> """
[docs]def register_api_endpoints(app): """Register API calls (using pluggable views)""" register_api( app, SmifAPI, "smif_api", "/api/v1/smif/", key="key", key_type="string" ) register_api( app, ModelRunAPI, "model_run_api", "/api/v1/model_runs/", key="model_run_name", key_type="string", action="action", action_type="string", ) register_api( app, SosModelAPI, "sos_model_api", "/api/v1/sos_models/", key="sos_model_name", key_type="string", ) register_api( app, SectorModelAPI, "sector_model_api", "/api/v1/sector_models/", key="sector_model_name", key_type="string", ) register_api( app, ScenarioAPI, "scenario_api", "/api/v1/scenarios/", key="scenario_name", key_type="string", ) register_api( app, DimensionAPI, "dimension_api", "/api/v1/dimensions/", key="dimension_name", key_type="string", )
[docs]def register_error_handlers(app): """Handle expected errors""" @app.errorhandler(SmifDataExistsError) def handle_exists(error): """Return 400 Bad Request if data to be created already exists""" response = jsonify({"message": str(error)}) response.status_code = 400 return response @app.errorhandler(SmifDataMismatchError) def handle_mismatch(error): """Return 400 Bad Request if data and id/name are mismatched""" response = jsonify({"message": str(error)}) response.status_code = 400 return response @app.errorhandler(SmifDataNotFoundError) def handle_not_found(error): """Return 404 if data is not found""" response = jsonify({"message": str(error)}) response.status_code = 404 return response
[docs]def register_api( app, view, endpoint, url, key="id", key_type="int", action=None, action_type=None ): """Register a MethodView as an endpoint with CRUD operations at a URL""" view_func = view.as_view(endpoint) app.add_url_rule(url, defaults={key: None}, view_func=view_func, methods=["GET"]) app.add_url_rule(url, view_func=view_func, methods=["POST"]) if action: app.add_url_rule( "%s<%s:%s>/<%s:%s>" % (url, key_type, key, action_type, action), view_func=view_func, methods=["GET"], ) app.add_url_rule( "%s<%s:%s>/<%s:%s>" % (url, key_type, key, action_type, action), view_func=view_func, methods=["POST"], ) app.add_url_rule( "%s<%s:%s>" % (url, key_type, key), view_func=view_func, methods=["GET", "PUT", "DELETE"], )