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.
Files changed (151) hide show
  1. apache_hamilton-1.90.0.dev0.dist-info/METADATA +407 -0
  2. apache_hamilton-1.90.0.dev0.dist-info/RECORD +151 -0
  3. apache_hamilton-1.90.0.dev0.dist-info/WHEEL +4 -0
  4. apache_hamilton-1.90.0.dev0.dist-info/entry_points.txt +9 -0
  5. apache_hamilton-1.90.0.dev0.dist-info/licenses/DISCLAIMER +10 -0
  6. apache_hamilton-1.90.0.dev0.dist-info/licenses/LICENSE +228 -0
  7. apache_hamilton-1.90.0.dev0.dist-info/licenses/NOTICE +5 -0
  8. hamilton/__init__.py +24 -0
  9. hamilton/ad_hoc_utils.py +132 -0
  10. hamilton/async_driver.py +465 -0
  11. hamilton/base.py +466 -0
  12. hamilton/caching/__init__.py +16 -0
  13. hamilton/caching/adapter.py +1475 -0
  14. hamilton/caching/cache_key.py +70 -0
  15. hamilton/caching/fingerprinting.py +287 -0
  16. hamilton/caching/stores/__init__.py +16 -0
  17. hamilton/caching/stores/base.py +242 -0
  18. hamilton/caching/stores/file.py +140 -0
  19. hamilton/caching/stores/memory.py +297 -0
  20. hamilton/caching/stores/sqlite.py +282 -0
  21. hamilton/caching/stores/utils.py +40 -0
  22. hamilton/cli/__init__.py +16 -0
  23. hamilton/cli/__main__.py +328 -0
  24. hamilton/cli/commands.py +126 -0
  25. hamilton/cli/logic.py +338 -0
  26. hamilton/common/__init__.py +76 -0
  27. hamilton/contrib/__init__.py +41 -0
  28. hamilton/data_quality/__init__.py +16 -0
  29. hamilton/data_quality/base.py +198 -0
  30. hamilton/data_quality/default_validators.py +560 -0
  31. hamilton/data_quality/pandera_validators.py +121 -0
  32. hamilton/dataflows/__init__.py +726 -0
  33. hamilton/dataflows/template/README.md +25 -0
  34. hamilton/dataflows/template/__init__.py +54 -0
  35. hamilton/dataflows/template/author.md +28 -0
  36. hamilton/dataflows/template/requirements.txt +0 -0
  37. hamilton/dataflows/template/tags.json +7 -0
  38. hamilton/dataflows/template/valid_configs.jsonl +1 -0
  39. hamilton/dev_utils/__init__.py +16 -0
  40. hamilton/dev_utils/deprecation.py +204 -0
  41. hamilton/driver.py +2112 -0
  42. hamilton/execution/__init__.py +16 -0
  43. hamilton/execution/debugging_utils.py +56 -0
  44. hamilton/execution/executors.py +502 -0
  45. hamilton/execution/graph_functions.py +421 -0
  46. hamilton/execution/grouping.py +430 -0
  47. hamilton/execution/state.py +539 -0
  48. hamilton/experimental/__init__.py +27 -0
  49. hamilton/experimental/databackend.py +61 -0
  50. hamilton/experimental/decorators/__init__.py +16 -0
  51. hamilton/experimental/decorators/parameterize_frame.py +233 -0
  52. hamilton/experimental/h_async.py +29 -0
  53. hamilton/experimental/h_cache.py +413 -0
  54. hamilton/experimental/h_dask.py +28 -0
  55. hamilton/experimental/h_databackends.py +174 -0
  56. hamilton/experimental/h_ray.py +28 -0
  57. hamilton/experimental/h_spark.py +32 -0
  58. hamilton/function_modifiers/README +40 -0
  59. hamilton/function_modifiers/__init__.py +121 -0
  60. hamilton/function_modifiers/adapters.py +900 -0
  61. hamilton/function_modifiers/base.py +859 -0
  62. hamilton/function_modifiers/configuration.py +310 -0
  63. hamilton/function_modifiers/delayed.py +202 -0
  64. hamilton/function_modifiers/dependencies.py +246 -0
  65. hamilton/function_modifiers/expanders.py +1230 -0
  66. hamilton/function_modifiers/macros.py +1634 -0
  67. hamilton/function_modifiers/metadata.py +434 -0
  68. hamilton/function_modifiers/recursive.py +908 -0
  69. hamilton/function_modifiers/validation.py +289 -0
  70. hamilton/function_modifiers_base.py +31 -0
  71. hamilton/graph.py +1153 -0
  72. hamilton/graph_types.py +264 -0
  73. hamilton/graph_utils.py +41 -0
  74. hamilton/htypes.py +450 -0
  75. hamilton/io/__init__.py +32 -0
  76. hamilton/io/data_adapters.py +216 -0
  77. hamilton/io/default_data_loaders.py +224 -0
  78. hamilton/io/materialization.py +500 -0
  79. hamilton/io/utils.py +158 -0
  80. hamilton/lifecycle/__init__.py +67 -0
  81. hamilton/lifecycle/api.py +833 -0
  82. hamilton/lifecycle/base.py +1130 -0
  83. hamilton/lifecycle/default.py +802 -0
  84. hamilton/log_setup.py +47 -0
  85. hamilton/models.py +92 -0
  86. hamilton/node.py +449 -0
  87. hamilton/plugins/README.md +48 -0
  88. hamilton/plugins/__init__.py +16 -0
  89. hamilton/plugins/dask_extensions.py +47 -0
  90. hamilton/plugins/dlt_extensions.py +161 -0
  91. hamilton/plugins/geopandas_extensions.py +49 -0
  92. hamilton/plugins/h_dask.py +331 -0
  93. hamilton/plugins/h_ddog.py +522 -0
  94. hamilton/plugins/h_diskcache.py +163 -0
  95. hamilton/plugins/h_experiments/__init__.py +22 -0
  96. hamilton/plugins/h_experiments/__main__.py +62 -0
  97. hamilton/plugins/h_experiments/cache.py +39 -0
  98. hamilton/plugins/h_experiments/data_model.py +68 -0
  99. hamilton/plugins/h_experiments/hook.py +219 -0
  100. hamilton/plugins/h_experiments/server.py +375 -0
  101. hamilton/plugins/h_kedro.py +152 -0
  102. hamilton/plugins/h_logging.py +454 -0
  103. hamilton/plugins/h_mcp/__init__.py +28 -0
  104. hamilton/plugins/h_mcp/__main__.py +33 -0
  105. hamilton/plugins/h_mcp/_helpers.py +129 -0
  106. hamilton/plugins/h_mcp/_templates.py +417 -0
  107. hamilton/plugins/h_mcp/server.py +328 -0
  108. hamilton/plugins/h_mlflow.py +335 -0
  109. hamilton/plugins/h_narwhals.py +134 -0
  110. hamilton/plugins/h_openlineage.py +400 -0
  111. hamilton/plugins/h_opentelemetry.py +167 -0
  112. hamilton/plugins/h_pandas.py +257 -0
  113. hamilton/plugins/h_pandera.py +117 -0
  114. hamilton/plugins/h_polars.py +304 -0
  115. hamilton/plugins/h_polars_lazyframe.py +282 -0
  116. hamilton/plugins/h_pyarrow.py +56 -0
  117. hamilton/plugins/h_pydantic.py +127 -0
  118. hamilton/plugins/h_ray.py +242 -0
  119. hamilton/plugins/h_rich.py +142 -0
  120. hamilton/plugins/h_schema.py +493 -0
  121. hamilton/plugins/h_slack.py +100 -0
  122. hamilton/plugins/h_spark.py +1380 -0
  123. hamilton/plugins/h_threadpool.py +125 -0
  124. hamilton/plugins/h_tqdm.py +122 -0
  125. hamilton/plugins/h_vaex.py +129 -0
  126. hamilton/plugins/huggingface_extensions.py +236 -0
  127. hamilton/plugins/ibis_extensions.py +93 -0
  128. hamilton/plugins/jupyter_magic.py +622 -0
  129. hamilton/plugins/kedro_extensions.py +117 -0
  130. hamilton/plugins/lightgbm_extensions.py +99 -0
  131. hamilton/plugins/matplotlib_extensions.py +108 -0
  132. hamilton/plugins/mlflow_extensions.py +216 -0
  133. hamilton/plugins/numpy_extensions.py +105 -0
  134. hamilton/plugins/pandas_extensions.py +1763 -0
  135. hamilton/plugins/plotly_extensions.py +150 -0
  136. hamilton/plugins/polars_extensions.py +71 -0
  137. hamilton/plugins/polars_implementations.py +25 -0
  138. hamilton/plugins/polars_lazyframe_extensions.py +302 -0
  139. hamilton/plugins/polars_post_1_0_0_extensions.py +877 -0
  140. hamilton/plugins/polars_pre_1_0_0_extension.py +836 -0
  141. hamilton/plugins/pydantic_extensions.py +98 -0
  142. hamilton/plugins/pyspark_pandas_extensions.py +47 -0
  143. hamilton/plugins/sklearn_plot_extensions.py +129 -0
  144. hamilton/plugins/spark_extensions.py +105 -0
  145. hamilton/plugins/vaex_extensions.py +51 -0
  146. hamilton/plugins/xgboost_extensions.py +91 -0
  147. hamilton/plugins/yaml_extensions.py +89 -0
  148. hamilton/registry.py +254 -0
  149. hamilton/settings.py +18 -0
  150. hamilton/telemetry.py +50 -0
  151. hamilton/version.py +18 -0
@@ -0,0 +1,198 @@
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 dataclasses
20
+ import enum
21
+ import inspect
22
+ import logging
23
+ from typing import Any
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+
28
+ class DataValidationError(Exception):
29
+ pass
30
+
31
+
32
+ class DataValidationLevel(enum.Enum):
33
+ WARN = "warn"
34
+ FAIL = "fail"
35
+
36
+
37
+ @dataclasses.dataclass
38
+ class ValidationResult:
39
+ passes: bool # Whether or not this passed the validation
40
+ message: str # Error message or success message
41
+ diagnostics: dict[str, Any] = dataclasses.field(
42
+ default_factory=dict
43
+ ) # Any extra diagnostics information needed, free-form
44
+
45
+
46
+ class DataValidator(abc.ABC):
47
+ """Base class for a data quality operator. This will be used by the `data_quality` operator"""
48
+
49
+ def __init__(self, importance: str):
50
+ self._importance = DataValidationLevel(importance)
51
+
52
+ @property
53
+ def importance(self) -> DataValidationLevel:
54
+ return self._importance
55
+
56
+ @abc.abstractmethod
57
+ def applies_to(self, datatype: type[type]) -> bool:
58
+ """Whether or not this data validator can apply to the specified dataset
59
+
60
+ :param datatype:
61
+ :return: True if it can be run on the specified type, false otherwise
62
+ """
63
+ pass
64
+
65
+ @abc.abstractmethod
66
+ def description(self) -> str:
67
+ """Gives a description of this validator. E.G.
68
+ `Checks whether the entire dataset lies between 0 and 1.`
69
+ Note it should be able to access internal state (E.G. constructor arguments).
70
+ :return: The description of the validator as a string
71
+ """
72
+ pass
73
+
74
+ @classmethod
75
+ @abc.abstractmethod
76
+ def name(cls) -> str:
77
+ """Returns the name for this validator."""
78
+
79
+ @abc.abstractmethod
80
+ def validate(self, dataset: Any) -> ValidationResult:
81
+ """Actually performs the validation. Note when you
82
+
83
+ :param dataset: dataset to validate
84
+ :return: The result of validation
85
+ """
86
+ pass
87
+
88
+
89
+ class AsyncDataValidator(DataValidator, abc.ABC):
90
+ """Base class for an async data quality operator. Use this when validation requires async operations
91
+ (e.g. async database queries, async API calls). Must be used with AsyncDriver."""
92
+
93
+ @abc.abstractmethod
94
+ async def validate(self, dataset: Any) -> ValidationResult:
95
+ """Asynchronously performs the validation.
96
+
97
+ :param dataset: dataset to validate
98
+ :return: The result of validation
99
+ """
100
+ pass
101
+
102
+
103
+ def is_async_validator(validator: DataValidator) -> bool:
104
+ """Checks whether a validator's validate method is a coroutine function.
105
+
106
+ :param validator: The validator to check
107
+ :return: True if the validator's validate method is async
108
+ """
109
+ return inspect.iscoroutinefunction(validator.validate)
110
+
111
+
112
+ def act_warn(node_name: str, validation_result: ValidationResult, validator: DataValidator):
113
+ """This is the current default for acting on the validation result when you want to warn.
114
+ Note that we might move this at some point -- we'll want to make it configurable. But for now, this
115
+ seems like a fine place to put it.
116
+
117
+ :param node_name: the name of the node we are validating.
118
+ :param validation_result: the result
119
+ :param validator: the validator object.
120
+ """
121
+ if not validation_result.passes:
122
+ logger.warning(_create_error_string(node_name, validation_result, validator))
123
+
124
+
125
+ def _create_error_string(node_name, validation_result, validator):
126
+ return (
127
+ f"[{node_name}:{validator.name()}] validator failed. Message was: {validation_result.message}. "
128
+ f"Diagnostic information is: {validation_result.diagnostics}."
129
+ )
130
+
131
+
132
+ def act_fail_bulk(node_name: str, failures: list[tuple[ValidationResult, DataValidator]]):
133
+ """This is the current default for acting on the validation result when you want to fail.
134
+ Note that we might move this at some point -- we'll want to make it configurable. But for now, this
135
+ seems like a fine place to put it.
136
+ :param node_name: the name of the node we are validating.
137
+ :param failures: list of tuples of (validation_result, validator)
138
+ :raises DataValidationError: if there are errors detected.
139
+ """
140
+ error_messages = []
141
+ for validation_result, validator in failures:
142
+ if not validation_result.passes:
143
+ message = f"{_create_error_string(node_name, validation_result, validator)}\n"
144
+ logger.error(message) # log here so things print nicely at least
145
+ error_messages.append(message)
146
+ if error_messages:
147
+ raise DataValidationError(error_messages)
148
+
149
+
150
+ class BaseDefaultValidator(DataValidator, abc.ABC):
151
+ """Base class for a default validator.
152
+ These are all validators that utilize a single argument to be passed to the decorator check_output.
153
+ check_output can thus delegate to multiple of these. This is an internal abstraction to allow for easy
154
+ creation of validators.
155
+ """
156
+
157
+ def __init__(self, importance: str):
158
+ super(BaseDefaultValidator, self).__init__(importance)
159
+
160
+ @classmethod
161
+ @abc.abstractmethod
162
+ def applies_to(cls, datatype: type[type]) -> bool:
163
+ pass
164
+
165
+ @abc.abstractmethod
166
+ def description(self) -> str:
167
+ pass
168
+
169
+ @abc.abstractmethod
170
+ def validate(self, data: Any) -> ValidationResult:
171
+ pass
172
+
173
+ @classmethod
174
+ @abc.abstractmethod
175
+ def arg(cls) -> str:
176
+ """Yields a string that represents this validator's argument.
177
+ @check_output() will be passed a series of kwargs, each one of which will correspond to
178
+ one of these default validators. Note that we have the limitation of allowing just a single
179
+ argument.
180
+
181
+ :return: The argument that this needs.
182
+ """
183
+ pass
184
+
185
+ @classmethod
186
+ def name(cls) -> str:
187
+ return f"{cls.arg()}_validator"
188
+
189
+
190
+ class AsyncBaseDefaultValidator(BaseDefaultValidator, abc.ABC):
191
+ """Base class for an async default validator.
192
+ Async variant of BaseDefaultValidator for validators that require async operations.
193
+ Must be used with AsyncDriver.
194
+ """
195
+
196
+ @abc.abstractmethod
197
+ async def validate(self, data: Any) -> ValidationResult:
198
+ pass