Skip to content
Snippets Groups Projects
update.py 2.02 KiB
import json
import datetime
from flask import jsonify, Response
from concurrent.futures import ThreadPoolExecutor
from json.decoder import JSONDecodeError
from flask import Blueprint, current_app
from brian_dashboard_manager.routes import common
from brian_dashboard_manager.grafana.provision import provision_maybe
from brian_dashboard_manager import CONFIG_KEY
from brian_dashboard_manager.config import STATE_PATH


routes = Blueprint("update", __name__)

UPDATE_RESPONSE_SCHEMA = {
    '$schema': 'http://json-schema.org/draft-07/schema#',
    'type': 'object',
    'properties': {
        'message': {
            'type': 'string'
        }
    }
}


@routes.after_request
def after_request(resp):
    return common.after_request(resp)


def should_provision():
    try:
        with open(STATE_PATH, 'r+') as f:
            try:
                state = json.load(f)
            except JSONDecodeError:
                state = {}

            provisioning = state.get('provisioning', False)
            timestamp = datetime.datetime.fromtimestamp(
                state.get('timestamp', 1))

            can_provision = not provisioning
            return can_provision, timestamp
    except FileNotFoundError:
        with open(STATE_PATH, 'w') as f:
            return True, None


@routes.route('/', methods=['GET'])
def update():
    """
    This resource is used to trigger the provisioning to Grafana.

    It responds to the request immediately after starting
    the provisioning process.

    The response will be formatted according to the following schema:

    .. asjson::
       brian_dashboard_manager.routes.update.UPDATE_RESPONSE_SCHEMA

    :return: json
    """
    should, timestamp = should_provision()
    if should:
        executor = ThreadPoolExecutor(max_workers=1)
        executor.submit(provision_maybe, current_app.config[CONFIG_KEY])
        return jsonify({'data': {'message': 'Provisioning dashboards!'}})
    else:
        message = f'Provision already in progress since {timestamp}'
        return Response(message, status=503)