Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose meta for Metric and SemanticModel #250

Merged
merged 6 commits into from
Mar 11, 2024
Merged
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
6 changes: 6 additions & 0 deletions .changes/unreleased/Features-20240120-000329.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Features
body: Expose meta on Metric/SemanticModel
time: 2024-01-20T00:03:29.80055-05:00
custom:
Author: WilliamDee
Issue: "251"
14 changes: 13 additions & 1 deletion dbt_semantic_interfaces/implementations/metric.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from __future__ import annotations

from typing import List, Optional, Sequence
from typing import Any, Dict, List, Optional, Sequence

from typing_extensions import override

from dbt_semantic_interfaces.enum_extension import assert_values_exhausted
from dbt_semantic_interfaces.errors import ParsingException
Expand All @@ -14,6 +16,7 @@
PydanticWhereFilterIntersection,
)
from dbt_semantic_interfaces.implementations.metadata import PydanticMetadata
from dbt_semantic_interfaces.protocols import MetricConfig, ProtocolHint
from dbt_semantic_interfaces.references import MeasureReference, MetricReference
from dbt_semantic_interfaces.type_enums import (
ConversionCalculationType,
Expand Down Expand Up @@ -170,6 +173,14 @@ class PydanticMetricTypeParams(HashableBaseModel):
input_measures: List[PydanticMetricInputMeasure] = Field(default_factory=list)


class PydanticMetricConfig(HashableBaseModel, ProtocolHint[MetricConfig]): # noqa: D
@override
def _implements_protocol(self) -> MetricConfig: # noqa: D
return self

meta: Dict[str, Any] = Field(default_factory=dict)


class PydanticMetric(HashableBaseModel, ModelWithMetadataParsing):
"""Describes a metric."""

Expand All @@ -180,6 +191,7 @@ class PydanticMetric(HashableBaseModel, ModelWithMetadataParsing):
filter: Optional[PydanticWhereFilterIntersection]
metadata: Optional[PydanticMetadata]
label: Optional[str] = None
config: Optional[PydanticMetricConfig]

@property
def input_measures(self) -> Sequence[PydanticMetricInputMeasure]:
Expand Down
14 changes: 12 additions & 2 deletions dbt_semantic_interfaces/implementations/semantic_model.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import Any, List, Optional, Sequence
from typing import Any, Dict, List, Optional, Sequence

from typing_extensions import override

Expand All @@ -15,6 +15,7 @@
from dbt_semantic_interfaces.protocols import (
ProtocolHint,
SemanticModel,
SemanticModelConfig,
SemanticModelDefaults,
)
from dbt_semantic_interfaces.references import (
Expand All @@ -24,7 +25,7 @@
SemanticModelReference,
TimeDimensionReference,
)
from dsi_pydantic_shim import validator
from dsi_pydantic_shim import Field, validator


class NodeRelation(HashableBaseModel):
Expand Down Expand Up @@ -76,6 +77,14 @@ def _implements_protocol(self) -> SemanticModelDefaults: # noqa: D
agg_time_dimension: Optional[str]


class PydanticSemanticModelConfig(HashableBaseModel, ProtocolHint[SemanticModelConfig]): # noqa: D
@override
def _implements_protocol(self) -> SemanticModelConfig: # noqa: D
return self

meta: Dict[str, Any] = Field(default_factory=dict)


class PydanticSemanticModel(HashableBaseModel, ModelWithMetadataParsing, ProtocolHint[SemanticModel]):
"""Describes a semantic model."""

Expand All @@ -95,6 +104,7 @@ def _implements_protocol(self) -> SemanticModel:
label: Optional[str] = None

metadata: Optional[PydanticMetadata]
config: Optional[PydanticSemanticModelConfig]

@property
def entity_references(self) -> List[LinkableElementReference]: # noqa: D
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,19 @@
],
"type": "object"
},
"metric_config_schema": {
"$id": "metric_config_schema",
"additionalProperties": false,
"properties": {
"meta": {
"propertyNames": {
"type": "string"
},
"type": "object"
}
},
"type": "object"
},
"metric_input_measure_schema": {
"$id": "metric_input_measure_schema",
"oneOf": [
Expand Down Expand Up @@ -383,6 +396,9 @@
"$id": "metric_schema",
"additionalProperties": false,
"properties": {
"config": {
"$ref": "#/definitions/metric_config_schema"
},
"description": {
"type": "string"
},
Expand Down Expand Up @@ -578,6 +594,19 @@
],
"type": "object"
},
"semantic_model_config_schema": {
"$id": "semantic_model_config_schema",
"additionalProperties": false,
"properties": {
"meta": {
"propertyNames": {
"type": "string"
},
"type": "object"
}
},
"type": "object"
},
"semantic_model_defaults_schema": {
"$id": "semantic_model_defaults_schema",
"additionalProperties": false,
Expand All @@ -593,6 +622,9 @@
"$id": "semantic_model_schema",
"additionalProperties": false,
"properties": {
"config": {
"$ref": "#/definitions/semantic_model_config_schema"
},
"defaults": {
"$ref": "#/definitions/semantic_model_defaults_schema"
},
Expand Down
22 changes: 22 additions & 0 deletions dbt_semantic_interfaces/parsing/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,15 @@
"required": ["name", "type"],
}

metric_config_schema = {
"$id": "metric_config_schema",
"type": "object",
"properties": {
"meta": {"type": "object", "propertyNames": {"type": "string"}},
},
"additionalProperties": False,
}

# Top level object schemas
metric_schema = {
"$id": "metric_schema",
Expand All @@ -266,6 +275,7 @@
"filter": {"$ref": "filter_schema"},
"description": {"type": "string"},
"label": {"type": "string"},
"config": {"$ref": "metric_config_schema"},
},
"additionalProperties": False,
"required": ["name", "type", "type_params"],
Expand Down Expand Up @@ -378,6 +388,15 @@
"additionalProperties": False,
}

semantic_model_config_schema = {
"$id": "semantic_model_config_schema",
"type": "object",
"properties": {
"meta": {"type": "object", "propertyNames": {"type": "string"}},
},
"additionalProperties": False,
}

semantic_model_schema = {
"$id": "semantic_model_schema",
"type": "object",
Expand All @@ -396,6 +415,7 @@
"dimensions": {"type": "array", "items": {"$ref": "dimension_schema"}},
"description": {"type": "string"},
"label": {"type": "string"},
"config": {"$ref": "semantic_model_config_schema"},
},
"additionalProperties": False,
"required": ["name"],
Expand Down Expand Up @@ -428,6 +448,8 @@
export_schema["$id"]: export_schema,
export_config_schema["$id"]: export_config_schema,
saved_query_query_params_schema["$id"]: saved_query_query_params_schema,
semantic_model_config_schema["$id"]: semantic_model_config_schema,
metric_config_schema["$id"]: metric_config_schema,
}

resources: List[Tuple[str, Resource]] = [(str(k), DRAFT7.create_resource(v)) for k, v in schema_store.items()]
Expand Down
2 changes: 2 additions & 0 deletions dbt_semantic_interfaces/protocols/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
ConstantPropertyInput,
ConversionTypeParams,
Metric,
MetricConfig,
MetricInput,
MetricInputMeasure,
MetricTimeWindow,
Expand All @@ -27,6 +28,7 @@
)
from dbt_semantic_interfaces.protocols.semantic_model import ( # noqa:F401
SemanticModel,
SemanticModelConfig,
SemanticModelDefaults,
SemanticModelT,
)
Expand Down
17 changes: 16 additions & 1 deletion dbt_semantic_interfaces/protocols/metric.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from abc import abstractmethod
from typing import Optional, Protocol, Sequence
from typing import Any, Dict, Optional, Protocol, Sequence

from dbt_semantic_interfaces.protocols.metadata import Metadata
from dbt_semantic_interfaces.protocols.where_filter import WhereFilterIntersection
Expand Down Expand Up @@ -228,6 +228,16 @@ def conversion_type_params(self) -> Optional[ConversionTypeParams]: # noqa: D
pass


class MetricConfig(Protocol): # noqa: D
"""The config property allows you to configure additional resources/metadata."""

@property
@abstractmethod
def meta(self) -> Dict[str, Any]:
"""The meta field can be used to set metadata for a resource."""
pass


class Metric(Protocol):
"""Describes a metric."""

Expand Down Expand Up @@ -280,6 +290,11 @@ def input_metrics(self) -> Sequence[MetricInput]:
def metadata(self) -> Optional[Metadata]: # noqa: D
pass

@property
@abstractmethod
def config(self) -> Optional[MetricConfig]: # noqa: D
pass

@property
@abstractmethod
def label(self) -> Optional[str]:
Expand Down
17 changes: 16 additions & 1 deletion dbt_semantic_interfaces/protocols/semantic_model.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from abc import abstractmethod
from typing import Optional, Protocol, Sequence, TypeVar
from typing import Any, Dict, Optional, Protocol, Sequence, TypeVar

from dbt_semantic_interfaces.protocols.dimension import Dimension
from dbt_semantic_interfaces.protocols.entity import Entity
Expand Down Expand Up @@ -50,6 +50,16 @@ def agg_time_dimension(self) -> Optional[str]:
pass


class SemanticModelConfig(Protocol): # noqa: D
"""The config property allows you to configure additional resources/metadata."""

@property
@abstractmethod
def meta(self) -> Dict[str, Any]:
"""The meta field can be used to set metadata for a resource."""
pass


class SemanticModel(Protocol):
"""Describes a semantic model."""

Expand Down Expand Up @@ -159,6 +169,11 @@ def reference(self) -> SemanticModelReference:
def metadata(self) -> Optional[Metadata]: # noqa: D
pass

@property
@abstractmethod
def config(self) -> Optional[SemanticModelConfig]: # noqa: D
pass

@abstractmethod
def checked_agg_time_dimension_for_measure(self, measure_reference: MeasureReference) -> TimeDimensionReference:
"""Returns the `TimeDimensionReference` what a measure should use for it's `agg_time_dimension`.
Expand Down
3 changes: 3 additions & 0 deletions tests/parsing/test_metric_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ def test_base_metric_parsing() -> None:
type: {metric_type.value}
description: {description}
label: {label}
config:
meta:
random: metadata
type_params:
measure:
name: metadata_test_measure
Expand Down
3 changes: 3 additions & 0 deletions tests/parsing/test_semantic_model_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ def test_base_semantic_model_parsing() -> None:
node_relation:
alias: source_table
schema_name: some_schema
config:
meta:
test_metadata: random
"""
)
file = YamlConfigFile(filepath="test_dir/inline_for_test", contents=yaml_contents)
Expand Down
2 changes: 2 additions & 0 deletions tests/test_implements_satisfy_protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from dbt_semantic_interfaces.implementations.metric import (
PydanticConversionTypeParams,
PydanticMetric,
PydanticMetricConfig,
PydanticMetricInput,
PydanticMetricInputMeasure,
PydanticMetricTypeParams,
Expand Down Expand Up @@ -117,6 +118,7 @@
filter=builds(PydanticWhereFilter) | none(),
metadata=OPTIONAL_METADATA_STRATEGY,
label=OPTIONAL_STR_STRATEGY,
config=builds(PydanticMetricConfig),
)

SAVED_QUERY_STRATEGY = builds(
Expand Down
Loading