Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/checkup-airflow/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "checkup-airflow"
version = "0.1.1"
version = "0.2.0"
description = "Airflow metrics for checkup"
readme = "README.md"
requires-python = ">=3.12"
Expand Down
2 changes: 1 addition & 1 deletion plugins/checkup-bitbucket/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "checkup-bitbucket"
version = "0.1.1"
version = "0.2.0"
description = "Bitbucket metrics for checkup"
readme = "README.md"
requires-python = ">=3.12"
Expand Down
2 changes: 1 addition & 1 deletion plugins/checkup-conveyor/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "checkup-conveyor"
version = "0.2.1"
version = "0.3.0"
description = "Conveyor metrics for checkup"
readme = "README.md"
requires-python = ">=3.12"
Expand Down
14 changes: 4 additions & 10 deletions plugins/checkup-conveyor/src/checkup_conveyor/conveyor_metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import requests

from checkup import Context
from checkup.metric import Measurement, Metric
from checkup.measurement import Measurement, Measurements
from checkup_conveyor import ConveyorMetric

logger = logging.getLogger(__name__)
Expand All @@ -15,9 +15,7 @@ class ConveyorLastDeploymentTime(ConveyorMetric):
description: ClassVar[str] = "Time of the last deployment in Conveyor"
unit: ClassVar[str] = "timestamp"

def calculate(
self, context: Context, measurements: dict[type[Metric], Measurement]
) -> Measurement:
def calculate(self, context: Context, measurements: Measurements) -> Measurement:
proj_id = self.get_conveyor_project_id(context)
if proj_id is None:
return self.measure(value=None)
Expand All @@ -40,9 +38,7 @@ class ConveyorIsDirtyDeployment(ConveyorMetric):
description: ClassVar[str] = "True if the last deployment was dirty"
unit: ClassVar[str] = "boolean"

def calculate(
self, context: Context, measurements: dict[type[Metric], Measurement]
) -> Measurement:
def calculate(self, context: Context, measurements: Measurements) -> Measurement:
proj_id = self.get_conveyor_project_id(context)
if proj_id is None:
return self.measure(value=None)
Expand All @@ -66,9 +62,7 @@ class ConveyorLastRunStatus(ConveyorMetric):
description: ClassVar[str] = "Status of the last run in Conveyor"
unit: ClassVar[str] = "string"

def calculate(
self, context: Context, measurements: dict[type[Metric], Measurement]
) -> Measurement:
def calculate(self, context: Context, measurements: Measurements) -> Measurement:
proj_id = self.get_conveyor_project_id(context)
if proj_id is None:
return self.measure(value=None)
Expand Down
2 changes: 1 addition & 1 deletion plugins/checkup-dbt/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "checkup-dbt"
version = "0.2.2"
version = "0.3.0"
description = "dbt metrics for checkup"
readme = "README.md"
requires-python = ">=3.12"
Expand Down
15 changes: 6 additions & 9 deletions plugins/checkup-dbt/src/checkup_dbt/metrics/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
from dbt.artifacts.resources.types import NodeType
from dbt.contracts.graph.manifest import Manifest

from checkup.metric import Measurement, Metric
from checkup.measurement import Measurement, Measurements
from checkup.metric import Metric
from checkup.provider import Provider
from checkup.types import Context
from checkup_dbt.manifest_query import ManifestQuery
Expand Down Expand Up @@ -73,7 +74,7 @@ class DbtCountMetric(DbtMetric):
Base class for metrics that count nodes or columns.

Subclasses should define:
- name, description, unit (ClassVars)
- name, description, unit
- resource_type: The NodeType to filter by
- count_target: What to count (NODES or COLUMNS)
- predicate (optional): Filter function
Expand All @@ -87,9 +88,7 @@ class DbtCountMetric(DbtMetric):
predicate: ClassVar[Callable[..., bool] | None] = None
log_message: ClassVar[str] = "Found {value} items"

def calculate(
self, context: Context, measurements: dict[type[Metric], Measurement]
) -> Measurement:
def calculate(self, context: Context, measurements: Measurements) -> Measurement:
cls = type(self)
query = self.query(context).filter_by_type(cls.resource_type)

Expand All @@ -111,7 +110,7 @@ class DbtDiagnosticMetric(DbtMetric):
Produces both a count and a diagnostic listing the items.

Subclasses should define:
- name, description, unit (ClassVars)
- name, description, unit
- resource_type: The NodeType to filter by
- count_target: What to count (NODES or COLUMNS)
- predicate (optional): Filter function
Expand All @@ -128,9 +127,7 @@ class DbtDiagnosticMetric(DbtMetric):
log_message: ClassVar[str] = "Found {value} items"
max_diagnostic_items: ClassVar[int] = 50

def calculate(
self, context: Context, measurements: dict[type[Metric], Measurement]
) -> Measurement:
def calculate(self, context: Context, measurements: Measurements) -> Measurement:
cls = type(self)
query = self.query(context).filter_by_type(cls.resource_type)

Expand Down
6 changes: 3 additions & 3 deletions plugins/checkup-dbt/src/checkup_dbt/metrics/core/columns.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@


class DbtColumnsMetric(DbtCountMetric):
name: ClassVar[str] = "dbt_columns"
description: ClassVar[str] = "Total number of columns across all models"
unit: ClassVar[str] = "columns"
name: str = "dbt_columns"
description: str = "Total number of columns across all models"
unit: str = "columns"
count_target: ClassVar[CountTarget] = CountTarget.COLUMNS
log_message: ClassVar[str] = "Found {value} columns"
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@


class DbtColumnsWithDescriptionMetric(DbtCountMetric):
name: ClassVar[str] = "dbt_columns_with_description"
description: ClassVar[str] = "Number of columns with descriptions"
unit: ClassVar[str] = "columns"
name: str = "dbt_columns_with_description"
description: str = "Number of columns with descriptions"
unit: str = "columns"
count_target: ClassVar[CountTarget] = CountTarget.COLUMNS
predicate = column_has_description
log_message: ClassVar[str] = "Found {value} columns with descriptions"


class DbtColumnsWithoutDescriptionMetric(DbtCountMetric):
name: ClassVar[str] = "dbt_columns_without_description"
description: ClassVar[str] = "Number of columns without descriptions"
unit: ClassVar[str] = "columns"
name: str = "dbt_columns_without_description"
description: str = "Number of columns without descriptions"
unit: str = "columns"
count_target: ClassVar[CountTarget] = CountTarget.COLUMNS
predicate = column_without_description
log_message: ClassVar[str] = "Found {value} columns without descriptions"
6 changes: 3 additions & 3 deletions plugins/checkup-dbt/src/checkup_dbt/metrics/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


class DbtModelsMetric(DbtCountMetric):
name: ClassVar[str] = "dbt_models"
description: ClassVar[str] = "Total number of dbt models"
unit: ClassVar[str] = "models"
name: str = "dbt_models"
description: str = "Total number of dbt models"
unit: str = "models"
log_message: ClassVar[str] = "Found {value} models"
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@


class DbtModelsWithDescriptionMetric(DbtCountMetric):
name: ClassVar[str] = "dbt_models_with_description"
description: ClassVar[str] = "Number of models with descriptions"
unit: ClassVar[str] = "models"
name: str = "dbt_models_with_description"
description: str = "Number of models with descriptions"
unit: str = "models"
predicate = has_description
log_message: ClassVar[str] = "Found {value} models with descriptions"


class DbtModelsWithoutDescriptionMetric(DbtCountMetric):
name: ClassVar[str] = "dbt_models_without_description"
description: ClassVar[str] = "Number of models without descriptions"
unit: ClassVar[str] = "models"
name: str = "dbt_models_without_description"
description: str = "Number of models without descriptions"
unit: str = "models"
predicate = without_description
log_message: ClassVar[str] = "Found {value} models without descriptions"
6 changes: 3 additions & 3 deletions plugins/checkup-dbt/src/checkup_dbt/metrics/core/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@


class DbtTestsMetric(DbtCountMetric):
name: ClassVar[str] = "dbt_tests"
description: ClassVar[str] = "Total number of dbt tests"
unit: ClassVar[str] = "tests"
name: str = "dbt_tests"
description: str = "Total number of dbt tests"
unit: str = "tests"
resource_type: ClassVar[NodeType] = NodeType.Test
log_message: ClassVar[str] = "Found {value} tests"
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@


class DbtOutputColumnsWithoutDataTypeMetric(DbtDiagnosticMetric):
name: ClassVar[str] = "dbt_output_columns_without_data_type"
description: ClassVar[str] = "Number of columns in output models without data type"
unit: ClassVar[str] = "columns"
name: str = "dbt_output_columns_without_data_type"
description: str = "Number of columns in output models without data type"
unit: str = "columns"
predicate = staticmethod(
lambda n, _name, col: is_output_model(n) and col.data_type is None
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@


class DbtOutputModelsMetric(DbtCountMetric):
name: ClassVar[str] = "dbt_output_models"
description: ClassVar[str] = "Number of output models (non-internal schema)"
unit: ClassVar[str] = "models"
name: str = "dbt_output_models"
description: str = "Number of output models (non-internal schema)"
unit: str = "models"
predicate = is_output_model
log_message: ClassVar[str] = "Found {value} output models"
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@


class DbtOutputModelsWithDescriptionMetric(DbtCountMetric):
name: ClassVar[str] = "dbt_output_models_with_description"
description: ClassVar[str] = "Number of output models with descriptions"
unit: ClassVar[str] = "models"
name: str = "dbt_output_models_with_description"
description: str = "Number of output models with descriptions"
unit: str = "models"
predicate = staticmethod(lambda n: is_output_model(n) and has_description(n))
log_message: ClassVar[str] = "Found {value} output models with descriptions"


class DbtOutputModelsWithoutDescriptionMetric(DbtCountMetric):
name: ClassVar[str] = "dbt_output_models_without_description"
description: ClassVar[str] = "Number of output models without descriptions"
unit: ClassVar[str] = "models"
name: str = "dbt_output_models_without_description"
description: str = "Number of output models without descriptions"
unit: str = "models"
predicate = staticmethod(lambda n: is_output_model(n) and without_description(n))
log_message: ClassVar[str] = "Found {value} output models without descriptions"
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@


class DbtOutputModelsWithoutContractsMetric(DbtDiagnosticMetric):
name: ClassVar[str] = "dbt_output_models_without_contracts"
description: ClassVar[str] = "Number of output models without enforced contracts"
unit: ClassVar[str] = "models"
name: str = "dbt_output_models_without_contracts"
description: str = "Number of output models without enforced contracts"
unit: str = "models"
predicate = staticmethod(lambda n: is_output_model(n) and not n.contract.enforced)
diagnostic_prefix: ClassVar[str] = "Output models without enforced contracts"
log_message: ClassVar[str] = "Found {value} output models without contracts"
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import logging
from typing import ClassVar

import yaml

from checkup.metric import Measurement, Metric
from checkup.measurement import Measurement, Measurements
from checkup.types import Context
from checkup_dbt.metrics.base import DbtMetric

Expand All @@ -18,22 +17,21 @@ class DbtFlaggedPackagesMetric(DbtMetric):
Useful for identifying deprecated, insecure, or non-approved packages.

Example:
class DeprecatedPackagesMetric(DbtFlaggedPackagesMetric):
flagged_packages: list[str] = [
DbtFlaggedPackagesMetric(
flagged_packages=[
"https://github.com/org/deprecated-package",
"https://github.com/org/insecure-package",
]
)
"""

name: ClassVar[str] = "dbt_flagged_packages"
description: ClassVar[str] = "Number of flagged packages in packages.yml"
unit: ClassVar[str] = "packages"
name: str = "dbt_flagged_packages"
description: str = "Number of flagged packages in packages.yml"
unit: str = "packages"

flagged_packages: list[str]

def calculate(
self, context: Context, measurements: dict[type[Metric], Measurement]
) -> Measurement:
def calculate(self, context: Context, measurements: Measurements) -> Measurement:
project_dir = self.get_project_dir(context)
packages_path = project_dir / "packages.yml"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import logging
from typing import ClassVar

from dbt.artifacts.resources.types import NodeType

from checkup.metric import Measurement, Metric
from checkup.measurement import Measurement, Measurements
from checkup.types import Context
from checkup_dbt.metrics.base import DbtMetric, NamingConventionChecker

Expand All @@ -14,41 +13,28 @@ class DbtModelsNotAdheringToNamingConventionMetric(DbtMetric):
"""
Metric for checking model naming conventions.

This metric requires a custom checker function that defines the naming
convention. Use with_checker() to create a configured metric class.
"""

name: ClassVar[str] = "dbt_models_not_adhering_to_naming_convention"
description: ClassVar[str] = "Number of models not adhering to naming convention"
unit: ClassVar[str] = "models"
Requires a checker function that defines the naming convention.

@classmethod
def get_checker(cls) -> NamingConventionChecker:
raise NotImplementedError(
"Subclasses must override get_checker() or use with_checker() to create a metric"
Example:
DbtModelsNotAdheringToNamingConventionMetric(
name="dbt_staging_naming",
checker=lambda ctx, node: node.name.startswith("stg_")
)
"""

@classmethod
def with_checker(
cls, checker: NamingConventionChecker
) -> type["DbtModelsNotAdheringToNamingConventionMetric"]:
class CustomNamingConventionMetric(cls):
@classmethod
def get_checker(cls) -> NamingConventionChecker:
return checker
name: str = "dbt_models_not_adhering_to_naming_convention"
description: str = "Number of models not adhering to naming convention"
unit: str = "models"

return CustomNamingConventionMetric
checker: NamingConventionChecker

def calculate(
self, context: Context, measurements: dict[type[Metric], Measurement]
) -> Measurement:
def calculate(self, context: Context, measurements: Measurements) -> Measurement:
manifest = self.get_manifest(context)
checker = self.get_checker()

non_adhering_models = [
node.name
for node in manifest.nodes.values()
if node.resource_type == NodeType.Model and not checker(context, node)
if node.resource_type == NodeType.Model and not self.checker(context, node)
]

value = len(non_adhering_models)
Expand Down
Loading
Loading