metaxy 0.0.1.dev3__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 (111) hide show
  1. metaxy/__init__.py +170 -0
  2. metaxy/_packaging.py +96 -0
  3. metaxy/_testing/__init__.py +55 -0
  4. metaxy/_testing/config.py +43 -0
  5. metaxy/_testing/metaxy_project.py +780 -0
  6. metaxy/_testing/models.py +111 -0
  7. metaxy/_testing/parametric/__init__.py +13 -0
  8. metaxy/_testing/parametric/metadata.py +664 -0
  9. metaxy/_testing/pytest_helpers.py +74 -0
  10. metaxy/_testing/runbook.py +533 -0
  11. metaxy/_utils.py +35 -0
  12. metaxy/_version.py +1 -0
  13. metaxy/cli/app.py +97 -0
  14. metaxy/cli/console.py +13 -0
  15. metaxy/cli/context.py +167 -0
  16. metaxy/cli/graph.py +610 -0
  17. metaxy/cli/graph_diff.py +290 -0
  18. metaxy/cli/list.py +46 -0
  19. metaxy/cli/metadata.py +317 -0
  20. metaxy/cli/migrations.py +999 -0
  21. metaxy/cli/utils.py +268 -0
  22. metaxy/config.py +680 -0
  23. metaxy/entrypoints.py +296 -0
  24. metaxy/ext/__init__.py +1 -0
  25. metaxy/ext/dagster/__init__.py +54 -0
  26. metaxy/ext/dagster/constants.py +10 -0
  27. metaxy/ext/dagster/dagster_type.py +156 -0
  28. metaxy/ext/dagster/io_manager.py +200 -0
  29. metaxy/ext/dagster/metaxify.py +512 -0
  30. metaxy/ext/dagster/observable.py +115 -0
  31. metaxy/ext/dagster/resources.py +27 -0
  32. metaxy/ext/dagster/selection.py +73 -0
  33. metaxy/ext/dagster/table_metadata.py +417 -0
  34. metaxy/ext/dagster/utils.py +462 -0
  35. metaxy/ext/sqlalchemy/__init__.py +23 -0
  36. metaxy/ext/sqlalchemy/config.py +29 -0
  37. metaxy/ext/sqlalchemy/plugin.py +353 -0
  38. metaxy/ext/sqlmodel/__init__.py +13 -0
  39. metaxy/ext/sqlmodel/config.py +29 -0
  40. metaxy/ext/sqlmodel/plugin.py +499 -0
  41. metaxy/graph/__init__.py +29 -0
  42. metaxy/graph/describe.py +325 -0
  43. metaxy/graph/diff/__init__.py +21 -0
  44. metaxy/graph/diff/diff_models.py +446 -0
  45. metaxy/graph/diff/differ.py +769 -0
  46. metaxy/graph/diff/models.py +443 -0
  47. metaxy/graph/diff/rendering/__init__.py +18 -0
  48. metaxy/graph/diff/rendering/base.py +323 -0
  49. metaxy/graph/diff/rendering/cards.py +188 -0
  50. metaxy/graph/diff/rendering/formatter.py +805 -0
  51. metaxy/graph/diff/rendering/graphviz.py +246 -0
  52. metaxy/graph/diff/rendering/mermaid.py +326 -0
  53. metaxy/graph/diff/rendering/rich.py +169 -0
  54. metaxy/graph/diff/rendering/theme.py +48 -0
  55. metaxy/graph/diff/traversal.py +247 -0
  56. metaxy/graph/status.py +329 -0
  57. metaxy/graph/utils.py +58 -0
  58. metaxy/metadata_store/__init__.py +32 -0
  59. metaxy/metadata_store/_ducklake_support.py +419 -0
  60. metaxy/metadata_store/base.py +1792 -0
  61. metaxy/metadata_store/bigquery.py +354 -0
  62. metaxy/metadata_store/clickhouse.py +184 -0
  63. metaxy/metadata_store/delta.py +371 -0
  64. metaxy/metadata_store/duckdb.py +446 -0
  65. metaxy/metadata_store/exceptions.py +61 -0
  66. metaxy/metadata_store/ibis.py +542 -0
  67. metaxy/metadata_store/lancedb.py +391 -0
  68. metaxy/metadata_store/memory.py +292 -0
  69. metaxy/metadata_store/system/__init__.py +57 -0
  70. metaxy/metadata_store/system/events.py +264 -0
  71. metaxy/metadata_store/system/keys.py +9 -0
  72. metaxy/metadata_store/system/models.py +129 -0
  73. metaxy/metadata_store/system/storage.py +957 -0
  74. metaxy/metadata_store/types.py +10 -0
  75. metaxy/metadata_store/utils.py +104 -0
  76. metaxy/metadata_store/warnings.py +36 -0
  77. metaxy/migrations/__init__.py +32 -0
  78. metaxy/migrations/detector.py +291 -0
  79. metaxy/migrations/executor.py +516 -0
  80. metaxy/migrations/generator.py +319 -0
  81. metaxy/migrations/loader.py +231 -0
  82. metaxy/migrations/models.py +528 -0
  83. metaxy/migrations/ops.py +447 -0
  84. metaxy/models/__init__.py +0 -0
  85. metaxy/models/bases.py +12 -0
  86. metaxy/models/constants.py +139 -0
  87. metaxy/models/feature.py +1335 -0
  88. metaxy/models/feature_spec.py +338 -0
  89. metaxy/models/field.py +263 -0
  90. metaxy/models/fields_mapping.py +307 -0
  91. metaxy/models/filter_expression.py +297 -0
  92. metaxy/models/lineage.py +285 -0
  93. metaxy/models/plan.py +232 -0
  94. metaxy/models/types.py +475 -0
  95. metaxy/py.typed +0 -0
  96. metaxy/utils/__init__.py +1 -0
  97. metaxy/utils/constants.py +2 -0
  98. metaxy/utils/exceptions.py +23 -0
  99. metaxy/utils/hashing.py +230 -0
  100. metaxy/versioning/__init__.py +31 -0
  101. metaxy/versioning/engine.py +656 -0
  102. metaxy/versioning/feature_dep_transformer.py +151 -0
  103. metaxy/versioning/ibis.py +249 -0
  104. metaxy/versioning/lineage_handler.py +205 -0
  105. metaxy/versioning/polars.py +189 -0
  106. metaxy/versioning/renamed_df.py +35 -0
  107. metaxy/versioning/types.py +63 -0
  108. metaxy-0.0.1.dev3.dist-info/METADATA +96 -0
  109. metaxy-0.0.1.dev3.dist-info/RECORD +111 -0
  110. metaxy-0.0.1.dev3.dist-info/WHEEL +4 -0
  111. metaxy-0.0.1.dev3.dist-info/entry_points.txt +4 -0
@@ -0,0 +1,189 @@
1
+ """Polars implementation of VersioningEngine."""
2
+
3
+ from collections.abc import Callable
4
+ from typing import cast
5
+
6
+ import narwhals as nw
7
+ import polars as pl
8
+ import polars_hash # noqa: F401 # Registers .nchash and .chash namespaces
9
+ from narwhals.typing import FrameT
10
+
11
+ from metaxy.versioning.engine import VersioningEngine
12
+ from metaxy.versioning.types import HashAlgorithm
13
+
14
+ # narwhals DataFrame backed by either a lazy or an eager frame
15
+ # PolarsFrame = TypeVar("PolarsFrame", pl.DataFrame, pl.LazyFrame)
16
+
17
+
18
+ class PolarsVersioningEngine(VersioningEngine):
19
+ """Provenance engine using Polars and polars_hash plugin.
20
+
21
+ Only implements hash_string_column and build_struct_column.
22
+ All logic lives in the base class.
23
+ """
24
+
25
+ # Map HashAlgorithm enum to polars-hash functions
26
+ _HASH_FUNCTION_MAP: dict[HashAlgorithm, Callable[[pl.Expr], pl.Expr]] = {
27
+ HashAlgorithm.XXHASH64: lambda expr: expr.nchash.xxhash64(), # pyright: ignore[reportAttributeAccessIssue]
28
+ HashAlgorithm.XXHASH32: lambda expr: expr.nchash.xxhash32(), # pyright: ignore[reportAttributeAccessIssue]
29
+ HashAlgorithm.WYHASH: lambda expr: expr.nchash.wyhash(), # pyright: ignore[reportAttributeAccessIssue]
30
+ HashAlgorithm.SHA256: lambda expr: expr.chash.sha2_256(), # pyright: ignore[reportAttributeAccessIssue]
31
+ HashAlgorithm.MD5: lambda expr: expr.nchash.md5(), # pyright: ignore[reportAttributeAccessIssue]
32
+ }
33
+
34
+ @classmethod
35
+ def implementation(cls) -> nw.Implementation:
36
+ return nw.Implementation.POLARS
37
+
38
+ def hash_string_column(
39
+ self,
40
+ df: FrameT,
41
+ source_column: str,
42
+ target_column: str,
43
+ hash_algo: HashAlgorithm,
44
+ ) -> FrameT:
45
+ """Hash a string column using polars_hash.
46
+
47
+ Args:
48
+ df: Narwhals DataFrame backed by Polars
49
+ source_column: Name of string column to hash
50
+ target_column: Name for the new column containing the hash
51
+ hash_algo: Hash algorithm to use
52
+
53
+ Returns:
54
+ Narwhals DataFrame with new hashed column added, backed by Polars.
55
+ The source column remains unchanged.
56
+ """
57
+ if hash_algo not in self._HASH_FUNCTION_MAP:
58
+ raise ValueError(
59
+ f"Hash algorithm {hash_algo} not supported. "
60
+ f"Supported: {list(self._HASH_FUNCTION_MAP.keys())}"
61
+ )
62
+
63
+ assert df.implementation == nw.Implementation.POLARS, (
64
+ "Only Polars DataFrames are accepted"
65
+ )
66
+ df_pl = cast(pl.DataFrame | pl.LazyFrame, df.to_native())
67
+
68
+ # Apply hash
69
+ hash_fn = self._HASH_FUNCTION_MAP[hash_algo]
70
+ hashed = hash_fn(polars_hash.col(source_column)).cast(pl.Utf8)
71
+
72
+ # Add new column with the hash
73
+ df_pl = df_pl.with_columns(hashed.alias(target_column))
74
+
75
+ # Convert back to Narwhals
76
+ return cast(FrameT, nw.from_native(df_pl))
77
+
78
+ @staticmethod
79
+ def build_struct_column(
80
+ df: FrameT,
81
+ struct_name: str,
82
+ field_columns: dict[str, str],
83
+ ) -> FrameT:
84
+ """Build a struct column from existing columns.
85
+
86
+ Args:
87
+ df: Narwhals DataFrame backed by Polars
88
+ struct_name: Name for the new struct column
89
+ field_columns: Mapping from struct field names to column names
90
+
91
+ Returns:
92
+ Narwhals DataFrame with new struct column added, backed by Polars.
93
+ The source columns remain unchanged.
94
+ """
95
+ assert df.implementation == nw.Implementation.POLARS, (
96
+ "Only Polars DataFrames are accepted"
97
+ )
98
+ df_pl = cast(pl.DataFrame | pl.LazyFrame, df.to_native())
99
+
100
+ # Build struct expression
101
+ struct_expr = pl.struct(
102
+ [
103
+ pl.col(col_name).alias(field_name)
104
+ for field_name, col_name in field_columns.items()
105
+ ]
106
+ )
107
+
108
+ # Add struct column
109
+ df_pl = df_pl.with_columns(struct_expr.alias(struct_name))
110
+
111
+ # Convert back to Narwhals
112
+ return cast(FrameT, nw.from_native(df_pl))
113
+
114
+ @staticmethod
115
+ def aggregate_with_string_concat(
116
+ df: FrameT,
117
+ group_by_columns: list[str],
118
+ concat_column: str,
119
+ concat_separator: str,
120
+ exclude_columns: list[str],
121
+ ) -> FrameT:
122
+ """Aggregate DataFrame by grouping and concatenating strings.
123
+
124
+ Args:
125
+ df: Narwhals DataFrame backed by Polars
126
+ group_by_columns: Columns to group by
127
+ concat_column: Column containing strings to concatenate within groups
128
+ concat_separator: Separator to use when concatenating strings
129
+ exclude_columns: Columns to exclude from aggregation
130
+
131
+ Returns:
132
+ Narwhals DataFrame with one row per group.
133
+ """
134
+ assert df.implementation == nw.Implementation.POLARS, (
135
+ "Only Polars DataFrames are accepted"
136
+ )
137
+ df_pl = cast(pl.DataFrame | pl.LazyFrame, df.to_native())
138
+
139
+ # Group and aggregate: concatenate concat_column, take first for others
140
+ grouped = df_pl.group_by(group_by_columns).agg(
141
+ [
142
+ pl.col(concat_column).str.join(concat_separator),
143
+ pl.exclude(
144
+ group_by_columns + [concat_column] + exclude_columns
145
+ ).first(),
146
+ ]
147
+ )
148
+
149
+ # Convert back to Narwhals
150
+ return cast(FrameT, nw.from_native(grouped))
151
+
152
+ @staticmethod
153
+ def keep_latest_by_group(
154
+ df: FrameT,
155
+ group_columns: list[str],
156
+ timestamp_column: str,
157
+ ) -> FrameT:
158
+ """Keep only the latest row per group based on a timestamp column.
159
+
160
+ Args:
161
+ df: Narwhals DataFrame/LazyFrame backed by Polars
162
+ group_columns: Columns to group by (typically ID columns)
163
+ timestamp_column: Column to use for determining "latest" (typically metaxy_created_at)
164
+
165
+ Returns:
166
+ Narwhals DataFrame/LazyFrame with only the latest row per group
167
+
168
+ Raises:
169
+ ValueError: If timestamp_column doesn't exist in df
170
+ """
171
+ assert df.implementation == nw.Implementation.POLARS, (
172
+ "Only Polars DataFrames are accepted"
173
+ )
174
+
175
+ # Check if timestamp_column exists
176
+ if timestamp_column not in df.columns:
177
+ raise ValueError(
178
+ f"Timestamp column '{timestamp_column}' not found in DataFrame. "
179
+ f"Available columns: {df.columns}"
180
+ )
181
+
182
+ df_pl = cast(pl.DataFrame | pl.LazyFrame, df.to_native())
183
+
184
+ result = df_pl.group_by(group_columns).agg(
185
+ pl.col("*").sort_by(timestamp_column).last()
186
+ )
187
+
188
+ # Convert back to Narwhals
189
+ return cast(FrameT, nw.from_native(result))
@@ -0,0 +1,35 @@
1
+ from collections.abc import Mapping, Sequence
2
+ from dataclasses import dataclass
3
+ from typing import Generic
4
+
5
+ import narwhals as nw
6
+ from narwhals.typing import FrameT
7
+ from typing_extensions import Self
8
+
9
+
10
+ @dataclass
11
+ class RenamedDataFrame(Generic[FrameT]):
12
+ """A class representing a dataframe with renamed columns.
13
+
14
+ We keep ID columns together with this DataFrame to join on them later on."""
15
+
16
+ df: FrameT
17
+ id_columns: list[str]
18
+
19
+ def rename(self, mapping: Mapping[str, str]) -> Self:
20
+ if mapping:
21
+ # Convert Mapping to dict for narwhals rename
22
+ self.df = self.df.rename(dict(mapping))
23
+ self.id_columns = [mapping.get(col, col) for col in self.id_columns]
24
+ return self
25
+
26
+ def filter(self, filters: Sequence[nw.Expr] | None) -> Self:
27
+ if filters:
28
+ self.df = self.df.filter(*filters)
29
+ return self
30
+
31
+ def select(self, columns: Sequence[str] | None) -> Self:
32
+ if columns:
33
+ self.df = self.df.select(*columns)
34
+ self.id_columns = [col for col in self.id_columns if col in columns]
35
+ return self
@@ -0,0 +1,63 @@
1
+ """Hash algorithms supported for field provenance calculation."""
2
+
3
+ from enum import Enum
4
+ from typing import Any, NamedTuple
5
+
6
+ import narwhals as nw
7
+
8
+
9
+ class HashAlgorithm(Enum):
10
+ """Supported hash algorithms for field provenance calculation.
11
+
12
+ These algorithms are chosen for:
13
+ - Speed (non-cryptographic hashes preferred)
14
+ - Cross-database availability
15
+ - Good collision resistance for field provenance calculation
16
+ """
17
+
18
+ XXHASH64 = "xxhash64" # Fast, available in DuckDB, ClickHouse, Polars
19
+ XXHASH32 = "xxhash32" # Faster for small data, less collision resistant
20
+ WYHASH = "wyhash" # Very fast, Polars-specific
21
+ SHA256 = "sha256" # Cryptographic, slower, universally available
22
+ MD5 = "md5" # Legacy, widely available, not recommended for new code
23
+ FARMHASH = "farmhash" # Better than MD5, available in BigQuery
24
+
25
+
26
+ class Increment(NamedTuple):
27
+ """Result of an incremental update containing eager dataframes.
28
+
29
+ Contains three sets of samples:
30
+ - added: New samples from upstream not present in current metadata
31
+ - changed: Samples with different provenance
32
+ - removed: Samples in current metadata but not in upstream state
33
+ """
34
+
35
+ added: nw.DataFrame[Any]
36
+ changed: nw.DataFrame[Any]
37
+ removed: nw.DataFrame[Any]
38
+
39
+ def collect(self) -> "Increment":
40
+ """No-op for eager Increment (already collected)."""
41
+ return self
42
+
43
+
44
+ class LazyIncrement(NamedTuple):
45
+ """Result of an incremental update containing lazy dataframes.
46
+
47
+ Contains three sets of samples:
48
+ - added: New samples from upstream not present in current metadata
49
+ - changed: Samples with different provenance
50
+ - removed: Samples in current metadata but not in upstream state
51
+ """
52
+
53
+ added: nw.LazyFrame[Any]
54
+ changed: nw.LazyFrame[Any]
55
+ removed: nw.LazyFrame[Any]
56
+
57
+ def collect(self) -> Increment:
58
+ """Collect all lazy frames to eager DataFrames."""
59
+ return Increment(
60
+ added=self.added.collect(),
61
+ changed=self.changed.collect(),
62
+ removed=self.removed.collect(),
63
+ )
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.3
2
+ Name: metaxy
3
+ Version: 0.0.1.dev3
4
+ Summary: Pluggable versioned metadata management for incremental multi-modal pipelines.
5
+ Author: Daniel Gafni
6
+ Author-email: Daniel Gafni <danielgafni16@gmail.com>
7
+ Classifier: Development Status :: 2 - Pre-Alpha
8
+ Classifier: License :: OSI Approved :: Apache Software License
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Typing :: Typed
15
+ Requires-Dist: cyclopts
16
+ Requires-Dist: narwhals>=2.9.0
17
+ Requires-Dist: platformdirs>=4.5.0
18
+ Requires-Dist: polars>=1.33.1
19
+ Requires-Dist: polars-hash>=0.5.1
20
+ Requires-Dist: pydantic>=2.11.9
21
+ Requires-Dist: pydantic-settings>=2.11.0
22
+ Requires-Dist: pyyaml>=6.0.0
23
+ Requires-Dist: sqlglot>=27.29.0
24
+ Requires-Dist: tomli>=2.3.0
25
+ Requires-Dist: rich>=13.0.0
26
+ Requires-Dist: ibis-framework[bigquery]>=11.0.0 ; extra == 'bigquery'
27
+ Requires-Dist: ibis-framework[clickhouse]>=11.0.0 ; extra == 'clickhouse'
28
+ Requires-Dist: dagster>=1.12.3 ; extra == 'dagster'
29
+ Requires-Dist: deltalake>=1.2.1 ; extra == 'delta'
30
+ Requires-Dist: ibis-framework[duckdb]>=11.0.0 ; extra == 'duckdb'
31
+ Requires-Dist: duckdb>=1.4.1 ; extra == 'duckdb'
32
+ Requires-Dist: pygraphviz>=1.14 ; extra == 'graphviz'
33
+ Requires-Dist: pyarrow>=18.0.0 ; extra == 'ibis'
34
+ Requires-Dist: ibis-framework>=11.0.0 ; extra == 'ibis'
35
+ Requires-Dist: lancedb>=0.15.0 ; extra == 'lancedb'
36
+ Requires-Dist: mermaid-py>=0.8.0 ; extra == 'mermaid'
37
+ Requires-Dist: sqlmodel>=0.0.27 ; extra == 'sqlmodel'
38
+ Requires-Python: >=3.10
39
+ Project-URL: Documentation, https://metaxy.dev
40
+ Project-URL: Issues, https://github.com/anam-org/metaxy/issues
41
+ Project-URL: Repository, https://github.com/anam-org/metaxy
42
+ Provides-Extra: bigquery
43
+ Provides-Extra: clickhouse
44
+ Provides-Extra: dagster
45
+ Provides-Extra: delta
46
+ Provides-Extra: duckdb
47
+ Provides-Extra: graphviz
48
+ Provides-Extra: ibis
49
+ Provides-Extra: lancedb
50
+ Provides-Extra: mermaid
51
+ Provides-Extra: sqlmodel
52
+ Description-Content-Type: text/markdown
53
+
54
+ <p align="center">
55
+ <img src="https://raw.githubusercontent.com/anam-org/metaxy/main/docs/assets/metaxy.svg" alt="Metaxy Logo" width="100"/>
56
+ </p>
57
+
58
+ <h1 align="center">Metaxy</h1>
59
+
60
+ <p align="center">
61
+ <a href="https://pypi.org/project/metaxy/"><img src="https://img.shields.io/pypi/v/metaxy.svg?color=4644ad" alt="PyPI version"></a>
62
+ <a href="https://pypi.org/project/metaxy/"><img src="https://img.shields.io/pypi/pyversions/metaxy.svg?color=4644ad" alt="Python versions"></a>
63
+ <a href="https://pypi.org/project/metaxy/"><img src="https://img.shields.io/pypi/dm/metaxy.svg?color=4644ad" alt="PyPI downloads"></a>
64
+ <a href="https://github.com/anam-org/metaxy/actions/workflows/QA.yml"><img src="https://github.com/anam-org/metaxy/actions/workflows/QA.yml/badge.svg" alt="CI"></a>
65
+ <a href="https://docs.astral.sh/ruff/"><img src="https://img.shields.io/badge/linting-ruff-4644ad" alt="Ruff"></a>
66
+ <a href="https://docs.basedpyright.com"><img src="https://img.shields.io/badge/basedpyright-checked-4644ad" alt="basedpyright - checked"></a>
67
+ <a href="https://prek.j178.dev"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/assets/badge/v0.json" alt="prek"></a>
68
+ </p>
69
+
70
+ Metaxy is a metadata layer for **multi-modal Data and ML pipelines**. Metaxy tracks feature versions, (partial) data dependencies, and lineage across complex computation graphs.
71
+
72
+ Metaxy's goal is to provide a standard instrument for any kind of multi-modal (or just tabular) **incremental** pipelines, standardizing dependency specification, versioning, partial data dependencies, manipulations over metadata, migrations, and more.
73
+
74
+ Read the [docs](https://anam-org.github.io/metaxy) to learn more.
75
+
76
+ ## Installation
77
+
78
+ **Warning**: Metaxy hasn't been publicly released yet, but you can try the latest dev release:
79
+
80
+ ```shell
81
+ pip install --pre metaxy
82
+ ```
83
+
84
+ ## Integrating Metaxy in your project
85
+
86
+ Metaxy is highly pluggable and generally can be used with any kind of incremental pipelines, storage, metadata stores, and dataframe libraries.
87
+
88
+ Metaxy provides integrations with popular tools such as [Dagster](https://anam-org.github.io/metaxy/main/integrations/orchestration/dagster), [ClickHouse](https://anam-org.github.io/metaxy/main/integrations/metadata-stores/databases/clickhouse), [DeltaLake](https://anam-org.github.io/metaxy/main/integrations/metadata-stores/storage/delta/), [SQLModel](https://anam-org.github.io/metaxy/main/integrations/plugins/sqlmodel/).
89
+
90
+ The full list can be found [here](https://anam-org.github.io/metaxy/main/integrations).
91
+
92
+ ## Contributing
93
+
94
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
95
+
96
+ <img referrerpolicy="no-referrer" src="https://static.scarf.sh/a.png?x-pxid=22cb75dc-201e-4a72-9fb2-c3a53ce9207e&page=README.md" />
@@ -0,0 +1,111 @@
1
+ metaxy/__init__.py,sha256=iqk7EB_rbosaNkJKDglZpHcrSISBc7DgrRMjr4Jr0W0,4373
2
+ metaxy/_packaging.py,sha256=E4r8UpfaBirWJcBy23FFNjTvwR76TUXHTY5M-XT-l58,3456
3
+ metaxy/_testing/__init__.py,sha256=YdvmjhYrdrUFEf5XhXAlPe6F3xHxEBojroIpgPBkjM4,1446
4
+ metaxy/_testing/config.py,sha256=PWLHCNxZoeVjAs57U2_XqaXalQSdetZO0I2fpeheyoY,1147
5
+ metaxy/_testing/metaxy_project.py,sha256=A1tENVruFFYtHWJb1nUfc18i_vPzt2JTZgegMSns1Uk,27070
6
+ metaxy/_testing/models.py,sha256=f6VFHWe5rYIxFwLOfwLoJiRawLuYIU3g5FU1b3X7_2Q,3501
7
+ metaxy/_testing/parametric/__init__.py,sha256=0nsF2OnNBazpRKVdjYVxaydpg3r-Ikwv5zaERnQv7IQ,347
8
+ metaxy/_testing/parametric/metadata.py,sha256=ll7VKAOaZ8cDPSf1mnAJNLUCol5_qJfT57UipTGubUw,25305
9
+ metaxy/_testing/pytest_helpers.py,sha256=0sTLLt27SSSNNr8SpbOUbmQdgUuZ-3fc3Qf0pchVFts,2304
10
+ metaxy/_testing/runbook.py,sha256=iYlx_SMOJwBoYwcdWn-covS0JwsIBfn7WhNo7TspMk4,17020
11
+ metaxy/_utils.py,sha256=PuuCmbn0Ig9VQ8g3Xn4WM1YGs5gSlehdMcxLNqg-To4,963
12
+ metaxy/_version.py,sha256=Nen3Jr4Cj-VxPTIW8M9gKf9vB4abvgirtm4TCaKcqck,27
13
+ metaxy/cli/app.py,sha256=mO2j3Yj7tpLE83pV9tRAbEhBrZCtXPzA_wYY5BJ1W0o,3081
14
+ metaxy/cli/console.py,sha256=3aOSOcK1YLrox1U8azNDIN0W7rRETeFd84UYXczIOX0,464
15
+ metaxy/cli/context.py,sha256=KphESWzHEoDGr26xnLee-VPk9Ruu3YK_jw4173GpLkg,5174
16
+ metaxy/cli/graph.py,sha256=hSpcV6fXzULqdHN0am52NHtTgeAlLIfrF08OfIDC8fo,22437
17
+ metaxy/cli/graph_diff.py,sha256=kloqqBcfdRdkeY1DoxLU-WxxLgZ0cw4EDTMZR3PgfCA,10067
18
+ metaxy/cli/list.py,sha256=4Sf-B9XRaeyuZa7zeUGHMRPpVocDyGr1xZc6eLG3Rcw,1625
19
+ metaxy/cli/metadata.py,sha256=2LH3474dcz8r1Ns8rpD3H9X9R6Fk3e4AnWrgxyPDdeI,10276
20
+ metaxy/cli/migrations.py,sha256=JL-T7l_DsCLX101_vtEyNMOZQfpqHw7Fzamp0GHYtU0,38519
21
+ metaxy/cli/utils.py,sha256=GNcZOgd0DxBXC5wFC-YQwBrgnSRytRPCXpqhNFiG9I0,8762
22
+ metaxy/config.py,sha256=akx_47aV56NMFBdzlc4t8LBikMQYfaECDE1HPIIZbj8,23651
23
+ metaxy/entrypoints.py,sha256=mJQeaBCN4OhEYxgICZc_4DgdQCPTH95y1x1SQ40Wmp0,9174
24
+ metaxy/ext/__init__.py,sha256=Y0-7EQCcv9XhoJCjAJtSYd74r49qbsken2VPQBxXs5c,46
25
+ metaxy/ext/dagster/__init__.py,sha256=APkjOqQIsvAULhi1R9qZVeh3SFjdGasShlO87AWYnH0,1737
26
+ metaxy/ext/dagster/constants.py,sha256=U0UhaPGjJu7p-iRuhB2oi1sSgtMf0HXAhiwfwAJYpLk,408
27
+ metaxy/ext/dagster/dagster_type.py,sha256=mhJoNmDrWN7ITshWtAm2ZaUf38WGZzLAJlQbK3kb4F4,5633
28
+ metaxy/ext/dagster/io_manager.py,sha256=_6m-k25SmA7WuloUDEL0JhAappIjSPlWyPYD_AyWo7o,7754
29
+ metaxy/ext/dagster/metaxify.py,sha256=-q4T3mFoxt5s3I8_TKCD1BYa8UNbOOkup_qiw0T3g08,20700
30
+ metaxy/ext/dagster/observable.py,sha256=AOAnP6MXijYIekZUqak4JXecHsfj5Pfw1m0HBQ7aA4Q,4588
31
+ metaxy/ext/dagster/resources.py,sha256=zvsZSiNypAb4NBE4TnNZYwOXLLMswVMivs4DTmYwYwE,973
32
+ metaxy/ext/dagster/selection.py,sha256=LNWQGrGhddeaLI_Ae1N9nL5DKqttNlJAk5JNHsKq_aE,2319
33
+ metaxy/ext/dagster/table_metadata.py,sha256=2eIIw5r2iIeAHPuUzVkz_dncb64zHurH02APj6JjjYg,16349
34
+ metaxy/ext/dagster/utils.py,sha256=U6rvltA9qKvQkd4U2eok4sRBoYamUf7NJITmFL5Ippw,16945
35
+ metaxy/ext/sqlalchemy/__init__.py,sha256=PhFD-eq-eqlZr6zsgOukG0vJIWFz6U1qRWlP4htNN60,710
36
+ metaxy/ext/sqlalchemy/config.py,sha256=wrx8zGCEECT5knwnqKxFMbXoar2jwvIGK1HYMZWaNk0,1001
37
+ metaxy/ext/sqlalchemy/plugin.py,sha256=7DmqOl-xX8jdvoX7DGwoRa4NOK8RG-q9JH4wKXNiqVA,11597
38
+ metaxy/ext/sqlmodel/__init__.py,sha256=HHkIfSHctr0DGYVkqPHtWniPtV-vdy2eB7r-V6jQUtA,328
39
+ metaxy/ext/sqlmodel/config.py,sha256=stPet5NeP_PropJ5GA00fdZLHPbBzV_c-ldM9FgqiXc,1003
40
+ metaxy/ext/sqlmodel/plugin.py,sha256=9ibu29ZiPGJmB8mTyLjTFgHKPYMZe_A6Rl3PTPpADbQ,18717
41
+ metaxy/graph/__init__.py,sha256=oK7P_GSkTp-FlbulbvTTYc-MD9p2rxFCewIDVMcifJc,620
42
+ metaxy/graph/describe.py,sha256=C02MAVz0WO0PBeMDQ_CFQUNFc9bVnFpMZVRyEp74hnU,10598
43
+ metaxy/graph/diff/__init__.py,sha256=sP467NBNZnL3IRUA-uqKjXkJiOJPHrxvr5sMosS7PTQ,399
44
+ metaxy/graph/diff/diff_models.py,sha256=fFEixXa0KHWeStaJ2699IOMbSbeBJagz_aSsge4vQ9o,16928
45
+ metaxy/graph/diff/differ.py,sha256=J9Ur2tryqMHW0AdlsQFd2YB4Yc3a6RggqBqEJgrBnrc,29894
46
+ metaxy/graph/diff/models.py,sha256=w-HkJqWgYsXNP1B6amGzdOp5eAztftXVIq0Wr5JW8gM,16027
47
+ metaxy/graph/diff/rendering/__init__.py,sha256=gRJXWnzF3KEs4vwgOk9XXxvsOXIkaVgicYLtSOKfC5A,606
48
+ metaxy/graph/diff/rendering/base.py,sha256=IlFxl17lm45zTzFB26_CK7KNlfzaJ23ti7XCtCkgGeI,10267
49
+ metaxy/graph/diff/rendering/cards.py,sha256=nGBJ6s5vSMyKgFbuz2CKdLZu-FidLXB8U8NLEe32oqw,6507
50
+ metaxy/graph/diff/rendering/formatter.py,sha256=swDrBg0vRuBKxmoiyfhpytEEietolwOqc78EUoH7DFY,32337
51
+ metaxy/graph/diff/rendering/graphviz.py,sha256=OEhar2AFdAM6DcYe-aamMRyCJ8sRbLE6VNA4vNc44rw,7946
52
+ metaxy/graph/diff/rendering/mermaid.py,sha256=V-ggXGzhfTADwPIsaOodXp0dTNEPpJ-poFQGxLdjL_4,11195
53
+ metaxy/graph/diff/rendering/rich.py,sha256=Hub0G6eMB_Qa4HUaken8TfEC8FMEKjaWWOHsnXiElnA,6133
54
+ metaxy/graph/diff/rendering/theme.py,sha256=z0hXs7a9TYjjUO2eyibL6RknxQU0RFA5_962AG7a2qs,1689
55
+ metaxy/graph/diff/traversal.py,sha256=KsuKr6lDw7h7S7qVlMWF0nwjAkjWErP4kyVub9AIlaI,8146
56
+ metaxy/graph/status.py,sha256=gNWLUDMa_UlfmWWTYGqRKyjLoUM-6prXKLOhppZQu7Y,11508
57
+ metaxy/graph/utils.py,sha256=E5FHHyTCn0o1o8gfmBEu2ntHv3nlkIoMCDet_MdLJoI,1311
58
+ metaxy/metadata_store/__init__.py,sha256=p83tu5RYCvjp5EicOyUqY1owKNEYgwi7rJOucmijVx8,895
59
+ metaxy/metadata_store/_ducklake_support.py,sha256=eP-i4m6G24bE77r184nMXF1ip5ZRhKJ3VKEXJ2A90j8,15147
60
+ metaxy/metadata_store/base.py,sha256=zfWuhWP260ZgJIiJ6dtdgPbqSj3gB2Bz-E6fWEX6MYs,72430
61
+ metaxy/metadata_store/bigquery.py,sha256=5NEoquZYQ4DuGYjJGDBAqfelirZkdWuf0pHav4Pev1E,13303
62
+ metaxy/metadata_store/clickhouse.py,sha256=oYKocRZ6K3tJywv1FSJ6lt2hBiTGX96yqMXWRmXpKZE,6074
63
+ metaxy/metadata_store/delta.py,sha256=CwnbvGghYlzF5HHvLrJ7MM_l7hHrm7HUSuU8P2EB4T4,13837
64
+ metaxy/metadata_store/duckdb.py,sha256=rXC3Hcd9QFtqQt2phvt1ygaH_U-haC3rB-GuX8nE0u8,16299
65
+ metaxy/metadata_store/exceptions.py,sha256=3fask4dmaKIDr0WSV-Rx6eFioN7YLfDXrJXv2LBExAs,1340
66
+ metaxy/metadata_store/ibis.py,sha256=9ZLHmW3YJg5NnJFzHR0znz3n_SXF6Rszr3mltponuOg,19553
67
+ metaxy/metadata_store/lancedb.py,sha256=WyEUoGO-rEL3eL_ld3B-gHRCCYToo9gkIZGyrUs3o5s,13988
68
+ metaxy/metadata_store/memory.py,sha256=x79IR9Uhtl06BwIpgtZyIXHOXbPhtgrtRvlIbpBVHgA,10099
69
+ metaxy/metadata_store/system/__init__.py,sha256=b1K5jJkqMrbfN_P6aQbAYfr_Yyv1dHGqTeIrg3EzNls,1292
70
+ metaxy/metadata_store/system/events.py,sha256=oJa_mE6rNRO7P6McMSjkCUAKfdLgxYomOAAJaCh9qYs,8112
71
+ metaxy/metadata_store/system/keys.py,sha256=x8qNVQe4xqVMCHDr3bgrv3iRkI2IfFWxt0Qs1EEh7i4,292
72
+ metaxy/metadata_store/system/models.py,sha256=XZ-DRgiOTFm1N3qKUWpX5Isubi0cn8JeZvBfq617l-A,4494
73
+ metaxy/metadata_store/system/storage.py,sha256=bmwCORadefASy90kv5lG7fXEs6Etd8-AFq5-vxCQVRs,36093
74
+ metaxy/metadata_store/types.py,sha256=tEBOmYsA5oTdgkfmkRXfNQGdxwqXwDW-tG28cMKJ42Q,400
75
+ metaxy/metadata_store/utils.py,sha256=8ktzGG4LxMC0jngymakoHUAQbSKoseldJGaNCajWq-Y,3417
76
+ metaxy/metadata_store/warnings.py,sha256=wj0LKniSlSD1GHDqfUQ8nhlgD_omizgvLnSycNlrOwg,1021
77
+ metaxy/migrations/__init__.py,sha256=1_ZmPq0tweVYGRqaF1qif6zNjqfgGW0Ol5h8zOMs73w,815
78
+ metaxy/migrations/detector.py,sha256=tXIBM71wA5sU22l00vDbnagxZ9b8LvF1920EeesRJdU,10523
79
+ metaxy/migrations/executor.py,sha256=EZTuRdJqAOgLrDMO9maqWI_mUhr5bgsgDUpwqiS-rW0,19748
80
+ metaxy/migrations/generator.py,sha256=wIkW5jYQqYj-X-EjF12RRT5PpVQrHj28vPsUAQFV3Vc,12036
81
+ metaxy/migrations/loader.py,sha256=b56ZN68k-X8el6Ta2lKE_LKbCmdsWxI6Rxy6KrDZvX4,7317
82
+ metaxy/migrations/models.py,sha256=vROWErYBoTPy-c8hVlkI_2ujdTmYDBOwuI3pg2RanYc,18396
83
+ metaxy/migrations/ops.py,sha256=1DPn0DhEsxusNdHhEdLtHkS8GP8Mcbd7YiKSy0jgMJg,17275
84
+ metaxy/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
+ metaxy/models/bases.py,sha256=RbbJnOZKhvCe3qXOth2b5saeazkbcBLr0DVpdXytPuc,303
86
+ metaxy/models/constants.py,sha256=0V9sdtGPhywHE12tLzCIsXHCWIUn0PAU_v7TBLeEUNI,4852
87
+ metaxy/models/feature.py,sha256=qv4-DNuXNee0S1Qil3MgQIBSDZt4KE3BftGurfyiw1c,51965
88
+ metaxy/models/feature_spec.py,sha256=5OVTZ2cZmRuZQdch-t0hnnoiz90m3NHWtv3NAXZw6G0,12820
89
+ metaxy/models/field.py,sha256=H1E5QNZdz3_diEYTSutIzE3YNZOBL-UChywYyq0QmYA,8344
90
+ metaxy/models/fields_mapping.py,sha256=89zyyCE6LtPxbXIJJOHEVPXqt6ztJzEVl2YUnvK37oQ,10056
91
+ metaxy/models/filter_expression.py,sha256=Eid2-7W8x5ETYdj5ri6xY69dVPRXqUKFIylTqns9PbA,9599
92
+ metaxy/models/lineage.py,sha256=YddbUrr1ELkN-_9Sin1nMq-a5MEc5FcI5HUyr7l-LuY,10051
93
+ metaxy/models/plan.py,sha256=sO7k7rLWxZc_X2jJxhRZkHvIkrpFCvYZUuY8ebIb6AE,8420
94
+ metaxy/models/types.py,sha256=USlHQXdYkSMzlEifw0s98l6e3ug7WTnyuCXcL4md-P0,14839
95
+ metaxy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
96
+ metaxy/utils/__init__.py,sha256=d2KPC4jX4iGQX7uQMfQHMfrRNz9MqywiuVY8prjNVhE,34
97
+ metaxy/utils/constants.py,sha256=1LyZxlVpxuU8BF4i3RO-GXehqcE_8WACruOX79vb1rE,100
98
+ metaxy/utils/exceptions.py,sha256=3l0IlF1KvYRuw6EgDjZLurSsvJqq0AURLil4xpA6h2s,687
99
+ metaxy/utils/hashing.py,sha256=4V_CkIJbAs0RKD6z1N-p1nnqsDgdOHHNOjXiL-uOTac,6580
100
+ metaxy/versioning/__init__.py,sha256=Ae_dQhPyJwLBY_IiDzdEGhAoAzYKBzCSnPA_ZlrttzU,1088
101
+ metaxy/versioning/engine.py,sha256=kTIWRSpn4eDdX6y2i-yleXxK_sY1dx2z-VU9NlAdiAw,26911
102
+ metaxy/versioning/feature_dep_transformer.py,sha256=7dbznclFIXQNCNlBRaidvHUaIBavxanf2WR66JpQKTg,5327
103
+ metaxy/versioning/ibis.py,sha256=e6HdRJ5sgfoTziRmrCo62O_h2GRkPuQ6jCkl4RXdY-E,8614
104
+ metaxy/versioning/lineage_handler.py,sha256=0wAYT43jXBWzUJb1jhRAsRXNc3BZYcA5A7CQlAu9uAE,7397
105
+ metaxy/versioning/polars.py,sha256=WcpeG1kyawZ3m1f-kqmghoVRddt-fhQCRnwmaKsnNlA,6761
106
+ metaxy/versioning/renamed_df.py,sha256=D3ALHJ4uUIaGrK3TlsH85SvUY8URQlaozyT4_zBU-80,1109
107
+ metaxy/versioning/types.py,sha256=--Zejj26-qFNA6BMwUn29SWTSCVmNMxy1JGxczU7IwE,2087
108
+ metaxy-0.0.1.dev3.dist-info/WHEEL,sha256=pFCy50wRV2h7SjJ35YOsQUupaV45rMdgpNIvnXbG5bE,79
109
+ metaxy-0.0.1.dev3.dist-info/entry_points.txt,sha256=HbLOdNbhhIxa_TzEsN3QRWki5LuctCJR_xkC7JoYsN4,73
110
+ metaxy-0.0.1.dev3.dist-info/METADATA,sha256=5xwZ65WWLPE7__N2BP0-8HMPd7M6FJsSCRTPf5HTRZc,4869
111
+ metaxy-0.0.1.dev3.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.8.19
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ metaxy = metaxy.cli.app:main
3
+ mx = metaxy.cli.app:main
4
+