Skip to content

Commit

Permalink
Add meta to measures, entities, and dimensions
Browse files Browse the repository at this point in the history
  • Loading branch information
DevonFulcher committed Oct 23, 2024
1 parent 98b5af5 commit e155c0d
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 9 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Features-20241023-113450.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Features
body: Support meta for dimensions, entities, and measures
time: 2024-10-23T11:34:50.577294-05:00
custom:
Author: DevonFulcher
Issue: None
18 changes: 17 additions & 1 deletion dbt_semantic_interfaces/implementations/elements/dimension.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from __future__ import annotations

from typing import Optional
from typing import Any, Dict, Optional

from pydantic import Field
from typing_extensions import override

from dbt_semantic_interfaces.implementations.base import (
HashableBaseModel,
ModelWithMetadataParsing,
)
from dbt_semantic_interfaces.implementations.metadata import PydanticMetadata
from dbt_semantic_interfaces.protocols.dimension import DimensionConfig
from dbt_semantic_interfaces.protocols.protocol_hint import ProtocolHint
from dbt_semantic_interfaces.references import (
DimensionReference,
TimeDimensionReference,
Expand Down Expand Up @@ -37,6 +42,16 @@ class PydanticDimensionTypeParams(HashableBaseModel):
validity_params: Optional[PydanticDimensionValidityParams] = None


class PydanticDimensionConfig(HashableBaseModel, ProtocolHint[DimensionConfig]):
"""PydanticDimension config."""

@override
def _implements_protocol(self) -> DimensionConfig: # noqa: D
return self

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


class PydanticDimension(HashableBaseModel, ModelWithMetadataParsing):
"""Describes a dimension."""

Expand All @@ -48,6 +63,7 @@ class PydanticDimension(HashableBaseModel, ModelWithMetadataParsing):
expr: Optional[str] = None
metadata: Optional[PydanticMetadata]
label: Optional[str] = None
config: Optional[PydanticDimensionConfig]

@property
def reference(self) -> DimensionReference: # noqa: D
Expand Down
18 changes: 17 additions & 1 deletion dbt_semantic_interfaces/implementations/elements/entity.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
from __future__ import annotations

from typing import Optional
from typing import Any, Dict, Optional

from pydantic import Field
from typing_extensions import override

from dbt_semantic_interfaces.implementations.base import (
HashableBaseModel,
ModelWithMetadataParsing,
)
from dbt_semantic_interfaces.implementations.metadata import PydanticMetadata
from dbt_semantic_interfaces.protocols.entity import EntityConfig
from dbt_semantic_interfaces.protocols.protocol_hint import ProtocolHint
from dbt_semantic_interfaces.references import EntityReference
from dbt_semantic_interfaces.type_enums import EntityType


class PydanticEntityConfig(HashableBaseModel, ProtocolHint[EntityConfig]):
"""PydanticEntity config."""

@override
def _implements_protocol(self) -> EntityConfig: # noqa: D
return self

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


class PydanticEntity(HashableBaseModel, ModelWithMetadataParsing):
"""Describes a entity."""

Expand All @@ -21,6 +36,7 @@ class PydanticEntity(HashableBaseModel, ModelWithMetadataParsing):
expr: Optional[str] = None
metadata: Optional[PydanticMetadata] = None
label: Optional[str] = None
config: Optional[PydanticEntityConfig]

@property
def reference(self) -> EntityReference: # noqa: D
Expand Down
17 changes: 16 additions & 1 deletion dbt_semantic_interfaces/implementations/elements/measure.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
from __future__ import annotations

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

from typing_extensions import override

from dbt_semantic_interfaces.implementations.base import (
HashableBaseModel,
ModelWithMetadataParsing,
)
from dbt_semantic_interfaces.implementations.metadata import PydanticMetadata
from dbt_semantic_interfaces.protocols.measure import MeasureConfig
from dbt_semantic_interfaces.protocols.protocol_hint import ProtocolHint
from dbt_semantic_interfaces.references import MeasureReference
from dbt_semantic_interfaces.type_enums import AggregationType
from dsi_pydantic_shim import Field
Expand All @@ -33,6 +37,16 @@ class PydanticMeasureAggregationParameters(HashableBaseModel):
use_approximate_percentile: bool = False


class PydanticMeasureConfig(HashableBaseModel, ProtocolHint[MeasureConfig]):
"""PydanticMeasure config."""

@override
def _implements_protocol(self) -> MeasureConfig: # noqa: D
return self

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


class PydanticMeasure(HashableBaseModel, ModelWithMetadataParsing):
"""Describes a measure."""

Expand All @@ -46,6 +60,7 @@ class PydanticMeasure(HashableBaseModel, ModelWithMetadataParsing):
non_additive_dimension: Optional[PydanticNonAdditiveDimensionParameters] = None
agg_time_dimension: Optional[str] = None
label: Optional[str] = None
config: Optional[PydanticMeasureConfig] = None

@property
def reference(self) -> MeasureReference: # noqa: D
Expand Down
17 changes: 16 additions & 1 deletion dbt_semantic_interfaces/protocols/dimension.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
from typing import Any, Dict, Optional, Protocol

from dbt_semantic_interfaces.protocols.metadata import Metadata
from dbt_semantic_interfaces.references import (
Expand Down Expand Up @@ -46,6 +46,16 @@ def validity_params(self) -> Optional[DimensionValidityParams]: # noqa: D
pass


class DimensionConfig(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 Dimension(Protocol):
"""Describes a dimension."""

Expand Down Expand Up @@ -107,3 +117,8 @@ def validity_params(self) -> Optional[DimensionValidityParams]:
def label(self) -> Optional[str]:
"""Returns a string representing a human readable label for the dimension."""
pass

@property
@abstractmethod
def config(self) -> Optional[DimensionConfig]: # noqa: D
pass
17 changes: 16 additions & 1 deletion dbt_semantic_interfaces/protocols/entity.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
from __future__ import annotations

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

from dbt_semantic_interfaces.references import EntityReference
from dbt_semantic_interfaces.type_enums import EntityType


class EntityConfig(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 Entity(Protocol):
"""Describes a entity."""

Expand Down Expand Up @@ -60,3 +70,8 @@ def is_linkable_entity_type(self) -> bool:
def label(self) -> Optional[str]:
"""Returns a string representing a human readable label for the entity."""
pass

@property
@abstractmethod
def config(self) -> Optional[EntityConfig]: # noqa: D
pass
17 changes: 16 additions & 1 deletion dbt_semantic_interfaces/protocols/measure.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.references import MeasureReference
from dbt_semantic_interfaces.type_enums import AggregationType
Expand Down Expand Up @@ -45,6 +45,16 @@ def use_approximate_percentile(self) -> bool: # noqa: D
pass


class MeasureConfig(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 Measure(Protocol):
"""Describes a measure.
Expand Down Expand Up @@ -98,3 +108,8 @@ def reference(self) -> MeasureReference:
def label(self) -> Optional[str]:
"""Returns a string representing a human readable label for the measure."""
pass

@property
@abstractmethod
def config(self) -> Optional[MeasureConfig]: # noqa: D
pass
11 changes: 9 additions & 2 deletions tests/parsing/test_semantic_model_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ def test_base_semantic_model_entity_parsing() -> None:
role: test_role
expr: example_id
label: {label}
config:
meta:
random: metadata
"""
)
file = YamlConfigFile(filepath="test_dir/inline_for_test", contents=yaml_contents)
Expand Down Expand Up @@ -206,7 +208,9 @@ def test_base_semantic_model_measure_parsing() -> None:
expr: example_input
description: {description}
label: {label}
config:
meta:
random: metadata
"""
)
file = YamlConfigFile(filepath="test_dir/inline_for_test", contents=yaml_contents)
Expand Down Expand Up @@ -325,6 +329,9 @@ def test_semantic_model_categorical_dimension_parsing() -> None:
- name: example_categorical_dimension
type: categorical
expr: dimension_input
config:
meta:
random: metadata
"""
)
file = YamlConfigFile(filepath="inline_for_test", contents=yaml_contents)
Expand Down
11 changes: 10 additions & 1 deletion tests/test_implements_satisfy_protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@

from dbt_semantic_interfaces.implementations.elements.dimension import (
PydanticDimension,
PydanticDimensionConfig,
PydanticDimensionTypeParams,
PydanticDimensionValidityParams,
)
from dbt_semantic_interfaces.implementations.elements.entity import PydanticEntity
from dbt_semantic_interfaces.implementations.elements.entity import (
PydanticEntity,
PydanticEntityConfig,
)
from dbt_semantic_interfaces.implementations.elements.measure import (
PydanticMeasure,
PydanticMeasureAggregationParameters,
PydanticMeasureConfig,
PydanticNonAdditiveDimensionParameters,
)
from dbt_semantic_interfaces.implementations.export import PydanticExport
Expand Down Expand Up @@ -66,6 +71,7 @@
expr=OPTIONAL_STR_STRATEGY,
metadata=OPTIONAL_METADATA_STRATEGY,
label=OPTIONAL_STR_STRATEGY,
config=builds(PydanticDimensionConfig),
)

DIMENSION_VALIDITY_PARAMS_STRATEGY = builds(
Expand All @@ -82,6 +88,7 @@
expr=OPTIONAL_STR_STRATEGY,
metadata=OPTIONAL_METADATA_STRATEGY,
label=OPTIONAL_STR_STRATEGY,
config=builds(PydanticDimensionConfig),
)

DIMENSION_STRATEGY = TIME_DIMENSION_STRATEGY | CATEGORICAL_DIMENSION_STRATEGY
Expand All @@ -93,6 +100,7 @@
expr=OPTIONAL_STR_STRATEGY,
metadata=OPTIONAL_METADATA_STRATEGY,
label=OPTIONAL_STR_STRATEGY,
config=builds(PydanticEntityConfig),
)

MEASURE_STRATEGY = builds(
Expand All @@ -104,6 +112,7 @@
non_additive_dimesnion=builds(PydanticNonAdditiveDimensionParameters) | none(),
agg_time_dimension=OPTIONAL_STR_STRATEGY,
label=OPTIONAL_STR_STRATEGY,
config=builds(PydanticMeasureConfig),
)

SEMANTIC_MODEL_STRATEGY = builds(
Expand Down

0 comments on commit e155c0d

Please sign in to comment.