datajunction 0.0.185__tar.gz → 0.0.186__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.185 → datajunction-0.0.186}/PKG-INFO +1 -1
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/__about__.py +1 -1
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/_internal.py +0 -7
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/builder.py +2 -5
- datajunction-0.0.186/datajunction/compile.py +36 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/models.py +13 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/init_system_nodes.py +11 -10
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/tags.py +1 -1
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/test__internal.py +35 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/test_base.py +59 -1
- datajunction-0.0.186/tests/test_compile.py +29 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/test_deploy.py +41 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/test_integration.py +1 -1
- datajunction-0.0.186/tests/test_models.py +47 -0
- datajunction-0.0.185/datajunction/compile.py +0 -1177
- datajunction-0.0.185/tests/test_compile.py +0 -572
- datajunction-0.0.185/tests/test_models.py +0 -18
- {datajunction-0.0.185 → datajunction-0.0.186}/.coveragerc +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/.gitignore +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/.pre-commit-config.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/LICENSE.txt +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/Makefile +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/README.md +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/claude_desktop_config.example.json +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/__init__.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/_base.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/admin.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/cli.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/client.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/deployment.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/exceptions.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/mcp/__init__.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/mcp/cli.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/mcp/config.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/nodes.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/rendering.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/date.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/deployment.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/dimension_link.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/distinct_node_authors.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/distinct_node_editors.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/is_active.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/materialization.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/median_deployment_duration_seconds.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/median_dim_links_per_node.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/median_dimension_indegree.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/median_downstream_count.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/median_revisions_per_node.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/median_upstream_count.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/namespace.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/node_revision.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/node_type.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/nodes.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/number_of_branches.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/number_of_deployments.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/number_of_materializations.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/number_of_namespaces.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/number_of_nodes.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/number_of_orphan_nodes.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/number_of_unused_dimensions.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/repo.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/seed/nodes/user.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/skills/datajunction-api.md +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/skills/datajunction-query.md +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/skills/datajunction-repo.md +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/skills/datajunction-semantic-model.md +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/datajunction/skills/datajunction.md +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/pyproject.toml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/setup.cfg +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/__init__.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/conftest.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/deploy0/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/deploy0/roads/companies.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/deploy0/roads/companies_dim.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/deploy0/roads/contractor.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/deploy0/roads/contractors.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/deploy0/roads/us_state.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/deploy0/roads/us_states.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/avg_length_of_employment.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/avg_repair_price.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/avg_time_to_dispatch.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/date.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/date_dim.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/dispatcher.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/dispatchers.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/hard_hat.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/hard_hat_state.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/hard_hats.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/local_hard_hats.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/municipality.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/municipality_dim.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/municipality_municipality_type.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/municipality_type.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/national_level_agg.transform.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/num_repair_orders.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/regional_level_agg.transform.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/regional_repair_efficiency.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/repair_order.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/repair_order_details.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/repair_order_transform.transform.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/repair_orders.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/repair_orders_cube.cube.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/repair_type.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/total_repair_cost.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/total_repair_order_discounts.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/us_region.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/us_state.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project1/roads/us_states.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project10/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/avg_length_of_employment.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/avg_repair_price.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/avg_time_to_dispatch.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/contractor.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/contractors.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/date.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/date_dim.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/dispatcher.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/dispatchers.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/hard_hat.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/hard_hat_state.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/hard_hats.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/local_hard_hats.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/municipality.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/municipality_dim.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/municipality_municipality_type.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/municipality_type.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/national_level_agg.transform.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/num_repair_orders.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/regional_level_agg.transform.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/regional_repair_efficiency.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/repair_order.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/repair_order_details.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/repair_order_transform.transform.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/repair_orders.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/repair_orders_cube.cube.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/repair_type.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/total_repair_cost.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/total_repair_order_discounts.metric.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/us_region.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/us_state.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project11/us_states.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project12/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project12/roads/companies.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project12/roads/companies_dim.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project12/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project12/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project12/roads/us_state.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project12/roads/us_states.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project2/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project2/some_node.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project3/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project3/some_node.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project4/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project4/very/very/deeply/nested/namespace/some_node.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project5/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project5/some_node.a.b.c.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project6/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project6/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project6/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project7/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project7/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project7/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project8/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project9/dj.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project9/roads/companies.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project9/roads/companies_dim.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project9/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project9/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project9/roads/us_state.dimension.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples/project9/roads/us_states.source.yaml +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/examples.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/mcp/README.md +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/mcp/__init__.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/mcp/test_cli.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/test_admin.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/test_builder.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/test_cli.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/test_client.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/test_generated_client.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tests/test_skills.py +0 -0
- {datajunction-0.0.185 → datajunction-0.0.186}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datajunction
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.186
|
|
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>
|
|
@@ -666,13 +666,6 @@ class DJClient:
|
|
|
666
666
|
response = self._session.post(f"/nodes/{node_name}/refresh/")
|
|
667
667
|
return response.json()
|
|
668
668
|
|
|
669
|
-
def _export_namespace(self, namespace):
|
|
670
|
-
"""
|
|
671
|
-
Export an array of definitions contained within a namespace
|
|
672
|
-
"""
|
|
673
|
-
response = self._session.get(f"/namespaces/{namespace}/export/")
|
|
674
|
-
return response.json()
|
|
675
|
-
|
|
676
669
|
def _export_namespace_yaml_zip(
|
|
677
670
|
self,
|
|
678
671
|
namespace: str,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import re
|
|
5
5
|
from dataclasses import fields
|
|
6
6
|
from http import HTTPStatus
|
|
7
|
-
from typing import
|
|
7
|
+
from typing import Dict, List, Optional
|
|
8
8
|
|
|
9
9
|
from datajunction import models
|
|
10
10
|
from datajunction.client import DJClient
|
|
@@ -27,9 +27,6 @@ from datajunction.nodes import (
|
|
|
27
27
|
)
|
|
28
28
|
from datajunction.tags import Tag
|
|
29
29
|
|
|
30
|
-
if TYPE_CHECKING:
|
|
31
|
-
from datajunction.compile import ColumnYAML # pragma: no cover
|
|
32
|
-
|
|
33
30
|
|
|
34
31
|
class DJBuilder(DJClient): # pylint: disable=too-many-public-methods
|
|
35
32
|
"""
|
|
@@ -409,7 +406,7 @@ class DJBuilder(DJClient): # pylint: disable=too-many-public-methods
|
|
|
409
406
|
table: Optional[str] = None,
|
|
410
407
|
display_name: Optional[str] = None,
|
|
411
408
|
description: Optional[str] = None,
|
|
412
|
-
columns: Optional[List["ColumnYAML"]] = None,
|
|
409
|
+
columns: Optional[List["models.ColumnYAML"]] = None,
|
|
413
410
|
primary_key: Optional[List[str]] = None,
|
|
414
411
|
tags: Optional[List[str]] = None,
|
|
415
412
|
mode: Optional[models.NodeMode] = models.NodeMode.PUBLISHED,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Deprecated: client-side compilation has moved server-side.
|
|
2
|
+
|
|
3
|
+
Client-side YAML compilation (the old ``Project`` / ``CompiledProject`` flow)
|
|
4
|
+
has been removed. YAML deployment is now handled entirely server-side: use
|
|
5
|
+
:class:`datajunction.DeploymentService` (or the ``dj push`` / ``dj pull`` CLI),
|
|
6
|
+
which reconstructs a deployment spec from local YAML files and POSTs it to the
|
|
7
|
+
server's ``/deployments`` orchestrator.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from datajunction.exceptions import DJClientException
|
|
11
|
+
|
|
12
|
+
_MESSAGE = (
|
|
13
|
+
"datajunction.Project / client-side YAML compilation has been removed. "
|
|
14
|
+
"Deployment is now handled server-side — use datajunction.DeploymentService "
|
|
15
|
+
"(or the `dj push` CLI)."
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Project: # pylint: disable=too-few-public-methods
|
|
20
|
+
"""
|
|
21
|
+
Deprecated. Client-side project compilation has been removed; deployment is
|
|
22
|
+
now handled server-side via :class:`datajunction.DeploymentService`.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, *args, **kwargs):
|
|
26
|
+
raise DJClientException(_MESSAGE)
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def load(cls, *args, **kwargs):
|
|
30
|
+
"""Deprecated. Use ``datajunction.DeploymentService`` instead."""
|
|
31
|
+
raise DJClientException(_MESSAGE)
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def load_current(cls, *args, **kwargs):
|
|
35
|
+
"""Deprecated. Use ``datajunction.DeploymentService`` instead."""
|
|
36
|
+
raise DJClientException(_MESSAGE)
|
|
@@ -20,6 +20,19 @@ class Engine(SerializableMixin):
|
|
|
20
20
|
version: Optional[str]
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
@dataclass
|
|
24
|
+
class ColumnYAML(SerializableMixin):
|
|
25
|
+
"""
|
|
26
|
+
Represents a column
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
name: str
|
|
30
|
+
type: str
|
|
31
|
+
display_name: Optional[str] = None
|
|
32
|
+
description: Optional[str] = None
|
|
33
|
+
attributes: Optional[List[str]] = None
|
|
34
|
+
|
|
35
|
+
|
|
23
36
|
class MetricDirection(str, enum.Enum):
|
|
24
37
|
"""
|
|
25
38
|
The direction of the metric that's considered good, i.e., higher is better
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from pathlib import Path
|
|
2
3
|
|
|
3
|
-
from datajunction import DJBuilder,
|
|
4
|
+
from datajunction import DJBuilder, DeploymentService
|
|
4
5
|
from datajunction.exceptions import DJClientException
|
|
5
6
|
from datajunction._internal import RequestsSessionWithEndpoint
|
|
6
7
|
|
|
@@ -35,14 +36,14 @@ for table in tables:
|
|
|
35
36
|
logger.error("Error registering tables: %s", exc)
|
|
36
37
|
logger.info("Finished registering DJ system metadata tables")
|
|
37
38
|
|
|
38
|
-
logger.info("Loading DJ system nodes...")
|
|
39
|
-
project = Project.load("nodes")
|
|
40
|
-
logger.info("Finished loading DJ system nodes.")
|
|
41
|
-
|
|
42
|
-
logger.info("Compiling DJ system nodes...")
|
|
43
|
-
compiled_project = project.compile()
|
|
44
|
-
logger.info("Finished compiling DJ system nodes.")
|
|
45
|
-
|
|
46
39
|
logger.info("Deploying DJ system nodes...")
|
|
47
|
-
|
|
40
|
+
# Deployment is handled server-side: DeploymentService reconstructs a deployment
|
|
41
|
+
# spec from the YAML files under `nodes/` and POSTs it to the `/deployments`
|
|
42
|
+
# orchestrator. The explicit namespace (matching the project's `prefix:` in
|
|
43
|
+
# dj.yaml) marks this as the bootstrap/system-seed case, which skips git config.
|
|
44
|
+
# Resolve the seed dir relative to this file so the script works regardless of
|
|
45
|
+
# the caller's working directory.
|
|
46
|
+
nodes_dir = Path(__file__).parent / "nodes"
|
|
47
|
+
service = DeploymentService(client=dj)
|
|
48
|
+
service.push(nodes_dir, namespace="system.dj")
|
|
48
49
|
logger.info("Finished deploying DJ system nodes.")
|
|
@@ -122,3 +122,38 @@ class TestDJClient: # pylint: disable=too-many-public-methods, protected-access
|
|
|
122
122
|
json={},
|
|
123
123
|
timeout=client._timeout,
|
|
124
124
|
)
|
|
125
|
+
|
|
126
|
+
def test__link_dimension_to_node_with_column(self, client):
|
|
127
|
+
"""
|
|
128
|
+
When a `dimension_column` is supplied, it is included in the request params.
|
|
129
|
+
"""
|
|
130
|
+
client._session.post = MagicMock(
|
|
131
|
+
return_value=MagicMock(json=MagicMock(return_value={"ok": True})),
|
|
132
|
+
)
|
|
133
|
+
result = client._link_dimension_to_node(
|
|
134
|
+
"my.node",
|
|
135
|
+
"col",
|
|
136
|
+
"my.dimension",
|
|
137
|
+
"dim_col",
|
|
138
|
+
)
|
|
139
|
+
assert result == {"ok": True}
|
|
140
|
+
client._session.post.assert_called_once_with(
|
|
141
|
+
"/nodes/my.node/columns/col/",
|
|
142
|
+
timeout=client._timeout,
|
|
143
|
+
params={"dimension": "my.dimension", "dimension_column": "dim_col"},
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
def test__link_dimension_to_node_without_column(self, client):
|
|
147
|
+
"""
|
|
148
|
+
When no `dimension_column` is supplied, only the dimension param is sent.
|
|
149
|
+
"""
|
|
150
|
+
client._session.post = MagicMock(
|
|
151
|
+
return_value=MagicMock(json=MagicMock(return_value={"ok": True})),
|
|
152
|
+
)
|
|
153
|
+
result = client._link_dimension_to_node("my.node", "col", "my.dimension", None)
|
|
154
|
+
assert result == {"ok": True}
|
|
155
|
+
client._session.post.assert_called_once_with(
|
|
156
|
+
"/nodes/my.node/columns/col/",
|
|
157
|
+
timeout=client._timeout,
|
|
158
|
+
params={"dimension": "my.dimension"},
|
|
159
|
+
)
|
|
@@ -4,12 +4,70 @@ Test serializable mixin for dict to dataclass conversion
|
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from datetime import datetime
|
|
7
|
-
from typing import List, Optional
|
|
7
|
+
from typing import List, Optional, Union
|
|
8
8
|
|
|
9
9
|
from datajunction._base import SerializableMixin
|
|
10
10
|
from datajunction._internal import DJClient
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
@dataclass
|
|
14
|
+
class CandidateA(SerializableMixin):
|
|
15
|
+
"""A union member that only accepts items discriminated by ``kind == 'a'``."""
|
|
16
|
+
|
|
17
|
+
kind: str
|
|
18
|
+
a_value: str
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def from_dict(cls, dj_client, data):
|
|
22
|
+
if data.get("kind") != "a":
|
|
23
|
+
raise TypeError("not a CandidateA")
|
|
24
|
+
return super().from_dict(dj_client, data)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class CandidateB(SerializableMixin):
|
|
29
|
+
"""A union member that only accepts items discriminated by ``kind == 'b'``."""
|
|
30
|
+
|
|
31
|
+
kind: str
|
|
32
|
+
b_value: str
|
|
33
|
+
|
|
34
|
+
@classmethod
|
|
35
|
+
def from_dict(cls, dj_client, data):
|
|
36
|
+
if data.get("kind") != "b":
|
|
37
|
+
raise TypeError("not a CandidateB")
|
|
38
|
+
return super().from_dict(dj_client, data)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class UnionListHolder(SerializableMixin):
|
|
43
|
+
"""Holds a list whose inner type is a discriminated union of dataclasses."""
|
|
44
|
+
|
|
45
|
+
items: List[Union[CandidateA, CandidateB]]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_serialize_union_list_fallback():
|
|
49
|
+
"""
|
|
50
|
+
When a list's inner type is a union of candidates, each item is tried
|
|
51
|
+
against every candidate; a candidate that raises TypeError/AttributeError
|
|
52
|
+
is skipped in favor of the next one that accepts the item.
|
|
53
|
+
"""
|
|
54
|
+
holder = UnionListHolder.from_dict(
|
|
55
|
+
dj_client=None,
|
|
56
|
+
data={
|
|
57
|
+
"items": [
|
|
58
|
+
{"kind": "a", "a_value": "x"},
|
|
59
|
+
{"kind": "b", "b_value": "y"},
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
)
|
|
63
|
+
assert holder == UnionListHolder(
|
|
64
|
+
items=[
|
|
65
|
+
CandidateA(kind="a", a_value="x"),
|
|
66
|
+
CandidateB(kind="b", b_value="y"),
|
|
67
|
+
],
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
13
71
|
@dataclass
|
|
14
72
|
class DataClassSimple(SerializableMixin):
|
|
15
73
|
"""Simple dataclass"""
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for the deprecated client-side compilation module.
|
|
3
|
+
|
|
4
|
+
Client-side YAML compilation has moved server-side (see DeploymentService).
|
|
5
|
+
The ``Project`` symbol is kept as a deprecation shim that errors when used.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
from datajunction import Project
|
|
11
|
+
from datajunction.exceptions import DJClientException
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_project_instantiation_raises():
|
|
15
|
+
"""Instantiating the deprecated Project raises a clear error."""
|
|
16
|
+
with pytest.raises(DJClientException, match="handled server-side"):
|
|
17
|
+
Project()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_project_load_raises():
|
|
21
|
+
"""Project.load is deprecated and raises."""
|
|
22
|
+
with pytest.raises(DJClientException, match="handled server-side"):
|
|
23
|
+
Project.load("nodes")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_project_load_current_raises():
|
|
27
|
+
"""Project.load_current is deprecated and raises."""
|
|
28
|
+
with pytest.raises(DJClientException, match="handled server-side"):
|
|
29
|
+
Project.load_current()
|
|
@@ -601,6 +601,47 @@ def test_reconstruct_deployment_spec(tmp_path):
|
|
|
601
601
|
assert spec["nodes"][0]["name"] == "foo.bar"
|
|
602
602
|
|
|
603
603
|
|
|
604
|
+
def test_system_seed_matches_server_deployment_spec():
|
|
605
|
+
"""
|
|
606
|
+
The bundled system-node seed is deployed at bootstrap by
|
|
607
|
+
``init_system_nodes`` via ``DeploymentService.push`` -> the server
|
|
608
|
+
``/deployments`` orchestrator. This guards that the seed YAML stays in the
|
|
609
|
+
server's ``DeploymentSpec`` format: it reconstructs the spec exactly as
|
|
610
|
+
``push`` does, then validates it against the server pydantic model (the same
|
|
611
|
+
gate the orchestrator applies). Catches field-name drift between the seed
|
|
612
|
+
and the deployment schema without needing a live deploy.
|
|
613
|
+
"""
|
|
614
|
+
# Imported here (not at module top) so the conftest server bootstrap has
|
|
615
|
+
# resolved the server package's import order first.
|
|
616
|
+
from datajunction_server.models.deployment import (
|
|
617
|
+
DeploymentSpec,
|
|
618
|
+
DimensionJoinLinkSpec,
|
|
619
|
+
)
|
|
620
|
+
|
|
621
|
+
seed_dir = Path(__file__).parent.parent / "datajunction" / "seed" / "nodes"
|
|
622
|
+
svc = DeploymentService(MagicMock())
|
|
623
|
+
spec_dict, warnings = svc._reconstruct_deployment_spec(seed_dir)
|
|
624
|
+
spec_dict["namespace"] = "system.dj"
|
|
625
|
+
|
|
626
|
+
# No filename/node-name mismatches in the bundled seed.
|
|
627
|
+
assert warnings == []
|
|
628
|
+
|
|
629
|
+
# Parses cleanly into the server's DeploymentSpec (raises on any drift).
|
|
630
|
+
spec = DeploymentSpec(**spec_dict)
|
|
631
|
+
assert spec.namespace == "system.dj"
|
|
632
|
+
assert len(spec.nodes) == len(spec_dict["nodes"])
|
|
633
|
+
|
|
634
|
+
# Dimension links resolve to the typed join subclass via the `type`
|
|
635
|
+
# discriminator (the seed uses `type: join`).
|
|
636
|
+
linked = [n for n in spec.nodes if getattr(n, "dimension_links", None)]
|
|
637
|
+
assert linked, "expected seed nodes with dimension links"
|
|
638
|
+
assert all(
|
|
639
|
+
isinstance(link, DimensionJoinLinkSpec)
|
|
640
|
+
for node in linked
|
|
641
|
+
for link in node.dimension_links
|
|
642
|
+
)
|
|
643
|
+
|
|
644
|
+
|
|
604
645
|
@pytest.mark.timeout(2)
|
|
605
646
|
def test_push_waits_until_success(monkeypatch, tmp_path):
|
|
606
647
|
# Create a fake project structure so _reconstruct_deployment_spec returns something
|
|
@@ -9,7 +9,7 @@ from time import sleep
|
|
|
9
9
|
import pytest
|
|
10
10
|
|
|
11
11
|
from datajunction import DJBuilder, models
|
|
12
|
-
from datajunction.
|
|
12
|
+
from datajunction.models import ColumnYAML
|
|
13
13
|
from datajunction.exceptions import DJClientException
|
|
14
14
|
|
|
15
15
|
_logger = logging.getLogger(__name__)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Tests for models."""
|
|
2
|
+
|
|
3
|
+
from datajunction.models import (
|
|
4
|
+
MetricDirection,
|
|
5
|
+
MetricMetadata,
|
|
6
|
+
MetricUnit,
|
|
7
|
+
QueryState,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_metric_metadata_from_dict():
|
|
12
|
+
"""
|
|
13
|
+
Check that MetricMetadata deserializes a server payload, normalizing the
|
|
14
|
+
direction/unit casing and reading the nested unit name.
|
|
15
|
+
"""
|
|
16
|
+
metadata = MetricMetadata.from_dict(
|
|
17
|
+
dj_client=None,
|
|
18
|
+
data={
|
|
19
|
+
"direction": "HIGHER_IS_BETTER",
|
|
20
|
+
"unit": {"name": "DOLLAR"},
|
|
21
|
+
"significant_digits": 2,
|
|
22
|
+
"min_decimal_exponent": -3,
|
|
23
|
+
"max_decimal_exponent": 5,
|
|
24
|
+
},
|
|
25
|
+
)
|
|
26
|
+
assert metadata == MetricMetadata(
|
|
27
|
+
direction=MetricDirection.HIGHER_IS_BETTER,
|
|
28
|
+
unit=MetricUnit.DOLLAR,
|
|
29
|
+
significant_digits=2,
|
|
30
|
+
min_decimal_exponent=-3,
|
|
31
|
+
max_decimal_exponent=5,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_enum_list():
|
|
36
|
+
"""
|
|
37
|
+
Check list of query states works
|
|
38
|
+
"""
|
|
39
|
+
assert QueryState.list() == [
|
|
40
|
+
"UNKNOWN",
|
|
41
|
+
"ACCEPTED",
|
|
42
|
+
"SCHEDULED",
|
|
43
|
+
"RUNNING",
|
|
44
|
+
"FINISHED",
|
|
45
|
+
"CANCELED",
|
|
46
|
+
"FAILED",
|
|
47
|
+
]
|