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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/py/ai/chronon/group_by.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ def GroupBy(
derivations: Optional[List[ttypes.Derivation]] = None,
deprecation_date: Optional[str] = None,
description: Optional[str] = None,
attributes: Optional[Dict[str, str]] = None,
**kwargs,
) -> ttypes.GroupBy:
"""
Expand Down Expand Up @@ -481,6 +482,7 @@ def GroupBy(
Additional properties that would be passed to run.py if specified under additional_args property.
And provides an option to pass custom values to the processing logic.
:param description: optional description of this GroupBy
:param attributes: any extra attributes of this GroupBy
:type kwargs: Dict[str, str]
:return:
A GroupBy object containing specified aggregations.
Expand Down Expand Up @@ -560,6 +562,7 @@ def _normalize_source(source):
offlineSchedule=offline_schedule,
deprecationDate=deprecation_date,
description=description,
attributes=attributes,
)

group_by = ttypes.GroupBy(
Expand Down
3 changes: 3 additions & 0 deletions api/py/ai/chronon/join.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ def Join(
tags: Optional[Dict[str, str]] = None,
description: Optional[str] = None,
model_transforms: Optional[api.ModelTransforms] = None,
attributes: Optional[Dict[str, str]] = None,
**kwargs,
) -> api.Join:
"""
Expand Down Expand Up @@ -498,6 +499,7 @@ def Join(
:param description: optional description of this Join
:param model_transforms:
A list of model transforms to convert derivation outputs to model outputs using model-based transformations
:param attributes: any extra attributes of this Join
:return:
A join object that can be used to backfill or serve data. For ML use-cases this should map 1:1 to model.
"""
Expand Down Expand Up @@ -607,6 +609,7 @@ def Join(
historicalBackfill=historical_backfill,
deprecationDate=deprecation_date,
description=description,
attributes=attributes,
)

return api.Join(
Expand Down
20 changes: 20 additions & 0 deletions api/py/test/test_group_by.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,26 @@ def test_group_by_with_description():
assert gb.metaData.description == "GroupBy description"


def test_group_by_with_attributes():
gb = group_by.GroupBy(
sources=[
ttypes.EventSource(
table="event_table1",
query=query.Query(
selects=None,
time_column="ts"
)
)
],
keys=["key1", "key2"],
aggregations=[group_by.Aggregation(input_column="event_id", operation=ttypes.Operation.SUM)],
name="test.additional_metadata_gb",
attributes=["attr1", "attr1Val"]
)
assert gb.metaData.attributes == ["attr1", "attr1Val"]



def test_derivation():
derivation = Derivation(name="derivation_name", expression="derivation_expression")
expected_derivation = ttypes.Derivation(
Expand Down
8 changes: 8 additions & 0 deletions api/py/test/test_join.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ def test_join_with_description():
)
assert join.metaData.description == "Join description"

def test_join_with_attributes():
join = Join(
left=event_source("sample_namespace.sample_table"),
right_parts=[right_part(event_source("sample_namespace.another_table"))],
attributes=["attr1", "attr1Val"]
)
assert join.metaData.attributes == ["attr1", "attr1Val"]

def test_deduped_dependencies():
"""
Check left and right dependencies are deduped in metadata.
Expand Down
6 changes: 5 additions & 1 deletion api/src/main/scala/ai/chronon/api/Builders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ object Builders {
tableProperties: Map[String, String] = Map.empty,
historicalBackill: Boolean = true,
deprecationDate: String = null,
description: String = null
description: String = null,
attributes: Map[String, String] = Map.empty
): MetaData = {
val result = new MetaData()
result.setName(name)
Expand All @@ -297,6 +298,9 @@ object Builders {
if (description != null) {
result.setDescription(description)
}
if (attributes != null) {
result.setAttributes(attributes.toJava)
}
result
}
}
Expand Down
22 changes: 22 additions & 0 deletions api/src/test/scala/ai/chronon/api/test/ExtensionsTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -248,4 +248,26 @@ class ExtensionsTest {
assertEquals(join1.semanticHash(excludeTopic = true), join2.semanticHash(excludeTopic = true))
assertEquals(join1.semanticHash(excludeTopic = false), join2.semanticHash(excludeTopic = false))
}

@Test
def semanticHashIgnoresMetadataAttributes(): Unit = {
val metadata = Builders.MetaData(name = "test", attributes = Map("owner" -> "Lucie"))
val groupBy = Builders.GroupBy(
sources = Seq(Builders.Source.events(query = null, table = "db.gb_table", topic = "test.gb_topic")),
keyColumns = Seq("a", "c"),
metaData = metadata)
val join1 = Builders.Join(
left = Builders.Source.events(query = null, table = "db.join_table", topic = "test.join_topic"),
joinParts = Seq(Builders.JoinPart(groupBy = groupBy)),
metaData = metadata,
derivations = Seq(Builders.Derivation(name = "*", expression = "*", metaData = metadata))
)
val updatedMetadata = Builders.MetaData(name = "test", attributes = Map("owner" -> "Katie"))
val join2 = join1.deepCopy()
join2.setMetaData(updatedMetadata)
join2.joinParts.get(0).groupBy.setMetaData(updatedMetadata)
join2.derivations.get(0).setMetaData(updatedMetadata)
assertEquals(join1.semanticHash(excludeTopic = true), join2.semanticHash(excludeTopic = true))
assertEquals(join1.semanticHash(excludeTopic = false), join2.semanticHash(excludeTopic = false))
}
}
1 change: 1 addition & 0 deletions api/thrift/api.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ struct MetaData {
15: optional string deprecationDate
// Description for the object holding this metadata
16: optional string description
17: optional map<string, string> attributes
}

// Equivalent to a FeatureSet in chronon terms
Expand Down