From f6fea48430784bb072d5d6f77e0ae742b4413bbd Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Wed, 23 Oct 2024 12:30:38 -0500 Subject: [PATCH 01/11] Add meta to measures, entities, and dimensions --- .../unreleased/Features-20241023-113450.yaml | 6 +++ .../implementations/elements/dimension.py | 18 ++++++- .../implementations/elements/entity.py | 18 ++++++- .../implementations/elements/measure.py | 17 ++++++- .../default_explicit_schema.json | 48 +++++++++++++++++++ dbt_semantic_interfaces/parsing/schemas.py | 34 +++++++++++++ .../protocols/dimension.py | 17 ++++++- dbt_semantic_interfaces/protocols/entity.py | 17 ++++++- dbt_semantic_interfaces/protocols/measure.py | 17 ++++++- tests/parsing/test_semantic_model_parsing.py | 11 ++++- tests/test_implements_satisfy_protocols.py | 11 ++++- 11 files changed, 205 insertions(+), 9 deletions(-) create mode 100644 .changes/unreleased/Features-20241023-113450.yaml diff --git a/.changes/unreleased/Features-20241023-113450.yaml b/.changes/unreleased/Features-20241023-113450.yaml new file mode 100644 index 00000000..0eda8b80 --- /dev/null +++ b/.changes/unreleased/Features-20241023-113450.yaml @@ -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 diff --git a/dbt_semantic_interfaces/implementations/elements/dimension.py b/dbt_semantic_interfaces/implementations/elements/dimension.py index c3cfa2e4..c75d6852 100644 --- a/dbt_semantic_interfaces/implementations/elements/dimension.py +++ b/dbt_semantic_interfaces/implementations/elements/dimension.py @@ -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, @@ -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.""" @@ -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 diff --git a/dbt_semantic_interfaces/implementations/elements/entity.py b/dbt_semantic_interfaces/implementations/elements/entity.py index ac98e4db..7c647ac1 100644 --- a/dbt_semantic_interfaces/implementations/elements/entity.py +++ b/dbt_semantic_interfaces/implementations/elements/entity.py @@ -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.""" @@ -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 diff --git a/dbt_semantic_interfaces/implementations/elements/measure.py b/dbt_semantic_interfaces/implementations/elements/measure.py index 5da1da4f..c98bb559 100644 --- a/dbt_semantic_interfaces/implementations/elements/measure.py +++ b/dbt_semantic_interfaces/implementations/elements/measure.py @@ -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 @@ -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.""" @@ -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 diff --git a/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json b/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json index 613bffd7..d00a3736 100644 --- a/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json +++ b/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json @@ -135,6 +135,19 @@ ], "type": "object" }, + "dimension_config_schema": { + "$id": "dimension_config_schema", + "additionalProperties": false, + "properties": { + "meta": { + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, "dimension_schema": { "$id": "dimension_schema", "additionalProperties": false, @@ -151,6 +164,9 @@ } ], "properties": { + "config": { + "$ref": "#/definitions/dimension_config_schema" + }, "description": { "type": "string" }, @@ -227,10 +243,26 @@ ], "type": "object" }, + "entity_config_schema": { + "$id": "entity_config_schema", + "additionalProperties": false, + "properties": { + "meta": { + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, "entity_schema": { "$id": "entity_schema", "additionalProperties": false, "properties": { + "config": { + "$ref": "#/definitions/entity_config_schema" + }, "entity": { "type": "string" }, @@ -337,6 +369,19 @@ "type" ] }, + "measure_config_schema": { + "$id": "measure_config_schema", + "additionalProperties": false, + "properties": { + "meta": { + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, "measure_schema": { "$id": "measure_schema", "additionalProperties": false, @@ -370,6 +415,9 @@ "pattern": "(?!.*__).*^[a-z][a-z0-9_]*[a-z0-9]$", "type": "string" }, + "config": { + "$ref": "#/definitions/measure_config_schema" + }, "create_metric": { "type": "boolean" }, diff --git a/dbt_semantic_interfaces/parsing/schemas.py b/dbt_semantic_interfaces/parsing/schemas.py index 66652535..bd981349 100644 --- a/dbt_semantic_interfaces/parsing/schemas.py +++ b/dbt_semantic_interfaces/parsing/schemas.py @@ -161,6 +161,16 @@ "additionalProperties": False, } + +entity_config_schema = { + "$id": "entity_config_schema", + "type": "object", + "properties": { + "meta": {"type": "object", "propertyNames": {"type": "string"}}, + }, + "additionalProperties": False, +} + entity_schema = { "$id": "entity_schema", "type": "object", @@ -174,6 +184,7 @@ "expr": {"type": ["string", "boolean"]}, "entity": {"type": "string"}, "label": {"type": "string"}, + "config": {"$ref": "entity_config_schema"}, }, "additionalProperties": False, "required": ["name", "type"], @@ -226,6 +237,15 @@ "additionalProperties": False, } +measure_config_schema = { + "$id": "measure_config_schema", + "type": "object", + "properties": { + "meta": {"type": "object", "propertyNames": {"type": "string"}}, + }, + "additionalProperties": False, +} + measure_schema = { "$id": "measure_schema", "type": "object", @@ -248,11 +268,21 @@ }, "description": {"type": "string"}, "label": {"type": "string"}, + "config": {"$ref": "measure_config_schema"}, }, "additionalProperties": False, "required": ["name", "agg"], } +dimension_config_schema = { + "$id": "dimension_config_schema", + "type": "object", + "properties": { + "meta": {"type": "object", "propertyNames": {"type": "string"}}, + }, + "additionalProperties": False, +} + dimension_schema = { "$id": "dimension_schema", "type": "object", @@ -267,6 +297,7 @@ "expr": {"type": ["string", "boolean"]}, "type_params": {"$ref": "dimension_type_params_schema"}, "label": {"type": "string"}, + "config": {"$ref": "dimension_config_schema"}, }, # dimension must have type_params if its a time dimension "anyOf": [{"not": {"$ref": "#/definitions/is-time-dimension"}}, {"required": ["type_params"]}], @@ -529,6 +560,9 @@ 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, + dimension_config_schema["$id"]: dimension_config_schema, + entity_config_schema["$id"]: entity_config_schema, + measure_config_schema["$id"]: measure_config_schema, } resources: List[Tuple[str, Resource]] = [(str(k), DRAFT7.create_resource(v)) for k, v in schema_store.items()] diff --git a/dbt_semantic_interfaces/protocols/dimension.py b/dbt_semantic_interfaces/protocols/dimension.py index 5cf8cbfe..5af912f7 100644 --- a/dbt_semantic_interfaces/protocols/dimension.py +++ b/dbt_semantic_interfaces/protocols/dimension.py @@ -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 ( @@ -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.""" @@ -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 diff --git a/dbt_semantic_interfaces/protocols/entity.py b/dbt_semantic_interfaces/protocols/entity.py index 356e6803..591da359 100644 --- a/dbt_semantic_interfaces/protocols/entity.py +++ b/dbt_semantic_interfaces/protocols/entity.py @@ -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.""" @@ -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 diff --git a/dbt_semantic_interfaces/protocols/measure.py b/dbt_semantic_interfaces/protocols/measure.py index a7588cfb..05075dab 100644 --- a/dbt_semantic_interfaces/protocols/measure.py +++ b/dbt_semantic_interfaces/protocols/measure.py @@ -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 @@ -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. @@ -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 diff --git a/tests/parsing/test_semantic_model_parsing.py b/tests/parsing/test_semantic_model_parsing.py index 8faec41f..1ab89853 100644 --- a/tests/parsing/test_semantic_model_parsing.py +++ b/tests/parsing/test_semantic_model_parsing.py @@ -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) @@ -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) @@ -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) diff --git a/tests/test_implements_satisfy_protocols.py b/tests/test_implements_satisfy_protocols.py index b37b5ca7..87771816 100644 --- a/tests/test_implements_satisfy_protocols.py +++ b/tests/test_implements_satisfy_protocols.py @@ -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 @@ -66,6 +71,7 @@ expr=OPTIONAL_STR_STRATEGY, metadata=OPTIONAL_METADATA_STRATEGY, label=OPTIONAL_STR_STRATEGY, + config=builds(PydanticDimensionConfig), ) DIMENSION_VALIDITY_PARAMS_STRATEGY = builds( @@ -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 @@ -93,6 +100,7 @@ expr=OPTIONAL_STR_STRATEGY, metadata=OPTIONAL_METADATA_STRATEGY, label=OPTIONAL_STR_STRATEGY, + config=builds(PydanticEntityConfig), ) MEASURE_STRATEGY = builds( @@ -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( From 44daf5935526922b1bc5ce019714562b6f98e249 Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Thu, 24 Oct 2024 12:54:26 -0500 Subject: [PATCH 02/11] Consolidated meta to use SemanticLayerElementConfig --- .../implementations/element_config.py | 18 +++++++++++++++ .../implementations/elements/dimension.py | 22 +++++-------------- .../implementations/elements/entity.py | 22 +++++-------------- .../implementations/elements/measure.py | 21 +++++------------- .../protocols/dimension.py | 15 +++---------- dbt_semantic_interfaces/protocols/entity.py | 15 +++---------- dbt_semantic_interfaces/protocols/measure.py | 15 +++---------- dbt_semantic_interfaces/protocols/meta.py | 12 ++++++++++ tests/parsing/test_semantic_model_parsing.py | 8 +++---- tests/test_implements_satisfy_protocols.py | 18 +++++++-------- 10 files changed, 66 insertions(+), 100 deletions(-) create mode 100644 dbt_semantic_interfaces/implementations/element_config.py create mode 100644 dbt_semantic_interfaces/protocols/meta.py diff --git a/dbt_semantic_interfaces/implementations/element_config.py b/dbt_semantic_interfaces/implementations/element_config.py new file mode 100644 index 00000000..e99237ca --- /dev/null +++ b/dbt_semantic_interfaces/implementations/element_config.py @@ -0,0 +1,18 @@ +from typing import Any, Dict + +from pydantic import Field +from typing_extensions import override + +from dbt_semantic_interfaces.implementations.base import HashableBaseModel +from dbt_semantic_interfaces.protocols.meta import ConfigMeta +from dbt_semantic_interfaces.protocols.protocol_hint import ProtocolHint + + +class SemanticLayerElementConfig(HashableBaseModel, ProtocolHint[ConfigMeta]): + """PydanticDimension config.""" + + @override + def _implements_protocol(self) -> ConfigMeta: # noqa: D + return self + + meta: Dict[str, Any] = Field(default_factory=dict) diff --git a/dbt_semantic_interfaces/implementations/elements/dimension.py b/dbt_semantic_interfaces/implementations/elements/dimension.py index c75d6852..ddbcdca9 100644 --- a/dbt_semantic_interfaces/implementations/elements/dimension.py +++ b/dbt_semantic_interfaces/implementations/elements/dimension.py @@ -1,17 +1,15 @@ from __future__ import annotations -from typing import Any, Dict, Optional - -from pydantic import Field -from typing_extensions import override +from typing import Optional from dbt_semantic_interfaces.implementations.base import ( HashableBaseModel, ModelWithMetadataParsing, ) +from dbt_semantic_interfaces.implementations.element_config import ( + SemanticLayerElementConfig, +) 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, @@ -42,16 +40,6 @@ 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.""" @@ -63,7 +51,7 @@ class PydanticDimension(HashableBaseModel, ModelWithMetadataParsing): expr: Optional[str] = None metadata: Optional[PydanticMetadata] label: Optional[str] = None - config: Optional[PydanticDimensionConfig] + config: Optional[SemanticLayerElementConfig] @property def reference(self) -> DimensionReference: # noqa: D diff --git a/dbt_semantic_interfaces/implementations/elements/entity.py b/dbt_semantic_interfaces/implementations/elements/entity.py index 7c647ac1..2496eaea 100644 --- a/dbt_semantic_interfaces/implementations/elements/entity.py +++ b/dbt_semantic_interfaces/implementations/elements/entity.py @@ -1,31 +1,19 @@ from __future__ import annotations -from typing import Any, Dict, Optional - -from pydantic import Field -from typing_extensions import override +from typing import Optional from dbt_semantic_interfaces.implementations.base import ( HashableBaseModel, ModelWithMetadataParsing, ) +from dbt_semantic_interfaces.implementations.element_config import ( + SemanticLayerElementConfig, +) 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.""" @@ -36,7 +24,7 @@ class PydanticEntity(HashableBaseModel, ModelWithMetadataParsing): expr: Optional[str] = None metadata: Optional[PydanticMetadata] = None label: Optional[str] = None - config: Optional[PydanticEntityConfig] + config: Optional[SemanticLayerElementConfig] @property def reference(self) -> EntityReference: # noqa: D diff --git a/dbt_semantic_interfaces/implementations/elements/measure.py b/dbt_semantic_interfaces/implementations/elements/measure.py index c98bb559..08b39db0 100644 --- a/dbt_semantic_interfaces/implementations/elements/measure.py +++ b/dbt_semantic_interfaces/implementations/elements/measure.py @@ -1,16 +1,15 @@ from __future__ import annotations -from typing import Any, Dict, List, Optional - -from typing_extensions import override +from typing import List, Optional from dbt_semantic_interfaces.implementations.base import ( HashableBaseModel, ModelWithMetadataParsing, ) +from dbt_semantic_interfaces.implementations.element_config import ( + SemanticLayerElementConfig, +) 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 @@ -37,16 +36,6 @@ 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.""" @@ -60,7 +49,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 + config: Optional[SemanticLayerElementConfig] = None @property def reference(self) -> MeasureReference: # noqa: D diff --git a/dbt_semantic_interfaces/protocols/dimension.py b/dbt_semantic_interfaces/protocols/dimension.py index 5af912f7..474a1753 100644 --- a/dbt_semantic_interfaces/protocols/dimension.py +++ b/dbt_semantic_interfaces/protocols/dimension.py @@ -1,8 +1,9 @@ from __future__ import annotations from abc import abstractmethod -from typing import Any, Dict, Optional, Protocol +from typing import Optional, Protocol +from dbt_semantic_interfaces.protocols.meta import ConfigMeta from dbt_semantic_interfaces.protocols.metadata import Metadata from dbt_semantic_interfaces.references import ( DimensionReference, @@ -46,16 +47,6 @@ 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.""" @@ -120,5 +111,5 @@ def label(self) -> Optional[str]: @property @abstractmethod - def config(self) -> Optional[DimensionConfig]: # noqa: D + def config(self) -> Optional[ConfigMeta]: # noqa: D pass diff --git a/dbt_semantic_interfaces/protocols/entity.py b/dbt_semantic_interfaces/protocols/entity.py index 591da359..c614ac9d 100644 --- a/dbt_semantic_interfaces/protocols/entity.py +++ b/dbt_semantic_interfaces/protocols/entity.py @@ -1,22 +1,13 @@ from __future__ import annotations from abc import abstractmethod -from typing import Any, Dict, Optional, Protocol +from typing import Optional, Protocol +from dbt_semantic_interfaces.protocols.meta import ConfigMeta 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.""" @@ -73,5 +64,5 @@ def label(self) -> Optional[str]: @property @abstractmethod - def config(self) -> Optional[EntityConfig]: # noqa: D + def config(self) -> Optional[ConfigMeta]: # noqa: D pass diff --git a/dbt_semantic_interfaces/protocols/measure.py b/dbt_semantic_interfaces/protocols/measure.py index 05075dab..b505cffd 100644 --- a/dbt_semantic_interfaces/protocols/measure.py +++ b/dbt_semantic_interfaces/protocols/measure.py @@ -1,8 +1,9 @@ from __future__ import annotations from abc import abstractmethod -from typing import Any, Dict, Optional, Protocol, Sequence +from typing import Optional, Protocol, Sequence +from dbt_semantic_interfaces.protocols.meta import ConfigMeta from dbt_semantic_interfaces.references import MeasureReference from dbt_semantic_interfaces.type_enums import AggregationType @@ -45,16 +46,6 @@ 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. @@ -111,5 +102,5 @@ def label(self) -> Optional[str]: @property @abstractmethod - def config(self) -> Optional[MeasureConfig]: # noqa: D + def config(self) -> Optional[ConfigMeta]: # noqa: D pass diff --git a/dbt_semantic_interfaces/protocols/meta.py b/dbt_semantic_interfaces/protocols/meta.py new file mode 100644 index 00000000..c2b5d208 --- /dev/null +++ b/dbt_semantic_interfaces/protocols/meta.py @@ -0,0 +1,12 @@ +from abc import abstractmethod +from typing import Any, Dict, Protocol + + +class ConfigMeta(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 diff --git a/tests/parsing/test_semantic_model_parsing.py b/tests/parsing/test_semantic_model_parsing.py index 1ab89853..34ad851f 100644 --- a/tests/parsing/test_semantic_model_parsing.py +++ b/tests/parsing/test_semantic_model_parsing.py @@ -111,8 +111,8 @@ def test_base_semantic_model_entity_parsing() -> None: expr: example_id label: {label} config: - meta: - random: metadata + meta: + random: metadata """ ) file = YamlConfigFile(filepath="test_dir/inline_for_test", contents=yaml_contents) @@ -209,8 +209,8 @@ def test_base_semantic_model_measure_parsing() -> None: description: {description} label: {label} config: - meta: - random: metadata + meta: + random: metadata """ ) file = YamlConfigFile(filepath="test_dir/inline_for_test", contents=yaml_contents) diff --git a/tests/test_implements_satisfy_protocols.py b/tests/test_implements_satisfy_protocols.py index 87771816..1288982b 100644 --- a/tests/test_implements_satisfy_protocols.py +++ b/tests/test_implements_satisfy_protocols.py @@ -3,20 +3,18 @@ from hypothesis import given from hypothesis.strategies import booleans, builds, from_type, just, lists, none, text +from dbt_semantic_interfaces.implementations.element_config import ( + SemanticLayerElementConfig, +) from dbt_semantic_interfaces.implementations.elements.dimension import ( PydanticDimension, - PydanticDimensionConfig, PydanticDimensionTypeParams, PydanticDimensionValidityParams, ) -from dbt_semantic_interfaces.implementations.elements.entity import ( - PydanticEntity, - PydanticEntityConfig, -) +from dbt_semantic_interfaces.implementations.elements.entity import PydanticEntity from dbt_semantic_interfaces.implementations.elements.measure import ( PydanticMeasure, PydanticMeasureAggregationParameters, - PydanticMeasureConfig, PydanticNonAdditiveDimensionParameters, ) from dbt_semantic_interfaces.implementations.export import PydanticExport @@ -71,7 +69,7 @@ expr=OPTIONAL_STR_STRATEGY, metadata=OPTIONAL_METADATA_STRATEGY, label=OPTIONAL_STR_STRATEGY, - config=builds(PydanticDimensionConfig), + config=builds(SemanticLayerElementConfig), ) DIMENSION_VALIDITY_PARAMS_STRATEGY = builds( @@ -88,7 +86,7 @@ expr=OPTIONAL_STR_STRATEGY, metadata=OPTIONAL_METADATA_STRATEGY, label=OPTIONAL_STR_STRATEGY, - config=builds(PydanticDimensionConfig), + config=builds(SemanticLayerElementConfig), ) DIMENSION_STRATEGY = TIME_DIMENSION_STRATEGY | CATEGORICAL_DIMENSION_STRATEGY @@ -100,7 +98,7 @@ expr=OPTIONAL_STR_STRATEGY, metadata=OPTIONAL_METADATA_STRATEGY, label=OPTIONAL_STR_STRATEGY, - config=builds(PydanticEntityConfig), + config=builds(SemanticLayerElementConfig), ) MEASURE_STRATEGY = builds( @@ -112,7 +110,7 @@ non_additive_dimesnion=builds(PydanticNonAdditiveDimensionParameters) | none(), agg_time_dimension=OPTIONAL_STR_STRATEGY, label=OPTIONAL_STR_STRATEGY, - config=builds(PydanticMeasureConfig), + config=builds(SemanticLayerElementConfig), ) SEMANTIC_MODEL_STRATEGY = builds( From ffe026cd2ea054cbc0a15749352e19fe2210baea Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:07:14 -0500 Subject: [PATCH 03/11] Consolidated meta config to use the same models --- .../implementations/metric.py | 17 ++++++----------- .../implementations/semantic_model.py | 16 +++++----------- dbt_semantic_interfaces/protocols/__init__.py | 2 -- dbt_semantic_interfaces/protocols/metric.py | 15 +++------------ .../protocols/semantic_model.py | 15 +++------------ tests/test_implements_satisfy_protocols.py | 3 +-- 6 files changed, 18 insertions(+), 50 deletions(-) diff --git a/dbt_semantic_interfaces/implementations/metric.py b/dbt_semantic_interfaces/implementations/metric.py index 02933e5a..27388649 100644 --- a/dbt_semantic_interfaces/implementations/metric.py +++ b/dbt_semantic_interfaces/implementations/metric.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Dict, List, Optional, Sequence, Set +from typing import Dict, List, Optional, Sequence, Set from typing_extensions import override @@ -12,11 +12,14 @@ PydanticCustomInputParser, PydanticParseableValueType, ) +from dbt_semantic_interfaces.implementations.element_config import ( + SemanticLayerElementConfig, +) from dbt_semantic_interfaces.implementations.filters.where_filter import ( PydanticWhereFilterIntersection, ) from dbt_semantic_interfaces.implementations.metadata import PydanticMetadata -from dbt_semantic_interfaces.protocols import Metric, MetricConfig, ProtocolHint +from dbt_semantic_interfaces.protocols import Metric, ProtocolHint from dbt_semantic_interfaces.references import MeasureReference, MetricReference from dbt_semantic_interfaces.type_enums import ( ConversionCalculationType, @@ -183,14 +186,6 @@ 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, ProtocolHint[Metric]): """Describes a metric.""" @@ -205,7 +200,7 @@ def _implements_protocol(self) -> Metric: # noqa: D filter: Optional[PydanticWhereFilterIntersection] metadata: Optional[PydanticMetadata] label: Optional[str] = None - config: Optional[PydanticMetricConfig] + config: Optional[SemanticLayerElementConfig] time_granularity: Optional[TimeGranularity] = None @property diff --git a/dbt_semantic_interfaces/implementations/semantic_model.py b/dbt_semantic_interfaces/implementations/semantic_model.py index eca8d6fd..a0c80bd3 100644 --- a/dbt_semantic_interfaces/implementations/semantic_model.py +++ b/dbt_semantic_interfaces/implementations/semantic_model.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Dict, List, Optional, Sequence +from typing import List, Optional, Sequence from typing_extensions import override @@ -8,6 +8,9 @@ HashableBaseModel, ModelWithMetadataParsing, ) +from dbt_semantic_interfaces.implementations.element_config import ( + SemanticLayerElementConfig, +) from dbt_semantic_interfaces.implementations.elements.dimension import PydanticDimension from dbt_semantic_interfaces.implementations.elements.entity import PydanticEntity from dbt_semantic_interfaces.implementations.elements.measure import PydanticMeasure @@ -16,7 +19,6 @@ from dbt_semantic_interfaces.protocols import ( ProtocolHint, SemanticModel, - SemanticModelConfig, SemanticModelDefaults, ) from dbt_semantic_interfaces.references import ( @@ -38,14 +40,6 @@ 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.""" @@ -65,7 +59,7 @@ def _implements_protocol(self) -> SemanticModel: label: Optional[str] = None metadata: Optional[PydanticMetadata] - config: Optional[PydanticSemanticModelConfig] + config: Optional[SemanticLayerElementConfig] @property def entity_references(self) -> List[LinkableElementReference]: # noqa: D diff --git a/dbt_semantic_interfaces/protocols/__init__.py b/dbt_semantic_interfaces/protocols/__init__.py index 76414058..f9dbea5b 100644 --- a/dbt_semantic_interfaces/protocols/__init__.py +++ b/dbt_semantic_interfaces/protocols/__init__.py @@ -14,7 +14,6 @@ ConstantPropertyInput, ConversionTypeParams, Metric, - MetricConfig, MetricInput, MetricInputMeasure, MetricTimeWindow, @@ -28,7 +27,6 @@ ) from dbt_semantic_interfaces.protocols.semantic_model import ( # noqa:F401 SemanticModel, - SemanticModelConfig, SemanticModelDefaults, SemanticModelT, ) diff --git a/dbt_semantic_interfaces/protocols/metric.py b/dbt_semantic_interfaces/protocols/metric.py index 9ccf931e..b5a3f4d5 100644 --- a/dbt_semantic_interfaces/protocols/metric.py +++ b/dbt_semantic_interfaces/protocols/metric.py @@ -1,8 +1,9 @@ from __future__ import annotations from abc import abstractmethod -from typing import Any, Dict, Optional, Protocol, Sequence +from typing import Optional, Protocol, Sequence +from dbt_semantic_interfaces.protocols.meta import ConfigMeta from dbt_semantic_interfaces.protocols.metadata import Metadata from dbt_semantic_interfaces.protocols.where_filter import WhereFilterIntersection from dbt_semantic_interfaces.references import MeasureReference, MetricReference @@ -253,16 +254,6 @@ def cumulative_type_params(self) -> Optional[CumulativeTypeParams]: # 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.""" @@ -317,7 +308,7 @@ def metadata(self) -> Optional[Metadata]: # noqa: D @property @abstractmethod - def config(self) -> Optional[MetricConfig]: # noqa: D + def config(self) -> Optional[ConfigMeta]: # noqa: D pass @property diff --git a/dbt_semantic_interfaces/protocols/semantic_model.py b/dbt_semantic_interfaces/protocols/semantic_model.py index d253b39a..605eabd7 100644 --- a/dbt_semantic_interfaces/protocols/semantic_model.py +++ b/dbt_semantic_interfaces/protocols/semantic_model.py @@ -1,11 +1,12 @@ from __future__ import annotations from abc import abstractmethod -from typing import Any, Dict, Optional, Protocol, Sequence, TypeVar +from typing import Optional, Protocol, Sequence, TypeVar from dbt_semantic_interfaces.protocols.dimension import Dimension from dbt_semantic_interfaces.protocols.entity import Entity from dbt_semantic_interfaces.protocols.measure import Measure +from dbt_semantic_interfaces.protocols.meta import ConfigMeta from dbt_semantic_interfaces.protocols.metadata import Metadata from dbt_semantic_interfaces.protocols.node_relation import NodeRelation from dbt_semantic_interfaces.references import ( @@ -27,16 +28,6 @@ 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.""" @@ -148,7 +139,7 @@ def metadata(self) -> Optional[Metadata]: # noqa: D @property @abstractmethod - def config(self) -> Optional[SemanticModelConfig]: # noqa: D + def config(self) -> Optional[ConfigMeta]: # noqa: D pass @abstractmethod diff --git a/tests/test_implements_satisfy_protocols.py b/tests/test_implements_satisfy_protocols.py index 1288982b..aa45ff44 100644 --- a/tests/test_implements_satisfy_protocols.py +++ b/tests/test_implements_satisfy_protocols.py @@ -25,7 +25,6 @@ from dbt_semantic_interfaces.implementations.metric import ( PydanticConversionTypeParams, PydanticMetric, - PydanticMetricConfig, PydanticMetricInput, PydanticMetricInputMeasure, PydanticMetricTypeParams, @@ -128,7 +127,7 @@ filter=builds(PydanticWhereFilter) | none(), metadata=OPTIONAL_METADATA_STRATEGY, label=OPTIONAL_STR_STRATEGY, - config=builds(PydanticMetricConfig), + config=builds(SemanticLayerElementConfig), ) SAVED_QUERY_STRATEGY = builds( From 9315754ace5e0da6ea3727a099605d94f13cf2b0 Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:12:34 -0500 Subject: [PATCH 04/11] changie --- .changes/unreleased/Breaking Changes-20241024-131227.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Breaking Changes-20241024-131227.yaml diff --git a/.changes/unreleased/Breaking Changes-20241024-131227.yaml b/.changes/unreleased/Breaking Changes-20241024-131227.yaml new file mode 100644 index 00000000..8f84c1b5 --- /dev/null +++ b/.changes/unreleased/Breaking Changes-20241024-131227.yaml @@ -0,0 +1,6 @@ +kind: Breaking Changes +body: Consolidated meta config to use the same models +time: 2024-10-24T13:12:27.343387-05:00 +custom: + Author: DevonFulcher + Issue: None From ada4b16e8c90cc05427efa5afce7a5198a36ff3b Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:07:22 -0500 Subject: [PATCH 05/11] Rename to PydanticSemanticLayerElementConfig --- dbt_semantic_interfaces/implementations/element_config.py | 6 +++--- dbt_semantic_interfaces/protocols/dimension.py | 4 ++-- dbt_semantic_interfaces/protocols/entity.py | 4 ++-- dbt_semantic_interfaces/protocols/measure.py | 4 ++-- dbt_semantic_interfaces/protocols/meta.py | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dbt_semantic_interfaces/implementations/element_config.py b/dbt_semantic_interfaces/implementations/element_config.py index e99237ca..0da5e278 100644 --- a/dbt_semantic_interfaces/implementations/element_config.py +++ b/dbt_semantic_interfaces/implementations/element_config.py @@ -4,15 +4,15 @@ from typing_extensions import override from dbt_semantic_interfaces.implementations.base import HashableBaseModel -from dbt_semantic_interfaces.protocols.meta import ConfigMeta +from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig from dbt_semantic_interfaces.protocols.protocol_hint import ProtocolHint -class SemanticLayerElementConfig(HashableBaseModel, ProtocolHint[ConfigMeta]): +class SemanticLayerElementConfig(HashableBaseModel, ProtocolHint[PydanticSemanticLayerElementConfig]): """PydanticDimension config.""" @override - def _implements_protocol(self) -> ConfigMeta: # noqa: D + def _implements_protocol(self) -> PydanticSemanticLayerElementConfig: # noqa: D return self meta: Dict[str, Any] = Field(default_factory=dict) diff --git a/dbt_semantic_interfaces/protocols/dimension.py b/dbt_semantic_interfaces/protocols/dimension.py index 474a1753..bcebac4e 100644 --- a/dbt_semantic_interfaces/protocols/dimension.py +++ b/dbt_semantic_interfaces/protocols/dimension.py @@ -3,7 +3,7 @@ from abc import abstractmethod from typing import Optional, Protocol -from dbt_semantic_interfaces.protocols.meta import ConfigMeta +from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig from dbt_semantic_interfaces.protocols.metadata import Metadata from dbt_semantic_interfaces.references import ( DimensionReference, @@ -111,5 +111,5 @@ def label(self) -> Optional[str]: @property @abstractmethod - def config(self) -> Optional[ConfigMeta]: # noqa: D + def config(self) -> Optional[PydanticSemanticLayerElementConfig]: # noqa: D pass diff --git a/dbt_semantic_interfaces/protocols/entity.py b/dbt_semantic_interfaces/protocols/entity.py index c614ac9d..ff0b1703 100644 --- a/dbt_semantic_interfaces/protocols/entity.py +++ b/dbt_semantic_interfaces/protocols/entity.py @@ -3,7 +3,7 @@ from abc import abstractmethod from typing import Optional, Protocol -from dbt_semantic_interfaces.protocols.meta import ConfigMeta +from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig from dbt_semantic_interfaces.references import EntityReference from dbt_semantic_interfaces.type_enums import EntityType @@ -64,5 +64,5 @@ def label(self) -> Optional[str]: @property @abstractmethod - def config(self) -> Optional[ConfigMeta]: # noqa: D + def config(self) -> Optional[PydanticSemanticLayerElementConfig]: # noqa: D pass diff --git a/dbt_semantic_interfaces/protocols/measure.py b/dbt_semantic_interfaces/protocols/measure.py index b505cffd..7f4dead5 100644 --- a/dbt_semantic_interfaces/protocols/measure.py +++ b/dbt_semantic_interfaces/protocols/measure.py @@ -3,7 +3,7 @@ from abc import abstractmethod from typing import Optional, Protocol, Sequence -from dbt_semantic_interfaces.protocols.meta import ConfigMeta +from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig from dbt_semantic_interfaces.references import MeasureReference from dbt_semantic_interfaces.type_enums import AggregationType @@ -102,5 +102,5 @@ def label(self) -> Optional[str]: @property @abstractmethod - def config(self) -> Optional[ConfigMeta]: # noqa: D + def config(self) -> Optional[PydanticSemanticLayerElementConfig]: # noqa: D pass diff --git a/dbt_semantic_interfaces/protocols/meta.py b/dbt_semantic_interfaces/protocols/meta.py index c2b5d208..ec4b06e1 100644 --- a/dbt_semantic_interfaces/protocols/meta.py +++ b/dbt_semantic_interfaces/protocols/meta.py @@ -2,7 +2,7 @@ from typing import Any, Dict, Protocol -class ConfigMeta(Protocol): # noqa: D +class PydanticSemanticLayerElementConfig(Protocol): # noqa: D """The config property allows you to configure additional resources/metadata.""" @property From 60316b240259a7db65706182dd3dca12381e92b4 Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:18:01 -0500 Subject: [PATCH 06/11] Fix renaming class --- dbt_semantic_interfaces/protocols/metric.py | 4 ++-- dbt_semantic_interfaces/protocols/semantic_model.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dbt_semantic_interfaces/protocols/metric.py b/dbt_semantic_interfaces/protocols/metric.py index b5a3f4d5..8ed98704 100644 --- a/dbt_semantic_interfaces/protocols/metric.py +++ b/dbt_semantic_interfaces/protocols/metric.py @@ -3,7 +3,7 @@ from abc import abstractmethod from typing import Optional, Protocol, Sequence -from dbt_semantic_interfaces.protocols.meta import ConfigMeta +from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig from dbt_semantic_interfaces.protocols.metadata import Metadata from dbt_semantic_interfaces.protocols.where_filter import WhereFilterIntersection from dbt_semantic_interfaces.references import MeasureReference, MetricReference @@ -308,7 +308,7 @@ def metadata(self) -> Optional[Metadata]: # noqa: D @property @abstractmethod - def config(self) -> Optional[ConfigMeta]: # noqa: D + def config(self) -> Optional[PydanticSemanticLayerElementConfig]: # noqa: D pass @property diff --git a/dbt_semantic_interfaces/protocols/semantic_model.py b/dbt_semantic_interfaces/protocols/semantic_model.py index 605eabd7..f8c390d8 100644 --- a/dbt_semantic_interfaces/protocols/semantic_model.py +++ b/dbt_semantic_interfaces/protocols/semantic_model.py @@ -6,7 +6,7 @@ from dbt_semantic_interfaces.protocols.dimension import Dimension from dbt_semantic_interfaces.protocols.entity import Entity from dbt_semantic_interfaces.protocols.measure import Measure -from dbt_semantic_interfaces.protocols.meta import ConfigMeta +from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig from dbt_semantic_interfaces.protocols.metadata import Metadata from dbt_semantic_interfaces.protocols.node_relation import NodeRelation from dbt_semantic_interfaces.references import ( @@ -139,7 +139,7 @@ def metadata(self) -> Optional[Metadata]: # noqa: D @property @abstractmethod - def config(self) -> Optional[ConfigMeta]: # noqa: D + def config(self) -> Optional[PydanticSemanticLayerElementConfig]: # noqa: D pass @abstractmethod From ff611d80574a228476c39c6e68dbd1c1de13d49d Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:26:10 -0500 Subject: [PATCH 07/11] Upgrade version to 0.8.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1f3090fe..cfdd39b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "dbt-semantic-interfaces" -version = "0.7.4" +version = "0.8.0" description = 'The shared semantic layer definitions that dbt-core and MetricFlow use' readme = "README.md" requires-python = ">=3.8" From 79916e800575958a3e1cfb3a2053afdbd6eee954 Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:35:36 -0500 Subject: [PATCH 08/11] Fix naming --- .../implementations/element_config.py | 6 +++--- .../implementations/elements/dimension.py | 4 ++-- .../implementations/elements/entity.py | 4 ++-- .../implementations/elements/measure.py | 4 ++-- dbt_semantic_interfaces/protocols/dimension.py | 4 ++-- dbt_semantic_interfaces/protocols/entity.py | 4 ++-- dbt_semantic_interfaces/protocols/measure.py | 4 ++-- dbt_semantic_interfaces/protocols/meta.py | 2 +- tests/test_implements_satisfy_protocols.py | 10 +++++----- 9 files changed, 21 insertions(+), 21 deletions(-) diff --git a/dbt_semantic_interfaces/implementations/element_config.py b/dbt_semantic_interfaces/implementations/element_config.py index 0da5e278..d8ec41dd 100644 --- a/dbt_semantic_interfaces/implementations/element_config.py +++ b/dbt_semantic_interfaces/implementations/element_config.py @@ -4,15 +4,15 @@ from typing_extensions import override from dbt_semantic_interfaces.implementations.base import HashableBaseModel -from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig +from dbt_semantic_interfaces.protocols.meta import SemanticLayerElementConfig from dbt_semantic_interfaces.protocols.protocol_hint import ProtocolHint -class SemanticLayerElementConfig(HashableBaseModel, ProtocolHint[PydanticSemanticLayerElementConfig]): +class PydanticSemanticLayerElementConfig(HashableBaseModel, ProtocolHint[SemanticLayerElementConfig]): """PydanticDimension config.""" @override - def _implements_protocol(self) -> PydanticSemanticLayerElementConfig: # noqa: D + def _implements_protocol(self) -> SemanticLayerElementConfig: # noqa: D return self meta: Dict[str, Any] = Field(default_factory=dict) diff --git a/dbt_semantic_interfaces/implementations/elements/dimension.py b/dbt_semantic_interfaces/implementations/elements/dimension.py index ddbcdca9..a4cb5a03 100644 --- a/dbt_semantic_interfaces/implementations/elements/dimension.py +++ b/dbt_semantic_interfaces/implementations/elements/dimension.py @@ -7,7 +7,7 @@ ModelWithMetadataParsing, ) from dbt_semantic_interfaces.implementations.element_config import ( - SemanticLayerElementConfig, + PydanticSemanticLayerElementConfig, ) from dbt_semantic_interfaces.implementations.metadata import PydanticMetadata from dbt_semantic_interfaces.references import ( @@ -51,7 +51,7 @@ class PydanticDimension(HashableBaseModel, ModelWithMetadataParsing): expr: Optional[str] = None metadata: Optional[PydanticMetadata] label: Optional[str] = None - config: Optional[SemanticLayerElementConfig] + config: Optional[PydanticSemanticLayerElementConfig] @property def reference(self) -> DimensionReference: # noqa: D diff --git a/dbt_semantic_interfaces/implementations/elements/entity.py b/dbt_semantic_interfaces/implementations/elements/entity.py index 2496eaea..9a6557e8 100644 --- a/dbt_semantic_interfaces/implementations/elements/entity.py +++ b/dbt_semantic_interfaces/implementations/elements/entity.py @@ -7,7 +7,7 @@ ModelWithMetadataParsing, ) from dbt_semantic_interfaces.implementations.element_config import ( - SemanticLayerElementConfig, + PydanticSemanticLayerElementConfig, ) from dbt_semantic_interfaces.implementations.metadata import PydanticMetadata from dbt_semantic_interfaces.references import EntityReference @@ -24,7 +24,7 @@ class PydanticEntity(HashableBaseModel, ModelWithMetadataParsing): expr: Optional[str] = None metadata: Optional[PydanticMetadata] = None label: Optional[str] = None - config: Optional[SemanticLayerElementConfig] + config: Optional[PydanticSemanticLayerElementConfig] @property def reference(self) -> EntityReference: # noqa: D diff --git a/dbt_semantic_interfaces/implementations/elements/measure.py b/dbt_semantic_interfaces/implementations/elements/measure.py index 08b39db0..f3c88c00 100644 --- a/dbt_semantic_interfaces/implementations/elements/measure.py +++ b/dbt_semantic_interfaces/implementations/elements/measure.py @@ -7,7 +7,7 @@ ModelWithMetadataParsing, ) from dbt_semantic_interfaces.implementations.element_config import ( - SemanticLayerElementConfig, + PydanticSemanticLayerElementConfig, ) from dbt_semantic_interfaces.implementations.metadata import PydanticMetadata from dbt_semantic_interfaces.references import MeasureReference @@ -49,7 +49,7 @@ class PydanticMeasure(HashableBaseModel, ModelWithMetadataParsing): non_additive_dimension: Optional[PydanticNonAdditiveDimensionParameters] = None agg_time_dimension: Optional[str] = None label: Optional[str] = None - config: Optional[SemanticLayerElementConfig] = None + config: Optional[PydanticSemanticLayerElementConfig] = None @property def reference(self) -> MeasureReference: # noqa: D diff --git a/dbt_semantic_interfaces/protocols/dimension.py b/dbt_semantic_interfaces/protocols/dimension.py index bcebac4e..f0ac3b67 100644 --- a/dbt_semantic_interfaces/protocols/dimension.py +++ b/dbt_semantic_interfaces/protocols/dimension.py @@ -3,7 +3,7 @@ from abc import abstractmethod from typing import Optional, Protocol -from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig +from dbt_semantic_interfaces.protocols.meta import SemanticLayerElementConfig from dbt_semantic_interfaces.protocols.metadata import Metadata from dbt_semantic_interfaces.references import ( DimensionReference, @@ -111,5 +111,5 @@ def label(self) -> Optional[str]: @property @abstractmethod - def config(self) -> Optional[PydanticSemanticLayerElementConfig]: # noqa: D + def config(self) -> Optional[SemanticLayerElementConfig]: # noqa: D pass diff --git a/dbt_semantic_interfaces/protocols/entity.py b/dbt_semantic_interfaces/protocols/entity.py index ff0b1703..27719d1a 100644 --- a/dbt_semantic_interfaces/protocols/entity.py +++ b/dbt_semantic_interfaces/protocols/entity.py @@ -3,7 +3,7 @@ from abc import abstractmethod from typing import Optional, Protocol -from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig +from dbt_semantic_interfaces.protocols.meta import SemanticLayerElementConfig from dbt_semantic_interfaces.references import EntityReference from dbt_semantic_interfaces.type_enums import EntityType @@ -64,5 +64,5 @@ def label(self) -> Optional[str]: @property @abstractmethod - def config(self) -> Optional[PydanticSemanticLayerElementConfig]: # noqa: D + def config(self) -> Optional[SemanticLayerElementConfig]: # noqa: D pass diff --git a/dbt_semantic_interfaces/protocols/measure.py b/dbt_semantic_interfaces/protocols/measure.py index 7f4dead5..7d8606f8 100644 --- a/dbt_semantic_interfaces/protocols/measure.py +++ b/dbt_semantic_interfaces/protocols/measure.py @@ -3,7 +3,7 @@ from abc import abstractmethod from typing import Optional, Protocol, Sequence -from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig +from dbt_semantic_interfaces.protocols.meta import SemanticLayerElementConfig from dbt_semantic_interfaces.references import MeasureReference from dbt_semantic_interfaces.type_enums import AggregationType @@ -102,5 +102,5 @@ def label(self) -> Optional[str]: @property @abstractmethod - def config(self) -> Optional[PydanticSemanticLayerElementConfig]: # noqa: D + def config(self) -> Optional[SemanticLayerElementConfig]: # noqa: D pass diff --git a/dbt_semantic_interfaces/protocols/meta.py b/dbt_semantic_interfaces/protocols/meta.py index ec4b06e1..08a1eef8 100644 --- a/dbt_semantic_interfaces/protocols/meta.py +++ b/dbt_semantic_interfaces/protocols/meta.py @@ -2,7 +2,7 @@ from typing import Any, Dict, Protocol -class PydanticSemanticLayerElementConfig(Protocol): # noqa: D +class SemanticLayerElementConfig(Protocol): # noqa: D """The config property allows you to configure additional resources/metadata.""" @property diff --git a/tests/test_implements_satisfy_protocols.py b/tests/test_implements_satisfy_protocols.py index 1288982b..0c4ec8e7 100644 --- a/tests/test_implements_satisfy_protocols.py +++ b/tests/test_implements_satisfy_protocols.py @@ -4,7 +4,7 @@ from hypothesis.strategies import booleans, builds, from_type, just, lists, none, text from dbt_semantic_interfaces.implementations.element_config import ( - SemanticLayerElementConfig, + PydanticSemanticLayerElementConfig, ) from dbt_semantic_interfaces.implementations.elements.dimension import ( PydanticDimension, @@ -69,7 +69,7 @@ expr=OPTIONAL_STR_STRATEGY, metadata=OPTIONAL_METADATA_STRATEGY, label=OPTIONAL_STR_STRATEGY, - config=builds(SemanticLayerElementConfig), + config=builds(PydanticSemanticLayerElementConfig), ) DIMENSION_VALIDITY_PARAMS_STRATEGY = builds( @@ -86,7 +86,7 @@ expr=OPTIONAL_STR_STRATEGY, metadata=OPTIONAL_METADATA_STRATEGY, label=OPTIONAL_STR_STRATEGY, - config=builds(SemanticLayerElementConfig), + config=builds(PydanticSemanticLayerElementConfig), ) DIMENSION_STRATEGY = TIME_DIMENSION_STRATEGY | CATEGORICAL_DIMENSION_STRATEGY @@ -98,7 +98,7 @@ expr=OPTIONAL_STR_STRATEGY, metadata=OPTIONAL_METADATA_STRATEGY, label=OPTIONAL_STR_STRATEGY, - config=builds(SemanticLayerElementConfig), + config=builds(PydanticSemanticLayerElementConfig), ) MEASURE_STRATEGY = builds( @@ -110,7 +110,7 @@ non_additive_dimesnion=builds(PydanticNonAdditiveDimensionParameters) | none(), agg_time_dimension=OPTIONAL_STR_STRATEGY, label=OPTIONAL_STR_STRATEGY, - config=builds(SemanticLayerElementConfig), + config=builds(PydanticSemanticLayerElementConfig), ) SEMANTIC_MODEL_STRATEGY = builds( From c22eb80ba2cf806d0d48d5922a090b6d0c1a05a3 Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:38:15 -0500 Subject: [PATCH 09/11] Fix sync --- dbt_semantic_interfaces/protocols/metric.py | 4 ++-- dbt_semantic_interfaces/protocols/semantic_model.py | 4 ++-- tests/test_implements_satisfy_protocols.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dbt_semantic_interfaces/protocols/metric.py b/dbt_semantic_interfaces/protocols/metric.py index 8ed98704..273ba7f2 100644 --- a/dbt_semantic_interfaces/protocols/metric.py +++ b/dbt_semantic_interfaces/protocols/metric.py @@ -3,7 +3,7 @@ from abc import abstractmethod from typing import Optional, Protocol, Sequence -from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig +from dbt_semantic_interfaces.protocols.meta import SemanticLayerElementConfig from dbt_semantic_interfaces.protocols.metadata import Metadata from dbt_semantic_interfaces.protocols.where_filter import WhereFilterIntersection from dbt_semantic_interfaces.references import MeasureReference, MetricReference @@ -308,7 +308,7 @@ def metadata(self) -> Optional[Metadata]: # noqa: D @property @abstractmethod - def config(self) -> Optional[PydanticSemanticLayerElementConfig]: # noqa: D + def config(self) -> Optional[SemanticLayerElementConfig]: # noqa: D pass @property diff --git a/dbt_semantic_interfaces/protocols/semantic_model.py b/dbt_semantic_interfaces/protocols/semantic_model.py index f8c390d8..15af3634 100644 --- a/dbt_semantic_interfaces/protocols/semantic_model.py +++ b/dbt_semantic_interfaces/protocols/semantic_model.py @@ -6,7 +6,7 @@ from dbt_semantic_interfaces.protocols.dimension import Dimension from dbt_semantic_interfaces.protocols.entity import Entity from dbt_semantic_interfaces.protocols.measure import Measure -from dbt_semantic_interfaces.protocols.meta import PydanticSemanticLayerElementConfig +from dbt_semantic_interfaces.protocols.meta import SemanticLayerElementConfig from dbt_semantic_interfaces.protocols.metadata import Metadata from dbt_semantic_interfaces.protocols.node_relation import NodeRelation from dbt_semantic_interfaces.references import ( @@ -139,7 +139,7 @@ def metadata(self) -> Optional[Metadata]: # noqa: D @property @abstractmethod - def config(self) -> Optional[PydanticSemanticLayerElementConfig]: # noqa: D + def config(self) -> Optional[SemanticLayerElementConfig]: # noqa: D pass @abstractmethod diff --git a/tests/test_implements_satisfy_protocols.py b/tests/test_implements_satisfy_protocols.py index 7f8be744..5919c83f 100644 --- a/tests/test_implements_satisfy_protocols.py +++ b/tests/test_implements_satisfy_protocols.py @@ -127,7 +127,7 @@ filter=builds(PydanticWhereFilter) | none(), metadata=OPTIONAL_METADATA_STRATEGY, label=OPTIONAL_STR_STRATEGY, - config=builds(SemanticLayerElementConfig), + config=builds(PydanticSemanticLayerElementConfig), ) SAVED_QUERY_STRATEGY = builds( From 83ff54235d81b0032df3ccab8f7dbd27148c00d7 Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:43:24 -0500 Subject: [PATCH 10/11] fix tests --- dbt_semantic_interfaces/implementations/metric.py | 4 ++-- dbt_semantic_interfaces/implementations/semantic_model.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dbt_semantic_interfaces/implementations/metric.py b/dbt_semantic_interfaces/implementations/metric.py index 27388649..50676ed2 100644 --- a/dbt_semantic_interfaces/implementations/metric.py +++ b/dbt_semantic_interfaces/implementations/metric.py @@ -13,7 +13,7 @@ PydanticParseableValueType, ) from dbt_semantic_interfaces.implementations.element_config import ( - SemanticLayerElementConfig, + PydanticSemanticLayerElementConfig, ) from dbt_semantic_interfaces.implementations.filters.where_filter import ( PydanticWhereFilterIntersection, @@ -200,7 +200,7 @@ def _implements_protocol(self) -> Metric: # noqa: D filter: Optional[PydanticWhereFilterIntersection] metadata: Optional[PydanticMetadata] label: Optional[str] = None - config: Optional[SemanticLayerElementConfig] + config: Optional[PydanticSemanticLayerElementConfig] time_granularity: Optional[TimeGranularity] = None @property diff --git a/dbt_semantic_interfaces/implementations/semantic_model.py b/dbt_semantic_interfaces/implementations/semantic_model.py index a0c80bd3..36ad145b 100644 --- a/dbt_semantic_interfaces/implementations/semantic_model.py +++ b/dbt_semantic_interfaces/implementations/semantic_model.py @@ -9,7 +9,7 @@ ModelWithMetadataParsing, ) from dbt_semantic_interfaces.implementations.element_config import ( - SemanticLayerElementConfig, + PydanticSemanticLayerElementConfig, ) from dbt_semantic_interfaces.implementations.elements.dimension import PydanticDimension from dbt_semantic_interfaces.implementations.elements.entity import PydanticEntity @@ -59,7 +59,7 @@ def _implements_protocol(self) -> SemanticModel: label: Optional[str] = None metadata: Optional[PydanticMetadata] - config: Optional[SemanticLayerElementConfig] + config: Optional[PydanticSemanticLayerElementConfig] @property def entity_references(self) -> List[LinkableElementReference]: # noqa: D From e91a1290843b57f99c0ae7d80e716ce0afe77a24 Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:35:03 -0600 Subject: [PATCH 11/11] Merge semantic model meta config (#367) ### Description This PR implements the meta config merge behavior described [here](https://docs.getdbt.com/reference/configs-and-properties#combining-configs) and referenced [here](https://github.com/dbt-labs/dbt-semantic-interfaces/issues/362). I decided to stack this PR on top to keep it distinct from the other PRs, but I don't intend to merge this one into main directly. I will merge it into its parent branch first. ### Checklist - [x] I have read [the contributing guide](https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/CONTRIBUTING.md) and understand what's expected of me - [x] I have signed the [CLA](https://docs.getdbt.com/docs/contributor-license-agreements) - [x] This PR includes tests, or tests are not required/relevant for this PR - [ ] ~~I have run `changie new` to [create a changelog entry](https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/CONTRIBUTING.md#adding-a-changelog-entry)~~ I'm not going to merge this directly into main, so we don't need a separate changelog entry. --- .../parsing/dir_to_model.py | 23 +++++- tests/parsing/test_semantic_model_parsing.py | 82 +++++++++++++++++++ 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/dbt_semantic_interfaces/parsing/dir_to_model.py b/dbt_semantic_interfaces/parsing/dir_to_model.py index 418ca254..c347b8a4 100644 --- a/dbt_semantic_interfaces/parsing/dir_to_model.py +++ b/dbt_semantic_interfaces/parsing/dir_to_model.py @@ -3,11 +3,17 @@ import traceback from dataclasses import dataclass from string import Template -from typing import Dict, List, Optional, Type, Union +from typing import Dict, List, Optional, Sequence, Type, Union from jsonschema import exceptions from dbt_semantic_interfaces.errors import ParsingException +from dbt_semantic_interfaces.implementations.element_config import ( + PydanticSemanticLayerElementConfig, +) +from dbt_semantic_interfaces.implementations.elements.dimension import PydanticDimension +from dbt_semantic_interfaces.implementations.elements.entity import PydanticEntity +from dbt_semantic_interfaces.implementations.elements.measure import PydanticMeasure from dbt_semantic_interfaces.implementations.metric import PydanticMetric from dbt_semantic_interfaces.implementations.project_configuration import ( PydanticProjectConfiguration, @@ -334,7 +340,20 @@ def parse_config_yaml( results.append(metric_class.parse_obj(object_cfg)) elif document_type == SEMANTIC_MODEL_TYPE: semantic_model_validator.validate(config_document[document_type]) - results.append(semantic_model_class.parse_obj(object_cfg)) + sm = semantic_model_class.parse_obj(object_cfg) + # Combine configs according to the behavior documented here https://docs.getdbt.com/reference/configs-and-properties#combining-configs + elements: Sequence[Union[PydanticDimension, PydanticEntity, PydanticMeasure]] = [ + *sm.dimensions, + *sm.entities, + *sm.measures, + ] + for element in elements: + if sm.config is not None: + if element.config is None: + element.config = PydanticSemanticLayerElementConfig(meta=sm.config.meta) + else: + element.config.meta = {**sm.config.meta, **element.config.meta} + results.append(sm) elif document_type == PROJECT_CONFIGURATION_TYPE: project_configuration_validator.validate(config_document[document_type]) results.append(project_configuration_class.parse_obj(object_cfg)) diff --git a/tests/parsing/test_semantic_model_parsing.py b/tests/parsing/test_semantic_model_parsing.py index 34ad851f..61839360 100644 --- a/tests/parsing/test_semantic_model_parsing.py +++ b/tests/parsing/test_semantic_model_parsing.py @@ -538,3 +538,85 @@ def test_semantic_model_dimension_validity_params_parsing() -> None: assert end_dimension.type_params.validity_params is not None assert end_dimension.type_params.validity_params.is_start is False assert end_dimension.type_params.validity_params.is_end is True + + +def test_semantic_model_element_config_merging() -> None: + """Test for merging element config metadata from semantic model into dimension, entity, and measure objects.""" + yaml_contents = textwrap.dedent( + """\ + semantic_model: + name: sm + config: + meta: + sm_metadata: asdf + node_relation: + alias: source_table + schema_name: some_schema + dimensions: + - name: dim_0 + type: time + type_params: + time_granularity: day + config: + meta: + sm_metadata: qwer + dim_metadata: fdsa + - name: dim_1 + type: time + type_params: + time_granularity: day + config: + meta: + dim_metadata: mlkj + sm_metadata: zxcv + - name: dim_2 + type: time + type_params: + time_granularity: day + - name: dim_3 + type: time + type_params: + time_granularity: day + config: + meta: + dim_metadata: gfds + entities: + - name: entity_0 + type: primary + config: + meta: + sm_metadata: hjkl + measures: + - name: measure_0 + agg: count_distinct + config: + meta: + sm_metadata: ijkl + """ + ) + file = YamlConfigFile(filepath="test_dir/inline_for_test", contents=yaml_contents) + + build_result = parse_yaml_files_to_semantic_manifest(files=[file, EXAMPLE_PROJECT_CONFIGURATION_YAML_CONFIG_FILE]) + + assert len(build_result.semantic_manifest.semantic_models) == 1 + semantic_model = build_result.semantic_manifest.semantic_models[0] + assert semantic_model.config is not None + assert semantic_model.config.meta["sm_metadata"] == "asdf" + assert len(semantic_model.dimensions) == 4 + assert semantic_model.dimensions[0].config is not None + assert semantic_model.dimensions[0].config.meta["sm_metadata"] == "qwer" + assert semantic_model.dimensions[0].config.meta["dim_metadata"] == "fdsa" + assert semantic_model.dimensions[1].config is not None + assert semantic_model.dimensions[1].config.meta["sm_metadata"] == "zxcv" + assert semantic_model.dimensions[1].config.meta["dim_metadata"] == "mlkj" + assert semantic_model.dimensions[2].config is not None + assert semantic_model.dimensions[2].config.meta["sm_metadata"] == "asdf" + assert semantic_model.dimensions[3].config is not None + assert semantic_model.dimensions[3].config.meta["dim_metadata"] == "gfds" + assert semantic_model.dimensions[3].config.meta["sm_metadata"] == "asdf" + assert len(semantic_model.entities) == 1 + assert semantic_model.entities[0].config is not None + assert semantic_model.entities[0].config.meta["sm_metadata"] == "hjkl" + assert len(semantic_model.measures) == 1 + assert semantic_model.measures[0].config is not None + assert semantic_model.measures[0].config.meta["sm_metadata"] == "ijkl"