Skip to content
Snippets Groups Projects
common.py 2.22 KiB
import functools
import logging

from flask import request, Response, current_app, g
from inventory_provider.tasks import common as tasks_common

logger = logging.getLogger(__name__)


def get_current_redis():
    if 'current_redis_db' in g:
        latch = tasks_common.get_latch(g.current_redis_db)
        if latch and latch['current'] == latch['this']:
            return g.current_redis_db
        logger.warning('switching to current redis db')

    config = current_app.config['INVENTORY_PROVIDER_CONFIG']
    g.current_redis_db = tasks_common.get_current_redis(config)
    return g.current_redis_db


def get_next_redis():
    if 'next_redis_db' in g:
        latch = tasks_common.get_latch(g.next_redis_db)
        if latch and latch['next'] == latch['this']:
            return g.next_redis_db
        logger.warning('switching to next redis db')

    config = current_app.config['INVENTORY_PROVIDER_CONFIG']
    g.next_redis_db = tasks_common.get_next_redis(config)
    return g.next_redis_db


def require_accepts_json(f):
    """
    used as a route handler decorator to return an error
    unless the request allows responses with type "application/json"
    :param f: the function to be decorated
    :return: the decorated function
    """
    @functools.wraps(f)
    def decorated_function(*args, **kwargs):
        # TODO: use best_match to disallow */* ...?
        if not request.accept_mimetypes.accept_json:
            return Response(
                response="response will be json",
                status=406,
                mimetype="text/html")
        return f(*args, **kwargs)
    return decorated_function


def after_request(response):
    """
    generic function to do additional logging of requests & responses
    :param response:
    :return:
    """
    if response.status_code != 200:

        try:
            data = response.data.decode('utf-8')
        except Exception:
            # never expected to happen, but we don't want any failures here
            logging.exception('INTERNAL DECODING ERROR')
            data = 'decoding error (see logs)'

        logger.warning('"%s %s" "%s" %s' % (
            request.method,
            request.path,
            data,
            str(response.status_code)))
    return response