apache-hamilton 1.90.0.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- apache_hamilton-1.90.0.dev0.dist-info/METADATA +407 -0
- apache_hamilton-1.90.0.dev0.dist-info/RECORD +151 -0
- apache_hamilton-1.90.0.dev0.dist-info/WHEEL +4 -0
- apache_hamilton-1.90.0.dev0.dist-info/entry_points.txt +9 -0
- apache_hamilton-1.90.0.dev0.dist-info/licenses/DISCLAIMER +10 -0
- apache_hamilton-1.90.0.dev0.dist-info/licenses/LICENSE +228 -0
- apache_hamilton-1.90.0.dev0.dist-info/licenses/NOTICE +5 -0
- hamilton/__init__.py +24 -0
- hamilton/ad_hoc_utils.py +132 -0
- hamilton/async_driver.py +465 -0
- hamilton/base.py +466 -0
- hamilton/caching/__init__.py +16 -0
- hamilton/caching/adapter.py +1475 -0
- hamilton/caching/cache_key.py +70 -0
- hamilton/caching/fingerprinting.py +287 -0
- hamilton/caching/stores/__init__.py +16 -0
- hamilton/caching/stores/base.py +242 -0
- hamilton/caching/stores/file.py +140 -0
- hamilton/caching/stores/memory.py +297 -0
- hamilton/caching/stores/sqlite.py +282 -0
- hamilton/caching/stores/utils.py +40 -0
- hamilton/cli/__init__.py +16 -0
- hamilton/cli/__main__.py +328 -0
- hamilton/cli/commands.py +126 -0
- hamilton/cli/logic.py +338 -0
- hamilton/common/__init__.py +76 -0
- hamilton/contrib/__init__.py +41 -0
- hamilton/data_quality/__init__.py +16 -0
- hamilton/data_quality/base.py +198 -0
- hamilton/data_quality/default_validators.py +560 -0
- hamilton/data_quality/pandera_validators.py +121 -0
- hamilton/dataflows/__init__.py +726 -0
- hamilton/dataflows/template/README.md +25 -0
- hamilton/dataflows/template/__init__.py +54 -0
- hamilton/dataflows/template/author.md +28 -0
- hamilton/dataflows/template/requirements.txt +0 -0
- hamilton/dataflows/template/tags.json +7 -0
- hamilton/dataflows/template/valid_configs.jsonl +1 -0
- hamilton/dev_utils/__init__.py +16 -0
- hamilton/dev_utils/deprecation.py +204 -0
- hamilton/driver.py +2112 -0
- hamilton/execution/__init__.py +16 -0
- hamilton/execution/debugging_utils.py +56 -0
- hamilton/execution/executors.py +502 -0
- hamilton/execution/graph_functions.py +421 -0
- hamilton/execution/grouping.py +430 -0
- hamilton/execution/state.py +539 -0
- hamilton/experimental/__init__.py +27 -0
- hamilton/experimental/databackend.py +61 -0
- hamilton/experimental/decorators/__init__.py +16 -0
- hamilton/experimental/decorators/parameterize_frame.py +233 -0
- hamilton/experimental/h_async.py +29 -0
- hamilton/experimental/h_cache.py +413 -0
- hamilton/experimental/h_dask.py +28 -0
- hamilton/experimental/h_databackends.py +174 -0
- hamilton/experimental/h_ray.py +28 -0
- hamilton/experimental/h_spark.py +32 -0
- hamilton/function_modifiers/README +40 -0
- hamilton/function_modifiers/__init__.py +121 -0
- hamilton/function_modifiers/adapters.py +900 -0
- hamilton/function_modifiers/base.py +859 -0
- hamilton/function_modifiers/configuration.py +310 -0
- hamilton/function_modifiers/delayed.py +202 -0
- hamilton/function_modifiers/dependencies.py +246 -0
- hamilton/function_modifiers/expanders.py +1230 -0
- hamilton/function_modifiers/macros.py +1634 -0
- hamilton/function_modifiers/metadata.py +434 -0
- hamilton/function_modifiers/recursive.py +908 -0
- hamilton/function_modifiers/validation.py +289 -0
- hamilton/function_modifiers_base.py +31 -0
- hamilton/graph.py +1153 -0
- hamilton/graph_types.py +264 -0
- hamilton/graph_utils.py +41 -0
- hamilton/htypes.py +450 -0
- hamilton/io/__init__.py +32 -0
- hamilton/io/data_adapters.py +216 -0
- hamilton/io/default_data_loaders.py +224 -0
- hamilton/io/materialization.py +500 -0
- hamilton/io/utils.py +158 -0
- hamilton/lifecycle/__init__.py +67 -0
- hamilton/lifecycle/api.py +833 -0
- hamilton/lifecycle/base.py +1130 -0
- hamilton/lifecycle/default.py +802 -0
- hamilton/log_setup.py +47 -0
- hamilton/models.py +92 -0
- hamilton/node.py +449 -0
- hamilton/plugins/README.md +48 -0
- hamilton/plugins/__init__.py +16 -0
- hamilton/plugins/dask_extensions.py +47 -0
- hamilton/plugins/dlt_extensions.py +161 -0
- hamilton/plugins/geopandas_extensions.py +49 -0
- hamilton/plugins/h_dask.py +331 -0
- hamilton/plugins/h_ddog.py +522 -0
- hamilton/plugins/h_diskcache.py +163 -0
- hamilton/plugins/h_experiments/__init__.py +22 -0
- hamilton/plugins/h_experiments/__main__.py +62 -0
- hamilton/plugins/h_experiments/cache.py +39 -0
- hamilton/plugins/h_experiments/data_model.py +68 -0
- hamilton/plugins/h_experiments/hook.py +219 -0
- hamilton/plugins/h_experiments/server.py +375 -0
- hamilton/plugins/h_kedro.py +152 -0
- hamilton/plugins/h_logging.py +454 -0
- hamilton/plugins/h_mcp/__init__.py +28 -0
- hamilton/plugins/h_mcp/__main__.py +33 -0
- hamilton/plugins/h_mcp/_helpers.py +129 -0
- hamilton/plugins/h_mcp/_templates.py +417 -0
- hamilton/plugins/h_mcp/server.py +328 -0
- hamilton/plugins/h_mlflow.py +335 -0
- hamilton/plugins/h_narwhals.py +134 -0
- hamilton/plugins/h_openlineage.py +400 -0
- hamilton/plugins/h_opentelemetry.py +167 -0
- hamilton/plugins/h_pandas.py +257 -0
- hamilton/plugins/h_pandera.py +117 -0
- hamilton/plugins/h_polars.py +304 -0
- hamilton/plugins/h_polars_lazyframe.py +282 -0
- hamilton/plugins/h_pyarrow.py +56 -0
- hamilton/plugins/h_pydantic.py +127 -0
- hamilton/plugins/h_ray.py +242 -0
- hamilton/plugins/h_rich.py +142 -0
- hamilton/plugins/h_schema.py +493 -0
- hamilton/plugins/h_slack.py +100 -0
- hamilton/plugins/h_spark.py +1380 -0
- hamilton/plugins/h_threadpool.py +125 -0
- hamilton/plugins/h_tqdm.py +122 -0
- hamilton/plugins/h_vaex.py +129 -0
- hamilton/plugins/huggingface_extensions.py +236 -0
- hamilton/plugins/ibis_extensions.py +93 -0
- hamilton/plugins/jupyter_magic.py +622 -0
- hamilton/plugins/kedro_extensions.py +117 -0
- hamilton/plugins/lightgbm_extensions.py +99 -0
- hamilton/plugins/matplotlib_extensions.py +108 -0
- hamilton/plugins/mlflow_extensions.py +216 -0
- hamilton/plugins/numpy_extensions.py +105 -0
- hamilton/plugins/pandas_extensions.py +1763 -0
- hamilton/plugins/plotly_extensions.py +150 -0
- hamilton/plugins/polars_extensions.py +71 -0
- hamilton/plugins/polars_implementations.py +25 -0
- hamilton/plugins/polars_lazyframe_extensions.py +302 -0
- hamilton/plugins/polars_post_1_0_0_extensions.py +877 -0
- hamilton/plugins/polars_pre_1_0_0_extension.py +836 -0
- hamilton/plugins/pydantic_extensions.py +98 -0
- hamilton/plugins/pyspark_pandas_extensions.py +47 -0
- hamilton/plugins/sklearn_plot_extensions.py +129 -0
- hamilton/plugins/spark_extensions.py +105 -0
- hamilton/plugins/vaex_extensions.py +51 -0
- hamilton/plugins/xgboost_extensions.py +91 -0
- hamilton/plugins/yaml_extensions.py +89 -0
- hamilton/registry.py +254 -0
- hamilton/settings.py +18 -0
- hamilton/telemetry.py +50 -0
- hamilton/version.py +18 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
|
3
|
+
# distributed with this work for additional information
|
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
|
6
|
+
# "License"); you may not use this file except in compliance
|
|
7
|
+
# with the License. You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
18
|
+
import abc
|
|
19
|
+
import asyncio
|
|
20
|
+
from collections import defaultdict
|
|
21
|
+
from collections.abc import Callable, Collection
|
|
22
|
+
from typing import Any
|
|
23
|
+
|
|
24
|
+
from hamilton import node
|
|
25
|
+
from hamilton.data_quality import base as dq_base
|
|
26
|
+
from hamilton.data_quality import default_validators
|
|
27
|
+
from hamilton.function_modifiers import base
|
|
28
|
+
|
|
29
|
+
"""Decorators that validate artifacts of a node"""
|
|
30
|
+
|
|
31
|
+
IS_DATA_VALIDATOR_TAG = "hamilton.data_quality.contains_dq_results"
|
|
32
|
+
DATA_VALIDATOR_ORIGINAL_OUTPUT_TAG = "hamilton.data_quality.source_node"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class BaseDataValidationDecorator(base.NodeTransformer):
|
|
36
|
+
@abc.abstractmethod
|
|
37
|
+
def get_validators(self, node_to_validate: node.Node) -> list[dq_base.DataValidator]:
|
|
38
|
+
"""Returns a list of validators used to transform the nodes.
|
|
39
|
+
|
|
40
|
+
:param node_to_validate: Nodes to which the output of the validator will apply
|
|
41
|
+
:return: A list of validators to apply to the node.
|
|
42
|
+
"""
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
def transform_node(
|
|
46
|
+
self, node_: node.Node, config: dict[str, Any], fn: Callable
|
|
47
|
+
) -> Collection[node.Node]:
|
|
48
|
+
raw_node = node.Node(
|
|
49
|
+
name=node_.name
|
|
50
|
+
+ "_raw", # TODO -- make this unique -- this will break with multiple validation decorators, which we *don't* want
|
|
51
|
+
typ=node_.type,
|
|
52
|
+
doc_string=node_.documentation,
|
|
53
|
+
callabl=node_.callable,
|
|
54
|
+
node_source=node_.node_role,
|
|
55
|
+
input_types=node_.input_types,
|
|
56
|
+
tags=node_.tags,
|
|
57
|
+
)
|
|
58
|
+
validators = self.get_validators(node_)
|
|
59
|
+
validator_nodes = []
|
|
60
|
+
validator_name_map = {}
|
|
61
|
+
validator_name_count = defaultdict(int)
|
|
62
|
+
for validator in validators:
|
|
63
|
+
if dq_base.is_async_validator(validator):
|
|
64
|
+
|
|
65
|
+
async def validation_function(
|
|
66
|
+
validator_to_call: dq_base.DataValidator = validator, **kwargs
|
|
67
|
+
):
|
|
68
|
+
result = list(kwargs.values())[0] # This should just have one kwarg
|
|
69
|
+
return await validator_to_call.validate(result)
|
|
70
|
+
|
|
71
|
+
else:
|
|
72
|
+
|
|
73
|
+
def validation_function(
|
|
74
|
+
validator_to_call: dq_base.DataValidator = validator, **kwargs
|
|
75
|
+
):
|
|
76
|
+
result = list(kwargs.values())[0] # This should just have one kwarg
|
|
77
|
+
validation_result = validator_to_call.validate(result)
|
|
78
|
+
if asyncio.iscoroutine(validation_result):
|
|
79
|
+
validation_result.close()
|
|
80
|
+
raise TypeError(
|
|
81
|
+
f"Validator '{validator_to_call.name()}' returned a coroutine. "
|
|
82
|
+
f"Use AsyncDriver for async validators."
|
|
83
|
+
)
|
|
84
|
+
return validation_result
|
|
85
|
+
|
|
86
|
+
validator_node_name = node_.name + "_" + validator.name()
|
|
87
|
+
validator_name_count[validator_node_name] = (
|
|
88
|
+
validator_name_count[validator_node_name] + 1
|
|
89
|
+
)
|
|
90
|
+
if validator_name_count[validator_node_name] > 1:
|
|
91
|
+
validator_node_name = (
|
|
92
|
+
validator_node_name + "_" + str(validator_name_count[validator_node_name] - 1)
|
|
93
|
+
)
|
|
94
|
+
validator_node = node.Node(
|
|
95
|
+
name=validator_node_name, # TODO -- determine a good approach towards naming this
|
|
96
|
+
typ=dq_base.ValidationResult,
|
|
97
|
+
doc_string=validator.description(),
|
|
98
|
+
callabl=validation_function,
|
|
99
|
+
node_source=node.NodeType.STANDARD,
|
|
100
|
+
input_types={raw_node.name: (node_.type, node.DependencyType.REQUIRED)},
|
|
101
|
+
tags={
|
|
102
|
+
**node_.tags,
|
|
103
|
+
**{
|
|
104
|
+
IS_DATA_VALIDATOR_TAG: True,
|
|
105
|
+
DATA_VALIDATOR_ORIGINAL_OUTPUT_TAG: node_.name,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
)
|
|
109
|
+
validator_name_map[validator_node_name] = validator
|
|
110
|
+
validator_nodes.append(validator_node)
|
|
111
|
+
|
|
112
|
+
def final_node_callable(
|
|
113
|
+
validator_nodes=validator_nodes, validator_name_map=validator_name_map, **kwargs
|
|
114
|
+
):
|
|
115
|
+
"""Callable for the final node. First calls the action on every node, then
|
|
116
|
+
|
|
117
|
+
:param validator_nodes:
|
|
118
|
+
:param validator_name_map:
|
|
119
|
+
:param kwargs:
|
|
120
|
+
:return: returns the original node output
|
|
121
|
+
"""
|
|
122
|
+
failures = []
|
|
123
|
+
for validator_node in validator_nodes:
|
|
124
|
+
validator: dq_base.DataValidator = validator_name_map[validator_node.name]
|
|
125
|
+
validation_result: dq_base.ValidationResult = kwargs[validator_node.name]
|
|
126
|
+
if validator.importance == dq_base.DataValidationLevel.WARN:
|
|
127
|
+
dq_base.act_warn(node_.name, validation_result, validator)
|
|
128
|
+
else:
|
|
129
|
+
failures.append((validation_result, validator))
|
|
130
|
+
dq_base.act_fail_bulk(node_.name, failures)
|
|
131
|
+
return kwargs[raw_node.name]
|
|
132
|
+
|
|
133
|
+
final_node = node.Node(
|
|
134
|
+
name=node_.name,
|
|
135
|
+
typ=node_.type,
|
|
136
|
+
doc_string=node_.documentation,
|
|
137
|
+
callabl=final_node_callable,
|
|
138
|
+
node_source=node_.node_role,
|
|
139
|
+
input_types={
|
|
140
|
+
raw_node.name: (node_.type, node.DependencyType.REQUIRED),
|
|
141
|
+
**{
|
|
142
|
+
validator_node.name: (validator_node.type, node.DependencyType.REQUIRED)
|
|
143
|
+
for validator_node in validator_nodes
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
tags=node_.tags,
|
|
147
|
+
)
|
|
148
|
+
return [*validator_nodes, final_node, raw_node]
|
|
149
|
+
|
|
150
|
+
def validate(self, fn: Callable):
|
|
151
|
+
pass
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class check_output_custom(BaseDataValidationDecorator):
|
|
155
|
+
"""Class to use if you want to implement your own custom validators.
|
|
156
|
+
|
|
157
|
+
Come chat to us in slack if you're interested in this!
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
def __init__(self, *validators: dq_base.DataValidator, target_: base.TargetType = None):
|
|
161
|
+
"""Creates a check_output_custom decorator. This allows passing of custom validators that implement the \
|
|
162
|
+
DataValidator interface.
|
|
163
|
+
|
|
164
|
+
:param validators: Validator to use.
|
|
165
|
+
:param target\\_: The nodes to check the output of. For more detail read the docs in\
|
|
166
|
+
function_modifiers.base.NodeTransformer, but your options are:
|
|
167
|
+
|
|
168
|
+
1. **None**: This will check just the "final node" (the node that is returned by the decorated function).
|
|
169
|
+
2. **... (Ellipsis)**: This will check all nodes in the subDAG created by this.
|
|
170
|
+
3. **string**: This will check the node with the given name.
|
|
171
|
+
4. **Collection[str]**: This will check all nodes specified in the list.
|
|
172
|
+
|
|
173
|
+
In all likelihood, you *don't* want ``...``, but the others are useful.
|
|
174
|
+
|
|
175
|
+
Note: you cannot stack `@check_output_custom` decorators. If you want to use multiple custom validators, \
|
|
176
|
+
you should pass them all in as arguments to a single `@check_output_custom` decorator.
|
|
177
|
+
|
|
178
|
+
"""
|
|
179
|
+
super(check_output_custom, self).__init__(target=target_)
|
|
180
|
+
self.validators = list(validators)
|
|
181
|
+
|
|
182
|
+
def get_validators(self, node_to_validate: node.Node) -> list[dq_base.DataValidator]:
|
|
183
|
+
return self.validators
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class check_output(BaseDataValidationDecorator):
|
|
187
|
+
"""The ``@check_output`` decorator enables you to add simple data quality checks to your code.
|
|
188
|
+
|
|
189
|
+
For example:
|
|
190
|
+
|
|
191
|
+
.. code-block:: python
|
|
192
|
+
|
|
193
|
+
import pandas as pd
|
|
194
|
+
import numpy as np
|
|
195
|
+
from hamilton.function_modifiers import check_output
|
|
196
|
+
|
|
197
|
+
@check_output(
|
|
198
|
+
data_type=np.int64,
|
|
199
|
+
data_in_range=(0,100),
|
|
200
|
+
importance="warn",
|
|
201
|
+
)
|
|
202
|
+
def some_int_data_between_0_and_100() -> pd.Series:
|
|
203
|
+
...
|
|
204
|
+
|
|
205
|
+
The check_output decorator takes in arguments that each correspond to one of the default validators. These \
|
|
206
|
+
arguments tell it to add the default validator to the list. The above thus creates two validators, one that checks \
|
|
207
|
+
the datatype of the series, and one that checks whether the data is in a certain range.
|
|
208
|
+
|
|
209
|
+
Pandera example that shows how to use the check_output decorator with a Pandera schema:
|
|
210
|
+
|
|
211
|
+
.. code-block:: python
|
|
212
|
+
|
|
213
|
+
import pandas as pd
|
|
214
|
+
import pandera as pa
|
|
215
|
+
from hamilton.function_modifiers import check_output
|
|
216
|
+
from hamilton.function_modifiers import extract_columns
|
|
217
|
+
|
|
218
|
+
schema = pa.DataFrameSchema(...)
|
|
219
|
+
|
|
220
|
+
@extract_columns('col1', 'col2')
|
|
221
|
+
@check_output(schema=schema, target_="builds_dataframe", importance="fail")
|
|
222
|
+
def builds_dataframe(...) -> pd.DataFrame:
|
|
223
|
+
...
|
|
224
|
+
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
def get_validators(self, node_to_validate: node.Node) -> list[dq_base.DataValidator]:
|
|
228
|
+
try:
|
|
229
|
+
return default_validators.resolve_default_validators(
|
|
230
|
+
node_to_validate.type,
|
|
231
|
+
importance=self.importance,
|
|
232
|
+
available_validators=self.default_validator_candidates,
|
|
233
|
+
**self.default_validator_kwargs,
|
|
234
|
+
)
|
|
235
|
+
except ValueError as e:
|
|
236
|
+
raise ValueError(
|
|
237
|
+
f"Could not resolve validators for @check_output for function [{node_to_validate.name}]. "
|
|
238
|
+
f"Please check that `target_` is set correctly if you're using that argument.\n"
|
|
239
|
+
f"Actual error: {e}"
|
|
240
|
+
) from e
|
|
241
|
+
|
|
242
|
+
def __init__(
|
|
243
|
+
self,
|
|
244
|
+
importance: str = dq_base.DataValidationLevel.WARN.value,
|
|
245
|
+
default_validator_candidates: list[type[dq_base.BaseDefaultValidator]] = None,
|
|
246
|
+
target_: base.TargetType = None,
|
|
247
|
+
**default_validator_kwargs: Any,
|
|
248
|
+
):
|
|
249
|
+
"""Creates the check_output validator.
|
|
250
|
+
|
|
251
|
+
This constructs the default validator class.
|
|
252
|
+
|
|
253
|
+
Note: that this creates a whole set of default validators.
|
|
254
|
+
TODO -- enable construction of custom validators using check_output.custom(\\*validators).
|
|
255
|
+
|
|
256
|
+
:param importance: For the default validator, how important is it that this passes.
|
|
257
|
+
:param default_validator_candidates: List of validators to be considerred for this check.
|
|
258
|
+
:param default_validator_kwargs: keyword arguments to be passed to the validator.
|
|
259
|
+
:param target\\_: a target specifying which nodes to decorate. See the docs in check_output_custom\
|
|
260
|
+
for a quick overview and the docs in function_modifiers.base.NodeTransformer for more detail.
|
|
261
|
+
"""
|
|
262
|
+
super(check_output, self).__init__(target=target_)
|
|
263
|
+
self.importance = importance
|
|
264
|
+
self.default_validator_kwargs = default_validator_kwargs
|
|
265
|
+
self.default_validator_candidates = default_validator_candidates
|
|
266
|
+
# We need to wait until we actually have the function in order to construct the validators
|
|
267
|
+
# So, we'll just store the constructor arguments for now and check it in validation
|
|
268
|
+
|
|
269
|
+
@staticmethod
|
|
270
|
+
def _validate_constructor_args(
|
|
271
|
+
*validator: dq_base.DataValidator, importance: str = None, **default_validator_kwargs: Any
|
|
272
|
+
):
|
|
273
|
+
if len(validator) != 0:
|
|
274
|
+
if importance is not None or len(default_validator_kwargs) > 0:
|
|
275
|
+
raise ValueError(
|
|
276
|
+
"Can provide *either* a list of custom validators or arguments for the default validator. "
|
|
277
|
+
"Instead received both."
|
|
278
|
+
)
|
|
279
|
+
else:
|
|
280
|
+
if importance is None:
|
|
281
|
+
raise ValueError("Must supply an importance level if using the default validator.")
|
|
282
|
+
|
|
283
|
+
def validate(self, fn: Callable):
|
|
284
|
+
"""Validates that the check_output node works on the function on which it was called
|
|
285
|
+
|
|
286
|
+
:param fn: Function to validate
|
|
287
|
+
:raises: InvalidDecoratorException if the decorator is not valid for the function's return type
|
|
288
|
+
"""
|
|
289
|
+
pass
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
|
3
|
+
# distributed with this work for additional information
|
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
|
6
|
+
# "License"); you may not use this file except in compliance
|
|
7
|
+
# with the License. You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
18
|
+
# Quick hack to make this a backwards compatible refactor
|
|
19
|
+
# This allows us to define everything within the function_modifiers directory, and just refer to that
|
|
20
|
+
# While maintaining old imports
|
|
21
|
+
import logging
|
|
22
|
+
|
|
23
|
+
from hamilton.function_modifiers.base import * # noqa F403
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
logger.warning(
|
|
27
|
+
"Import of this module is deprecated, and will be removed in a 2.0 release. In fact, "
|
|
28
|
+
"this is not a public-facing API, so if you're hitting this message either we're internally "
|
|
29
|
+
"importing the wrong one or you're doing something fancy. Either way, \n"
|
|
30
|
+
"please replace with `from hamilton.function_modifiers import base as fm_base`."
|
|
31
|
+
)
|