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
hamilton/registry.py ADDED
@@ -0,0 +1,254 @@
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 collections
19
+ import configparser
20
+ import functools
21
+ import importlib
22
+ import logging
23
+ import os
24
+ import pathlib
25
+ from typing import Any, Literal, get_args
26
+
27
+ logger = logging.getLogger(__name__)
28
+
29
+ # Use this to ensure the registry is loaded only once.
30
+ INITIALIZED = False
31
+ ExtensionName = Literal[
32
+ "yaml",
33
+ "matplotlib",
34
+ "numpy",
35
+ "pandas",
36
+ "plotly",
37
+ "polars",
38
+ "polars_lazyframe",
39
+ "pyspark_pandas",
40
+ "spark",
41
+ "dask",
42
+ "geopandas",
43
+ "xgboost",
44
+ "lightgbm",
45
+ "sklearn_plot",
46
+ "vaex",
47
+ "ibis",
48
+ "dlt",
49
+ "kedro",
50
+ "huggingface",
51
+ "mlflow",
52
+ "pydantic",
53
+ ]
54
+ HAMILTON_EXTENSIONS: tuple[ExtensionName, ...] = get_args(ExtensionName)
55
+ HAMILTON_AUTOLOAD_ENV = "HAMILTON_AUTOLOAD_EXTENSIONS"
56
+ DEFAULT_CONFIG_LOCATION = pathlib.Path("~/.hamilton.conf").expanduser()
57
+
58
+ # This is a dictionary of extension name -> dict with dataframe and column types.
59
+ DF_TYPE_AND_COLUMN_TYPES: dict[str, dict[str, type]] = {}
60
+
61
+ COLUMN_TYPE = "column_type"
62
+ DATAFRAME_TYPE = "dataframe_type"
63
+
64
+
65
+ def load_autoload_config() -> configparser.ConfigParser:
66
+ """Load the Hamilton config file and set the autoloading environment variable"""
67
+ config = configparser.ConfigParser()
68
+ config.read(DEFAULT_CONFIG_LOCATION)
69
+
70
+ if config.has_option("DEFAULT", HAMILTON_AUTOLOAD_ENV):
71
+ os.environ[HAMILTON_AUTOLOAD_ENV] = config.get("DEFAULT", HAMILTON_AUTOLOAD_ENV)
72
+
73
+ return config
74
+
75
+
76
+ load_autoload_config()
77
+
78
+
79
+ def load_extension(plugin_module: ExtensionName):
80
+ """Given a module name, loads it for Hamilton to use.
81
+
82
+ :param plugin_module: the module name sans .py. e.g. pandas, polars, pyspark_pandas.
83
+ """
84
+ mod = importlib.import_module(f"hamilton.plugins.{plugin_module}_extensions")
85
+ # We have various plugin extensions. We default to assuming it's a dataframe extension with columns,
86
+ # unless it explicitly says it's not.
87
+ # We need to check the following if we are to enable `@extract_columns` for example.
88
+ extractable = getattr(mod, "COLUMN_FRIENDLY_DF_TYPE", True)
89
+ if extractable:
90
+ assert hasattr(mod, "register_types"), "Error extension missing function register_types()"
91
+ assert hasattr(mod, f"get_column_{plugin_module}"), (
92
+ f"Error extension missing get_column_{plugin_module}"
93
+ )
94
+ assert hasattr(mod, f"fill_with_scalar_{plugin_module}"), (
95
+ f"Error extension missing fill_with_scalar_{plugin_module}"
96
+ )
97
+ logger.info(f"Detected {plugin_module} and successfully loaded Hamilton extensions.")
98
+
99
+
100
+ def initialize():
101
+ """Iterate over all extensions and try to load them"""
102
+ logger.debug(f"{HAMILTON_AUTOLOAD_ENV}={os.environ.get(HAMILTON_AUTOLOAD_ENV)}")
103
+ for extension_name in HAMILTON_EXTENSIONS:
104
+ # skip modules that aren't explicitly imported by the user
105
+ if str(os.environ.get(HAMILTON_AUTOLOAD_ENV)) == "0":
106
+ continue
107
+
108
+ try:
109
+ load_extension(extension_name)
110
+ except (NotImplementedError, ImportError, Warning) as e:
111
+ logger.debug(f"Did not load {extension_name} extension because {str(e)}.")
112
+
113
+ global INITIALIZED
114
+ INITIALIZED = True
115
+
116
+
117
+ def disable_autoload():
118
+ """Disable extension autoloading by setting an environment variable.
119
+ This needs to be done before hamilton.driver is imported.
120
+ """
121
+ os.environ[HAMILTON_AUTOLOAD_ENV] = "0"
122
+
123
+
124
+ def enable_autoload():
125
+ """Enable extension autoloading by deleting an environment variable.
126
+ This needs to be done before hamilton.driver is imported.
127
+ """
128
+ del os.environ[HAMILTON_AUTOLOAD_ENV]
129
+
130
+
131
+ def config_enable_autoload():
132
+ """Modify the Hamilton config file to enable extension autoloading.
133
+ Autoloading can be disabled manually via `hamilton.registry.disable_autoload()`
134
+ before importing `hamilton.driver`.
135
+
136
+ NOTE the function name is tied to an entrypoint in `pyproject.toml`
137
+ """
138
+ config = load_autoload_config()
139
+ if "DEFAULT" not in config:
140
+ config.add_section("DEFAULT")
141
+
142
+ config.remove_option("DEFAULT", HAMILTON_AUTOLOAD_ENV)
143
+ with DEFAULT_CONFIG_LOCATION.open("w") as f:
144
+ config.write(f)
145
+
146
+
147
+ def config_disable_autoload():
148
+ """Modify the Hamilton config file to disable extension autoloading.
149
+ Autoloading can be enabled manually via `hamilton.registry.enable_autoload()`
150
+ before importing `hamilton.driver`.
151
+
152
+ NOTE the function name is tied to an entrypoint in `pyproject.toml`
153
+ """
154
+ config = load_autoload_config()
155
+ if "DEFAULT" not in config:
156
+ config.add_section("DEFAULT")
157
+
158
+ config.set("DEFAULT", HAMILTON_AUTOLOAD_ENV, "0")
159
+ with DEFAULT_CONFIG_LOCATION.open("w") as f:
160
+ config.write(f)
161
+
162
+
163
+ def register_types(extension_name: str, dataframe_type: type, column_type: type | None):
164
+ """Registers the dataframe and column types for the extension. Note that column types are optional
165
+ as some extensions may not have a column type (E.G. spark). In this case, this is not included
166
+
167
+ :param extension_name: name of the extension doing the registering.
168
+ :param dataframe_type: the dataframe type to register.
169
+ :param column_type: the column type to register
170
+ """
171
+ global DF_TYPE_AND_COLUMN_TYPES
172
+ output = {}
173
+ output[DATAFRAME_TYPE] = dataframe_type
174
+ if column_type is not None:
175
+ output[COLUMN_TYPE] = column_type
176
+ DF_TYPE_AND_COLUMN_TYPES[extension_name] = output
177
+
178
+
179
+ @functools.singledispatch
180
+ def get_column(df: Any, column_name: str):
181
+ """Gets a column from a dataframe.
182
+
183
+ Each extension should register a function for this.
184
+
185
+ :param df: the dataframe.
186
+ :param column_name: the column name.
187
+ :return: the correct "representation" of a column for this "dataframe".
188
+ """
189
+ raise NotImplementedError()
190
+
191
+
192
+ @functools.singledispatch
193
+ def fill_with_scalar(df: Any, column_name: str, scalar_value: Any) -> Any:
194
+ """Fills a column with a scalar value.
195
+
196
+ :param df: the dataframe.
197
+ :param column_name: the column to fill.
198
+ :param scalar_value: the scalar value to fill with.
199
+ :return: the modified dataframe.
200
+ """
201
+ raise NotImplementedError()
202
+
203
+
204
+ def get_column_type_from_df_type(dataframe_type: type) -> type:
205
+ """Function to cycle through the registered extensions and return the column type for the dataframe type.
206
+
207
+ :param dataframe_type: the dataframe type to find the column type for.
208
+ :return: the column type.
209
+ :raises: NotImplementedError if we don't know what the column type is.
210
+ """
211
+ for _extension, type_map in DF_TYPE_AND_COLUMN_TYPES.items():
212
+ if dataframe_type == type_map[DATAFRAME_TYPE]:
213
+ return type_map[COLUMN_TYPE]
214
+ raise NotImplementedError(
215
+ f"Cannot get column type for [{dataframe_type}]. "
216
+ f"Registered types are {DF_TYPE_AND_COLUMN_TYPES}"
217
+ )
218
+
219
+
220
+ LOADER_REGISTRY = collections.defaultdict(list)
221
+ SAVER_REGISTRY = collections.defaultdict(list)
222
+
223
+
224
+ def register_adapter(adapter: Any):
225
+ """Registers a adapter. Note that the type is any,
226
+ because we can't import it here due to circular imports.
227
+
228
+ :param adapter: the adapter to register.
229
+ """
230
+ if adapter.can_load():
231
+ LOADER_REGISTRY[adapter.name()].append(adapter)
232
+ if adapter.can_save():
233
+ SAVER_REGISTRY[adapter.name()].append(adapter)
234
+
235
+
236
+ def get_registered_dataframe_types() -> dict[str, type]:
237
+ """Returns a dictionary of extension name -> dataframe type.
238
+
239
+ :return: the dictionary.
240
+ """
241
+ return {
242
+ extension: type_map[DATAFRAME_TYPE]
243
+ for extension, type_map in DF_TYPE_AND_COLUMN_TYPES.items()
244
+ }
245
+
246
+
247
+ def get_registered_column_types() -> dict[str, type]:
248
+ """Returns a dictionary of extension name -> column type.
249
+
250
+ :return: the dictionary.
251
+ """
252
+ return {
253
+ extension: type_map[COLUMN_TYPE] for extension, type_map in DF_TYPE_AND_COLUMN_TYPES.items()
254
+ }
hamilton/settings.py ADDED
@@ -0,0 +1,18 @@
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
+ ENABLE_POWER_USER_MODE = "hamilton.enable_power_user_mode"
hamilton/telemetry.py ADDED
@@ -0,0 +1,50 @@
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
+ """
19
+ Telemetry has been removed from Hamilton.
20
+
21
+ This module is kept as a no-op stub for backwards compatibility,
22
+ so that any user code calling ``telemetry.disable_telemetry()``
23
+ will not break.
24
+ """
25
+
26
+ from hamilton.dev_utils.deprecation import deprecated
27
+
28
+
29
+ @deprecated(
30
+ warn_starting=(1, 89, 0),
31
+ fail_starting=(2, 0, 0),
32
+ use_this=None,
33
+ explanation="Telemetry has been removed from Hamilton. This function is a no-op.",
34
+ migration_guide="Simply remove any calls to `telemetry.disable_telemetry()`.",
35
+ )
36
+ def disable_telemetry():
37
+ """No-op. Telemetry has been removed."""
38
+ pass
39
+
40
+
41
+ @deprecated(
42
+ warn_starting=(1, 89, 0),
43
+ fail_starting=(2, 0, 0),
44
+ use_this=None,
45
+ explanation="Telemetry has been removed from Hamilton. This function always returns False.",
46
+ migration_guide="Simply remove any calls to `telemetry.is_telemetry_enabled()`.",
47
+ )
48
+ def is_telemetry_enabled() -> bool:
49
+ """Always returns False. Telemetry has been removed."""
50
+ return False
hamilton/version.py ADDED
@@ -0,0 +1,18 @@
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
+ VERSION = (1, 90, 0, "dev0")