Skip to content

Commit 5531bca

Browse files
committed
Add full back-reference from dataset to campaign.
1 parent 8c8cc88 commit 5531bca

File tree

6 files changed

+68
-42
lines changed

6 files changed

+68
-42
lines changed

order/adapters/order.py

+35
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,41 @@ class OrderAdapter(Adapter):
2626
needs_data_location = True
2727

2828

29+
class CampaignAdapter(OrderAdapter):
30+
31+
name = "order_campaign"
32+
33+
def retrieve_data(
34+
self,
35+
data_location: str,
36+
*,
37+
campaign_name: str,
38+
) -> Materialized:
39+
# only supporting local evaluation for now
40+
if not self.location_is_local(data_location):
41+
raise NotImplementedError(f"non-local location {data_location} not handled by {self!r}")
42+
43+
# build the yaml file path
44+
path = os.path.join(
45+
self.remove_scheme(data_location),
46+
"campaigns",
47+
f"{campaign_name}.yaml",
48+
)
49+
if not os.path.exists(path):
50+
raise FileNotFoundError(f"campaign file {path} does not exist")
51+
52+
# open the file and look for the campaign
53+
with open(path, "r") as f:
54+
stream = yaml.load_all(f, Loader=yaml.SafeLoader)
55+
for entry in stream:
56+
if entry.get("name") == campaign_name:
57+
return Materialized(campaign=entry)
58+
# only one campaign per file allowed
59+
break
60+
61+
raise Exception(f"no campaign entry with name '{campaign_name}' found in {path}")
62+
63+
2964
class DatasetsAdapter(OrderAdapter):
3065

3166
name = "order_datasets"

order/models/base.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,15 @@ def fget(self):
133133
# set the value
134134
setattr(self, lazy_attr_, materialized[adapter_model_.key])
135135

136+
# get back the now instantiated value
137+
value_ = getattr(self, lazy_attr_)
138+
139+
# invoke the on_materialize hook
140+
self.on_materialize(attr_, value_, adapter_model_)
141+
136142
# assign it to the return value for the requested attribute
137143
if attr_ == attr:
138-
value = getattr(self, lazy_attr_)
144+
value = value_
139145

140146
# complain if the return value was not set
141147
if value == no_value:
@@ -347,3 +353,9 @@ def __repr_args__(self, *, verbose: bool = False, adapters: bool = False) -> Gen
347353
value = self.__repr_adapter__(value)
348354

349355
yield attr, value
356+
357+
def on_materialize(self, attr: str, value: Any, adapter_model: AdapterModel) -> None:
358+
"""
359+
A custom hook that gets invoked when a lazy attribute is materialized.
360+
"""
361+
return

order/models/campaign.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,13 @@ def _dataset_materialize_callback(self, dataset: Dataset) -> None:
5656
dataset.campaign = self
5757

5858
def _dataset_add_callback(self, dataset: LazyDataset | Dataset) -> None:
59-
if isinstance(dataset, Dataset):
60-
dataset.campaign = self
59+
if not isinstance(dataset, Dataset):
60+
return
61+
62+
dataset.campaign = self
6163

6264
def _dataset_remove_callback(self, dataset: LazyDataset | Dataset) -> None:
63-
if isinstance(dataset, Dataset):
64-
dataset.campaign = None
65+
if not isinstance(dataset, Dataset):
66+
return
67+
68+
dataset.campaign = None

order/models/dataset.py

+7-35
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
from pydantic import Field, field_validator
1212

1313
from order.types import (
14-
Union, List, Dict, NonEmptyStrictStr, PositiveStrictInt, Lazy, ClassVar, GeneratorType,
14+
Union, List, Dict, NonEmptyStrictStr, PositiveStrictInt, Lazy, ClassVar, GeneratorType, Any,
1515
)
16-
from order.util import validated
17-
from order.models.base import Model
16+
# from order.util import validated
17+
from order.models.base import Model, AdapterModel
1818
from order.models.unique import UniqueObjectBase, UniqueObject, LazyUniqueObject, UniqueObjectIndex
1919

2020

@@ -84,45 +84,17 @@ def validate_gen_order(cls, gen_order: str) -> str:
8484

8585
class Dataset(UniqueObject):
8686

87+
campaign: Lazy["Campaign"]
8788
variations: Dict[str, DatasetVariation] = Field(frozen=True)
8889

8990
lazy_cls: ClassVar[UniqueObjectBase] = LazyDataset
9091

91-
@validated(default=None)
92-
def campaign(self, campaign: "Campaign" | None) -> "Campaign":
93-
# do nothing when the previous campaign matches the new one
94-
if campaign == self.campaign:
95-
return campaign
96-
97-
# deregister from previous campaign
98-
if self.campaign:
99-
self.campaign.datasets.remove(self, skip_callback=True)
100-
101-
# None case
102-
if campaign is None:
103-
return campaign
104-
105-
# type check
106-
if not isinstance(campaign, Campaign):
107-
raise TypeError(f"expected Campaign object, but got '{campaign}'")
108-
109-
# add to the index if not already in there
110-
if self not in campaign.datasets:
111-
campaign.datasets.add(self, skip_callback=True)
112-
113-
return campaign
114-
11592
def __getitem__(self, name: str) -> DatasetVariation:
11693
return self.get_info(name)
11794

118-
def __repr_args__(self, verbose: bool = False, adapters: bool = False) -> GeneratorType:
119-
"""
120-
Yields all key-values pairs to be injected into the representation.
121-
"""
122-
yield from super().__repr_args__(verbose=verbose, adapters=adapters)
123-
124-
if self.campaign:
125-
yield "campaign", self.campaign.name
95+
def on_materialize(self, attr: str, value: Any, adapter_model: AdapterModel) -> None:
96+
if attr == "campaign":
97+
value.datasets.add(self, overwrite=True, skip_callback=True)
12698

12799
def get_variation(self, name: str) -> DatasetVariation:
128100
return self.variations[name]

order/types.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,10 @@ def make_strict(cls, type_: type) -> AnnotatedType:
9292

9393
@classmethod
9494
def can_make_strict(cls, type_: type) -> bool:
95-
if type_.__dict__.get("_name") in ("Dict", "List"):
95+
if (
96+
getattr(type_, "__dict__", None) is not None and
97+
type_.__dict__.get("_name") in ("Dict", "List")
98+
):
9699
return False
97100

98101
return True

order/util.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ class validated(property):
186186
187187
.. code-block:: python
188188
189-
class MyClass(object):
189+
class MyClass(object):
190190
191191
def __init__(self):
192192
self._foo: str = None

0 commit comments

Comments
 (0)