datajunction 0.0.240__tar.gz → 0.0.243__tar.gz
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.
- {datajunction-0.0.240 → datajunction-0.0.243}/PKG-INFO +1 -1
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/__about__.py +1 -1
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/models.py +44 -1
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_deploy.py +104 -11
- {datajunction-0.0.240 → datajunction-0.0.243}/.coveragerc +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/.gitignore +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/.pre-commit-config.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/LICENSE.txt +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/Makefile +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/README.md +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/claude_desktop_config.example.json +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/__init__.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/_base.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/_internal.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/admin.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/builder.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/cli.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/client.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/compile.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/deployment.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/exceptions.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/mcp/__init__.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/mcp/cli.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/mcp/config.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/nodes.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/rendering.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/init_system_nodes.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/date.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/deployment.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/dimension_link.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/distinct_node_authors.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/distinct_node_editors.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/is_active.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/materialization.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/median_deployment_duration_seconds.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/median_dim_links_per_node.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/median_dimension_indegree.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/median_downstream_count.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/median_revisions_per_node.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/median_upstream_count.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/namespace.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/node_revision.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/node_type.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/nodes.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/number_of_branches.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/number_of_deployments.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/number_of_materializations.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/number_of_namespaces.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/number_of_nodes.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/number_of_orphan_nodes.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/number_of_unused_dimensions.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/repo.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/user.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/skills/datajunction/SKILL.md +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/skills/datajunction-api/SKILL.md +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/skills/datajunction-query/SKILL.md +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/skills/datajunction-repo/SKILL.md +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/skills/datajunction-semantic-model/SKILL.md +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/datajunction/tags.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/pyproject.toml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/setup.cfg +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/__init__.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/conftest.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/deploy0/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/deploy0/roads/companies.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/deploy0/roads/companies_dim.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/deploy0/roads/contractor.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/deploy0/roads/contractors.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/deploy0/roads/us_state.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/deploy0/roads/us_states.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/avg_length_of_employment.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/avg_repair_price.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/avg_time_to_dispatch.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/date.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/date_dim.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/dispatcher.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/dispatchers.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/hard_hat.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/hard_hat_state.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/hard_hats.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/local_hard_hats.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/municipality.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/municipality_dim.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/municipality_municipality_type.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/municipality_type.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/national_level_agg.transform.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/num_repair_orders.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/regional_level_agg.transform.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/regional_repair_efficiency.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/repair_order.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/repair_order_details.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/repair_order_transform.transform.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/repair_orders.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/repair_orders_cube.cube.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/repair_type.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/total_repair_cost.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/total_repair_order_discounts.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/us_region.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/us_state.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/us_states.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project10/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/avg_length_of_employment.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/avg_repair_price.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/avg_time_to_dispatch.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/contractor.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/contractors.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/date.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/date_dim.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/dispatcher.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/dispatchers.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/hard_hat.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/hard_hat_state.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/hard_hats.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/local_hard_hats.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/municipality.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/municipality_dim.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/municipality_municipality_type.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/municipality_type.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/national_level_agg.transform.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/num_repair_orders.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/regional_level_agg.transform.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/regional_repair_efficiency.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/repair_order.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/repair_order_details.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/repair_order_transform.transform.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/repair_orders.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/repair_orders_cube.cube.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/repair_type.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/total_repair_cost.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/total_repair_order_discounts.metric.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/us_region.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/us_state.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/us_states.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project12/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project12/roads/companies.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project12/roads/companies_dim.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project12/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project12/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project12/roads/us_state.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project12/roads/us_states.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project2/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project2/some_node.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project3/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project3/some_node.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project4/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project4/very/very/deeply/nested/namespace/some_node.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project5/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project5/some_node.a.b.c.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project6/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project6/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project6/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project7/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project7/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project7/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project8/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project9/dj.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project9/roads/companies.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project9/roads/companies_dim.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project9/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project9/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project9/roads/us_state.dimension.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project9/roads/us_states.source.yaml +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/examples.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/mcp/README.md +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/mcp/__init__.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/mcp/test_cli.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test__internal.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_admin.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_base.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_builder.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_cli.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_client.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_compile.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_generated_client.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_integration.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_models.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_plugin_mirror.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tests/test_skills.py +0 -0
- {datajunction-0.0.240 → datajunction-0.0.243}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: datajunction
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.243
|
|
4
4
|
Summary: DataJunction client library for connecting to a DataJunction server
|
|
5
5
|
Project-URL: repository, https://github.com/DataJunction/dj
|
|
6
6
|
Author-email: DataJunction Authors <yian.shang@gmail.com>
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import enum
|
|
6
|
+
import re
|
|
6
7
|
from dataclasses import dataclass, field
|
|
7
|
-
from typing import TYPE_CHECKING, Any
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Literal, TypeAlias
|
|
8
9
|
|
|
9
10
|
from datajunction._base import SerializableMixin
|
|
10
11
|
|
|
@@ -361,6 +362,38 @@ class BranchInfo(SerializableMixin):
|
|
|
361
362
|
# ---------------------------------------------------------------------------
|
|
362
363
|
|
|
363
364
|
|
|
365
|
+
@dataclass
|
|
366
|
+
class SemanticFingerprint:
|
|
367
|
+
"""A semantic node digest returned by the server."""
|
|
368
|
+
|
|
369
|
+
digest: str
|
|
370
|
+
version: int = 1
|
|
371
|
+
|
|
372
|
+
def __post_init__(self) -> None:
|
|
373
|
+
if re.fullmatch(r"[0-9a-f]{64}", self.digest) is None:
|
|
374
|
+
raise ValueError(
|
|
375
|
+
"Semantic fingerprint digest must be 64 lowercase hexadecimal characters",
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
@classmethod
|
|
379
|
+
def from_dict(cls, d: dict) -> SemanticFingerprint:
|
|
380
|
+
return cls(
|
|
381
|
+
version=d.get("version", 1),
|
|
382
|
+
digest=d.get("digest", ""),
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
SemanticFingerprintValue: TypeAlias = SemanticFingerprint | Literal["unknown"]
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def _parse_semantic_fingerprint(value: Any) -> SemanticFingerprintValue | None:
|
|
390
|
+
if value is None or value == "unknown":
|
|
391
|
+
return value
|
|
392
|
+
if not isinstance(value, dict):
|
|
393
|
+
raise ValueError("Semantic fingerprint must be an object or 'unknown'")
|
|
394
|
+
return SemanticFingerprint.from_dict(value)
|
|
395
|
+
|
|
396
|
+
|
|
364
397
|
@dataclass
|
|
365
398
|
class DeploymentResult:
|
|
366
399
|
"""A single node-level result within a deployment."""
|
|
@@ -370,15 +403,22 @@ class DeploymentResult:
|
|
|
370
403
|
status: str
|
|
371
404
|
message: str = ""
|
|
372
405
|
changed_fields: list[str] = field(default_factory=list)
|
|
406
|
+
deploy_type: str = ""
|
|
407
|
+
change_tier: Literal["none", "minor", "major"] | None = None
|
|
408
|
+
semantic_fingerprint: SemanticFingerprintValue | None = None
|
|
373
409
|
|
|
374
410
|
@classmethod
|
|
375
411
|
def from_dict(cls, d: dict) -> DeploymentResult:
|
|
412
|
+
fingerprint = d.get("semantic_fingerprint")
|
|
376
413
|
return cls(
|
|
377
414
|
name=d.get("name", ""),
|
|
378
415
|
operation=d.get("operation", ""),
|
|
379
416
|
status=d.get("status", ""),
|
|
380
417
|
message=d.get("message", ""),
|
|
381
418
|
changed_fields=d.get("changed_fields") or [],
|
|
419
|
+
deploy_type=d.get("deploy_type", ""),
|
|
420
|
+
change_tier=d.get("change_tier"),
|
|
421
|
+
semantic_fingerprint=_parse_semantic_fingerprint(fingerprint),
|
|
382
422
|
)
|
|
383
423
|
|
|
384
424
|
|
|
@@ -392,9 +432,11 @@ class DownstreamImpact:
|
|
|
392
432
|
caused_by: list[str] = field(default_factory=list)
|
|
393
433
|
depth: int = 0
|
|
394
434
|
impact_type: str = ""
|
|
435
|
+
semantic_fingerprint: SemanticFingerprintValue | None = None
|
|
395
436
|
|
|
396
437
|
@classmethod
|
|
397
438
|
def from_dict(cls, d: dict) -> DownstreamImpact:
|
|
439
|
+
fingerprint = d.get("semantic_fingerprint")
|
|
398
440
|
return cls(
|
|
399
441
|
name=d.get("name", ""),
|
|
400
442
|
node_type=d.get("node_type", ""),
|
|
@@ -402,6 +444,7 @@ class DownstreamImpact:
|
|
|
402
444
|
caused_by=d.get("caused_by") or [],
|
|
403
445
|
depth=d.get("depth", 0),
|
|
404
446
|
impact_type=d.get("impact_type", ""),
|
|
447
|
+
semantic_fingerprint=_parse_semantic_fingerprint(fingerprint),
|
|
405
448
|
)
|
|
406
449
|
|
|
407
450
|
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import importlib.metadata
|
|
2
2
|
import io
|
|
3
3
|
import json
|
|
4
|
-
from pathlib import Path
|
|
5
4
|
import time
|
|
6
5
|
import zipfile
|
|
6
|
+
from pathlib import Path
|
|
7
7
|
from unittest import mock
|
|
8
|
-
import pytest
|
|
9
8
|
from unittest.mock import MagicMock, patch
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
import yaml
|
|
10
12
|
from datajunction.deployment import DeploymentService
|
|
11
13
|
from datajunction.exceptions import DJClientException, DJDeploymentFailure
|
|
12
|
-
from datajunction.models import DeploymentInfo
|
|
14
|
+
from datajunction.models import DeploymentInfo, SemanticFingerprint
|
|
13
15
|
from datajunction.rendering import (
|
|
14
16
|
_render_error_bullets,
|
|
15
17
|
_strip_summary_lines,
|
|
16
18
|
print_deployment_header,
|
|
17
19
|
print_results,
|
|
18
20
|
)
|
|
19
|
-
import yaml
|
|
20
21
|
from rich.console import Console
|
|
21
22
|
|
|
22
23
|
|
|
@@ -1401,24 +1402,41 @@ class TestGetImpact:
|
|
|
1401
1402
|
monkeypatch.delenv("DJ_DEPLOY_REPO", raising=False)
|
|
1402
1403
|
|
|
1403
1404
|
# Create mock client
|
|
1404
|
-
|
|
1405
|
-
mock_client.get_deployment_impact.return_value = {
|
|
1405
|
+
response = {
|
|
1406
1406
|
"uuid": "dry_run",
|
|
1407
1407
|
"namespace": "test.ns",
|
|
1408
1408
|
"status": "success",
|
|
1409
1409
|
"results": [
|
|
1410
1410
|
{
|
|
1411
1411
|
"name": "test.ns.my_node",
|
|
1412
|
+
"deploy_type": "node",
|
|
1412
1413
|
"operation": "noop",
|
|
1413
1414
|
"status": "success",
|
|
1414
1415
|
"message": "",
|
|
1416
|
+
"change_tier": "none",
|
|
1417
|
+
"semantic_fingerprint": {
|
|
1418
|
+
"version": 1,
|
|
1419
|
+
"digest": "a" * 64,
|
|
1420
|
+
},
|
|
1421
|
+
},
|
|
1422
|
+
],
|
|
1423
|
+
"downstream_impacts": [
|
|
1424
|
+
{
|
|
1425
|
+
"name": "external.metric",
|
|
1426
|
+
"node_type": "metric",
|
|
1427
|
+
"predicted_status": "valid",
|
|
1428
|
+
"semantic_fingerprint": {
|
|
1429
|
+
"version": 1,
|
|
1430
|
+
"digest": "b" * 64,
|
|
1431
|
+
},
|
|
1415
1432
|
},
|
|
1416
1433
|
],
|
|
1417
|
-
"downstream_impacts": [],
|
|
1418
1434
|
}
|
|
1435
|
+
mock_client = MagicMock()
|
|
1436
|
+
mock_client.get_deployment_impact.return_value = response
|
|
1419
1437
|
|
|
1420
1438
|
svc = DeploymentService(mock_client)
|
|
1421
|
-
result = svc.get_impact(tmp_path)
|
|
1439
|
+
result = svc.get_impact(tmp_path, display=False)
|
|
1422
1440
|
|
|
1423
1441
|
# Verify the API was called
|
|
1424
1442
|
mock_client.get_deployment_impact.assert_called_once()
|
|
@@ -1426,9 +1444,84 @@ class TestGetImpact:
|
|
|
1426
1444
|
assert call_args["namespace"] == "test.ns"
|
|
1427
1445
|
assert "nodes" in call_args
|
|
1428
1446
|
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
assert
|
|
1447
|
+
assert result is response
|
|
1448
|
+
parsed = DeploymentInfo.from_dict(result)
|
|
1449
|
+
assert parsed.results[0].deploy_type == "node"
|
|
1450
|
+
assert parsed.results[0].change_tier == "none"
|
|
1451
|
+
assert parsed.results[0].semantic_fingerprint == SemanticFingerprint(
|
|
1452
|
+
digest="a" * 64,
|
|
1453
|
+
)
|
|
1454
|
+
assert parsed.downstream_impacts[0].semantic_fingerprint == SemanticFingerprint(
|
|
1455
|
+
digest="b" * 64,
|
|
1456
|
+
)
|
|
1457
|
+
|
|
1458
|
+
def test_deployment_info_parses_unknown_fingerprints(self):
|
|
1459
|
+
parsed = DeploymentInfo.from_dict(
|
|
1460
|
+
{
|
|
1461
|
+
"uuid": "dry_run",
|
|
1462
|
+
"namespace": "test.ns",
|
|
1463
|
+
"status": "success",
|
|
1464
|
+
"results": [{"semantic_fingerprint": "unknown"}],
|
|
1465
|
+
"downstream_impacts": [{"semantic_fingerprint": "unknown"}],
|
|
1466
|
+
},
|
|
1467
|
+
)
|
|
1468
|
+
|
|
1469
|
+
assert parsed.results[0].semantic_fingerprint == "unknown"
|
|
1470
|
+
assert parsed.downstream_impacts[0].semantic_fingerprint == "unknown"
|
|
1471
|
+
|
|
1472
|
+
with pytest.raises(
|
|
1473
|
+
ValueError,
|
|
1474
|
+
match="Semantic fingerprint must be an object or 'unknown'",
|
|
1475
|
+
):
|
|
1476
|
+
DeploymentInfo.from_dict(
|
|
1477
|
+
{
|
|
1478
|
+
"results": [{"semantic_fingerprint": "invalid"}],
|
|
1479
|
+
},
|
|
1480
|
+
)
|
|
1481
|
+
|
|
1482
|
+
def test_deployment_info_parses_older_impact_response(self):
|
|
1483
|
+
parsed = DeploymentInfo.from_dict(
|
|
1484
|
+
{
|
|
1485
|
+
"uuid": "dry_run",
|
|
1486
|
+
"namespace": "test.ns",
|
|
1487
|
+
"status": "success",
|
|
1488
|
+
"results": [
|
|
1489
|
+
{
|
|
1490
|
+
"name": "test.ns.my_node",
|
|
1491
|
+
"operation": "noop",
|
|
1492
|
+
"status": "skipped",
|
|
1493
|
+
},
|
|
1494
|
+
],
|
|
1495
|
+
},
|
|
1496
|
+
)
|
|
1497
|
+
assert parsed.results[0].deploy_type == ""
|
|
1498
|
+
assert parsed.results[0].change_tier is None
|
|
1499
|
+
assert parsed.results[0].semantic_fingerprint is None
|
|
1500
|
+
assert parsed.downstream_impacts == []
|
|
1501
|
+
|
|
1502
|
+
@pytest.mark.parametrize("digest", ["a" * 63, "A" * 64, "g" * 64])
|
|
1503
|
+
def test_semantic_fingerprint_rejects_invalid_digest(self, digest):
|
|
1504
|
+
with pytest.raises(ValueError, match="64 lowercase hexadecimal"):
|
|
1505
|
+
SemanticFingerprint(digest=digest)
|
|
1506
|
+
|
|
1507
|
+
def test_semantic_fingerprint_preserves_unknown_version(self):
|
|
1508
|
+
parsed = DeploymentInfo.from_dict(
|
|
1509
|
+
{
|
|
1510
|
+
"results": [
|
|
1511
|
+
{
|
|
1512
|
+
"semantic_fingerprint": {
|
|
1513
|
+
"version": 2,
|
|
1514
|
+
"digest": "a" * 64,
|
|
1515
|
+
},
|
|
1516
|
+
},
|
|
1517
|
+
],
|
|
1518
|
+
},
|
|
1519
|
+
)
|
|
1520
|
+
|
|
1521
|
+
assert parsed.results[0].semantic_fingerprint == SemanticFingerprint(
|
|
1522
|
+
version=2,
|
|
1523
|
+
digest="a" * 64,
|
|
1524
|
+
)
|
|
1432
1525
|
|
|
1433
1526
|
def test_get_impact_with_namespace_override(self, tmp_path, monkeypatch):
|
|
1434
1527
|
"""get_impact should respect namespace override."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/distinct_node_authors.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/distinct_node_editors.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/median_dim_links_per_node.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/median_dimension_indegree.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/median_downstream_count.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/median_revisions_per_node.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/median_upstream_count.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/number_of_branches.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/number_of_deployments.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/number_of_namespaces.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/seed/nodes/number_of_orphan_nodes.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/skills/datajunction-query/SKILL.md
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/datajunction/skills/datajunction-repo/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/deploy0/roads/companies_dim.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/contractors.source.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/date.source.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/date_dim.dimension.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/dispatchers.source.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/hard_hat.dimension.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/hard_hats.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/municipality.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/repair_type.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/us_region.source.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/us_state.dimension.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project1/roads/us_states.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/avg_repair_price.metric.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/contractor.dimension.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/contractors.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/date_dim.dimension.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/dispatcher.dimension.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/dispatchers.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/hard_hat.dimension.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/hard_hat_state.source.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/hard_hats.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/municipality.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/municipality_type.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/num_repair_orders.metric.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/repair_order.dimension.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/repair_orders.source.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/repair_orders_cube.cube.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/repair_type.source.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/total_repair_cost.metric.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/us_region.source.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/us_state.dimension.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project11/us_states.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project12/roads/companies.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project12/roads/contractors.source.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project12/roads/us_state.dimension.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project12/roads/us_states.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project5/some_node.a.b.c.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project6/roads/contractors.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project7/roads/contractors.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project9/roads/companies.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project9/roads/contractors.source.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project9/roads/us_state.dimension.yaml
RENAMED
|
File without changes
|
{datajunction-0.0.240 → datajunction-0.0.243}/tests/examples/project9/roads/us_states.source.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|