Example #1
0
def prepare_metrics(obj,
                    org_metric_lookup,
                    valid_levels=[],
                    parent_obj='ContentItem',
                    check_timeseries=True):
    """
    Validate a metric.
    """
    # check if metrics exist and are properly formatted.
    obj.update(obj.pop('metrics', {}))
    for k in obj.keys():
        m = org_metric_lookup.get(k)
        if not m:
            raise RequestError(
                "Metric '{}' does not exist at this level.".format(k))

        if m['faceted'] and not isinstance(obj[k], list):
            raise RequestError(
                "Metric '{}' is faceted but was not passed in as a list.".
                format(k))

        if m['faceted'] and not set(
                obj[k][0].keys()) == set(METRIC_FACET_KEYS):
            raise RequestError(
                "Metric '{}' is faceted, but it\'s elements are not properly formatted. "
                "Each facet must be a dictionary of '{\"facet\":\"facet_name\", \"value\": 1234}"
                .format(k))

        # parse number
        obj[k] = stats.parse_number(obj[k])
    return obj
Example #2
0
def prepare_metrics(
        obj,
        org_metric_lookup,
        valid_levels=[],
        parent_obj='ContentItem',
        check_timeseries=True
        ):
    """
    Validate a metric.
    """
    # check if metrics exist and are properly formatted.
    obj.update(obj.pop('metrics', {}))
    for k in obj.keys():
        m = org_metric_lookup.get(k)
        if not m:
            raise RequestError(
                "Metric '{}' does not exist at this level."
                .format(k))

        if m['faceted'] and not isinstance(obj[k], list):
            raise RequestError(
                "Metric '{}' is faceted but was not passed in as a list."
                .format(k))

        if m['faceted'] and not set(obj[k][0].keys()) == set(METRIC_FACET_KEYS):
            raise RequestError(
                "Metric '{}' is faceted, but it\'s elements are not properly formatted. "
                "Each facet must be a dictionary of '{\"facet\":\"facet_name\", \"value\": 1234}"
                .format(k))

        # parse number
        obj[k] = stats.parse_number(obj[k])
    return obj
Example #3
0
def _prepare_metrics(obj, metrics_lookup):
    """
    Given a lookup of all metrics this object can contain,
    validate the object and prepare for ingest.
    """
    # check if metrics exist and are properly formatted.
    obj.update(obj.pop('metrics', {}))
    for k in obj.keys():
        if k == 'datetime':
            continue

        # fetch from lookup
        m = metrics_lookup.get(k)
        if not m:
            raise RequestError(
                "Metric '{}' does not exist at this level."
                .format(k))

        # validate facet formatting.
        if m['faceted'] and not isinstance(obj[k], list):
            raise RequestError(
                "Metric '{}' is faceted but was not passed in as a list."
                .format(k))

        if m['faceted'] and len(obj[k]) \
           and not set(obj[k][0].keys()) == set(METRIC_FACET_KEYS):
            raise RequestError(
                "Metric '{}' is faceted, but it\'s elements are not properly formatted. "
                "Each facet must be a dictionary of '{\"facet\":\"facet_name\", \"value\": 1234}"
                .format(k))

        # remove empty facets
        if m['faceted'] and not len(obj[k]):
            obj.pop(k)

        # parse numbers.
        if not m['faceted']:
            obj[k] = stats.parse_number(obj[k])

        # parse facet values.
        else:
            for i, v in enumerate(obj[k]):
                obj[k][i]['value'] = \
                    stats.parse_number(obj[k][i]['value'])

    return obj
Example #4
0
def _prepare_metrics(obj, metrics_lookup):
    """
    Given a lookup of all metrics this object can contain,
    validate the object and prepare for ingest.
    """
    # check if metrics exist and are properly formatted.
    obj.update(obj.pop('metrics', {}))
    for k in obj.keys():
        if k == 'datetime':
            continue

        # fetch from lookup
        m = metrics_lookup.get(k)
        if not m:
            raise RequestError(
                "Metric '{}' does not exist at this level.".format(k))

        # validate facet formatting.
        if m['faceted'] and not isinstance(obj[k], list):
            raise RequestError(
                "Metric '{}' is faceted but was not passed in as a list.".
                format(k))

        if m['faceted'] and len(obj[k]) \
           and not set(obj[k][0].keys()) == set(METRIC_FACET_KEYS):
            raise RequestError(
                "Metric '{}' is faceted, but it\'s elements are not properly formatted. "
                "Each facet must be a dictionary of '{\"facet\":\"facet_name\", \"value\": 1234}"
                .format(k))

        # remove empty facets
        if m['faceted'] and not len(obj[k]):
            obj.pop(k)

        # parse numbers.
        if not m['faceted']:
            obj[k] = stats.parse_number(obj[k])

        # parse facet values.
        else:
            for i, v in enumerate(obj[k]):
                obj[k][i]['value'] = \
                    stats.parse_number(obj[k][i]['value'])

    return obj
Example #5
0
 def valid_numeric(self, key, opt):
     """
     Validate a numeric option.
     """
     try:
         return parse_number(opt)
     except:
         return RecipeSchemaError(
             "{} is an 'numeric' field but was passed '{}'."
             .format(key, opt))
Example #6
0
 def valid_numeric(self, key, opt):
     """
     Validate a numeric option.
     """
     try:
         return parse_number(opt)
     except:
         return RecipeSchemaError(
             "{} is an 'numeric' field but was passed '{}'."
             .format(key, opt))
Example #7
0
def list_metrics(user, org):

    # optionally filter by type/level/category
    include_recipes, exclude_recipes = \
        arg_list('recipes', default=[], typ=str, exclusions=True)
    include_sous_chefs, exclude_sous_chefs = \
        arg_list('sous_chefs', default=[], typ=str, exclusions=True)
    include_types, exclude_types = \
        arg_list('types', default=[], typ=str, exclusions=True)
    include_content_levels, exclude_content_levels = \
        arg_list('content_levels', default=[], typ=str, exclusions=True)
    include_org_levels, exclude_org_levels = \
        arg_list('org_levels', default=[], typ=str, exclusions=True)
    sort_field, direction = arg_sort('sort', default='display_name')
    faceted = arg_bool('faceted', default=None)

    # base query
    metric_query = Metric.query.join(Recipe).join(SousChef)

    # validate sort fields are part of Recipe object.
    if sort_field:
        validate_fields(Metric, fields=[sort_field], suffix='to sort by')

    # filter by recipes
    if len(include_recipes):
        slugs = []
        ids = []
        for r in include_recipes:
            try:
                i = parse_number(r)
                ids.append(i)
            except:
                slugs.append(r)

        metric_query = metric_query\
            .filter(or_(Recipe.id.in_(ids), Recipe.slug.in_(slugs)))

    if len(exclude_recipes):
        slugs = []
        ids = []
        for r in exclude_recipes:
            try:
                i = parse_number(r)
                ids.append(i)
            except:
                slugs.append(r)
        metric_query = metric_query\
            .filter(~or_(Recipe.id.in_(ids), Recipe.slug.in_(slugs)))

    # filter by sous-chefs
    if len(include_sous_chefs):
        slugs = []
        ids = []
        for r in include_sous_chefs:
            try:
                i = parse_number(r)
                ids.append(i)
            except:
                slugs.append(r)

        metric_query = metric_query\
            .filter(or_(SousChef.id.in_(ids), SousChef.slug.in_(slugs)))

    if len(exclude_sous_chefs):
        slugs = []
        ids = []
        for r in exclude_sous_chefs:
            try:
                i = parse_number(r)
                ids.append(i)
            except:
                slugs.append(r)

        metric_query = metric_query\
            .filter(~or_(SousChef.id.in_(ids), SousChef.slug.in_(slugs)))

    # filter by levels
    if len(include_types):
        metric_query = metric_query\
            .filter(Metric.type.in_(include_types))

    if len(exclude_types):
        metric_query = metric_query\
            .filter(~Metric.type.in_(exclude_types))

    # filter by levels
    if len(include_content_levels):
        metric_query = metric_query\
            .filter(Metric.content_levels.contains(include_content_levels))

    if len(exclude_content_levels):
        metric_query = metric_query\
            .filter(~Metric.content_levels.contains(exclude_content_levels))

    if len(include_org_levels):
        metric_query = metric_query\
            .filter(Metric.org_levels.contains(include_org_levels))

    if len(exclude_org_levels):
        metric_query = metric_query\
            .filter(~Metric.org_levels.contains(exclude_org_levels))

    # filter by faceted
    if faceted is not None:
        metric_query = metric_query\
            .filter(Metric.faceted == faceted)

    if sort_field:
        sort_obj = eval('Metric.{}.{}'.format(sort_field, direction))
        metric_query = metric_query.order_by(sort_obj())

    facets = defaultdict(Counter)

    metrics = []

    for m in metric_query.all():
        facets['recipes'][m.recipe.slug] += 1
        facets['types'][m.type] += 1
        if 'faceted' in facets:
            if m.faceted:
                facets['faceted'] += 1
        else:
            facets['faceted'] = 0
        for cl in m.content_levels:
            facets['content_levels'][cl] += 1
        for cl in m.org_levels:
            facets['org_levels'][cl] += 1

        metrics.append(m.to_dict())

    resp = {
        'metrics': metrics,
        'facets': facets
    }
    return jsonify(resp)