datajunction 0.0.243__tar.gz → 0.0.245__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.
Files changed (184) hide show
  1. {datajunction-0.0.243 → datajunction-0.0.245}/PKG-INFO +1 -1
  2. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/__about__.py +1 -1
  3. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/_internal.py +18 -1
  4. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/deployment.py +1 -1
  5. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/models.py +4 -0
  6. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test__internal.py +76 -0
  7. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_cli.py +4 -4
  8. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_deploy.py +2 -0
  9. {datajunction-0.0.243 → datajunction-0.0.245}/.coveragerc +0 -0
  10. {datajunction-0.0.243 → datajunction-0.0.245}/.gitignore +0 -0
  11. {datajunction-0.0.243 → datajunction-0.0.245}/.pre-commit-config.yaml +0 -0
  12. {datajunction-0.0.243 → datajunction-0.0.245}/LICENSE.txt +0 -0
  13. {datajunction-0.0.243 → datajunction-0.0.245}/Makefile +0 -0
  14. {datajunction-0.0.243 → datajunction-0.0.245}/README.md +0 -0
  15. {datajunction-0.0.243 → datajunction-0.0.245}/claude_desktop_config.example.json +0 -0
  16. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/__init__.py +0 -0
  17. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/_base.py +0 -0
  18. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/admin.py +0 -0
  19. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/builder.py +0 -0
  20. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/cli.py +0 -0
  21. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/client.py +0 -0
  22. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/compile.py +0 -0
  23. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/exceptions.py +0 -0
  24. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/mcp/__init__.py +0 -0
  25. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/mcp/cli.py +0 -0
  26. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/mcp/config.py +0 -0
  27. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/nodes.py +0 -0
  28. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/rendering.py +0 -0
  29. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/init_system_nodes.py +0 -0
  30. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/date.yaml +0 -0
  31. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/deployment.yaml +0 -0
  32. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/dimension_link.yaml +0 -0
  33. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/distinct_node_authors.yaml +0 -0
  34. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/distinct_node_editors.yaml +0 -0
  35. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/dj.yaml +0 -0
  36. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/is_active.yaml +0 -0
  37. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/materialization.yaml +0 -0
  38. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/median_deployment_duration_seconds.yaml +0 -0
  39. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/median_dim_links_per_node.yaml +0 -0
  40. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/median_dimension_indegree.yaml +0 -0
  41. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/median_downstream_count.yaml +0 -0
  42. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/median_revisions_per_node.yaml +0 -0
  43. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/median_upstream_count.yaml +0 -0
  44. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/namespace.yaml +0 -0
  45. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/node_revision.yaml +0 -0
  46. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/node_type.yaml +0 -0
  47. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/nodes.yaml +0 -0
  48. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/number_of_branches.yaml +0 -0
  49. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/number_of_deployments.yaml +0 -0
  50. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/number_of_materializations.yaml +0 -0
  51. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/number_of_namespaces.yaml +0 -0
  52. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/number_of_nodes.yaml +0 -0
  53. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/number_of_orphan_nodes.yaml +0 -0
  54. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/number_of_unused_dimensions.yaml +0 -0
  55. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/repo.yaml +0 -0
  56. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/seed/nodes/user.yaml +0 -0
  57. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/skills/datajunction/SKILL.md +0 -0
  58. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/skills/datajunction-api/SKILL.md +0 -0
  59. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/skills/datajunction-query/SKILL.md +0 -0
  60. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/skills/datajunction-repo/SKILL.md +0 -0
  61. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/skills/datajunction-semantic-model/SKILL.md +0 -0
  62. {datajunction-0.0.243 → datajunction-0.0.245}/datajunction/tags.py +0 -0
  63. {datajunction-0.0.243 → datajunction-0.0.245}/pyproject.toml +0 -0
  64. {datajunction-0.0.243 → datajunction-0.0.245}/setup.cfg +0 -0
  65. {datajunction-0.0.243 → datajunction-0.0.245}/tests/__init__.py +0 -0
  66. {datajunction-0.0.243 → datajunction-0.0.245}/tests/conftest.py +0 -0
  67. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/deploy0/dj.yaml +0 -0
  68. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/deploy0/roads/companies.yaml +0 -0
  69. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/deploy0/roads/companies_dim.yaml +0 -0
  70. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/deploy0/roads/contractor.yaml +0 -0
  71. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/deploy0/roads/contractors.yaml +0 -0
  72. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/deploy0/roads/us_state.yaml +0 -0
  73. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/deploy0/roads/us_states.yaml +0 -0
  74. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/dj.yaml +0 -0
  75. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/avg_length_of_employment.metric.yaml +0 -0
  76. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/avg_repair_price.metric.yaml +0 -0
  77. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/avg_time_to_dispatch.metric.yaml +0 -0
  78. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/contractor.dimension.yaml +0 -0
  79. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/contractors.source.yaml +0 -0
  80. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/date.source.yaml +0 -0
  81. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/date_dim.dimension.yaml +0 -0
  82. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/dispatcher.dimension.yaml +0 -0
  83. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/dispatchers.source.yaml +0 -0
  84. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/hard_hat.dimension.yaml +0 -0
  85. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/hard_hat_state.source.yaml +0 -0
  86. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/hard_hats.source.yaml +0 -0
  87. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/local_hard_hats.dimension.yaml +0 -0
  88. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/municipality.source.yaml +0 -0
  89. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/municipality_dim.dimension.yaml +0 -0
  90. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/municipality_municipality_type.source.yaml +0 -0
  91. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/municipality_type.source.yaml +0 -0
  92. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/national_level_agg.transform.yaml +0 -0
  93. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/num_repair_orders.metric.yaml +0 -0
  94. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/regional_level_agg.transform.yaml +0 -0
  95. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/regional_repair_efficiency.metric.yaml +0 -0
  96. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/repair_order.dimension.yaml +0 -0
  97. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/repair_order_details.source.yaml +0 -0
  98. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/repair_order_transform.transform.yaml +0 -0
  99. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/repair_orders.source.yaml +0 -0
  100. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/repair_orders_cube.cube.yaml +0 -0
  101. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/repair_type.source.yaml +0 -0
  102. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/total_repair_cost.metric.yaml +0 -0
  103. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/total_repair_order_discounts.metric.yaml +0 -0
  104. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/us_region.source.yaml +0 -0
  105. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/us_state.dimension.yaml +0 -0
  106. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project1/roads/us_states.source.yaml +0 -0
  107. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project10/dj.yaml +0 -0
  108. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/avg_length_of_employment.metric.yaml +0 -0
  109. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/avg_repair_price.metric.yaml +0 -0
  110. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/avg_time_to_dispatch.metric.yaml +0 -0
  111. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/contractor.dimension.yaml +0 -0
  112. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/contractors.source.yaml +0 -0
  113. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/date.source.yaml +0 -0
  114. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/date_dim.dimension.yaml +0 -0
  115. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/dispatcher.dimension.yaml +0 -0
  116. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/dispatchers.source.yaml +0 -0
  117. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/dj.yaml +0 -0
  118. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/hard_hat.dimension.yaml +0 -0
  119. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/hard_hat_state.source.yaml +0 -0
  120. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/hard_hats.source.yaml +0 -0
  121. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/local_hard_hats.dimension.yaml +0 -0
  122. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/municipality.source.yaml +0 -0
  123. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/municipality_dim.dimension.yaml +0 -0
  124. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/municipality_municipality_type.source.yaml +0 -0
  125. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/municipality_type.source.yaml +0 -0
  126. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/national_level_agg.transform.yaml +0 -0
  127. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/num_repair_orders.metric.yaml +0 -0
  128. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/regional_level_agg.transform.yaml +0 -0
  129. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/regional_repair_efficiency.metric.yaml +0 -0
  130. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/repair_order.dimension.yaml +0 -0
  131. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/repair_order_details.source.yaml +0 -0
  132. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/repair_order_transform.transform.yaml +0 -0
  133. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/repair_orders.source.yaml +0 -0
  134. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/repair_orders_cube.cube.yaml +0 -0
  135. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/repair_type.source.yaml +0 -0
  136. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/total_repair_cost.metric.yaml +0 -0
  137. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/total_repair_order_discounts.metric.yaml +0 -0
  138. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/us_region.source.yaml +0 -0
  139. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/us_state.dimension.yaml +0 -0
  140. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project11/us_states.source.yaml +0 -0
  141. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project12/dj.yaml +0 -0
  142. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project12/roads/companies.source.yaml +0 -0
  143. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project12/roads/companies_dim.dimension.yaml +0 -0
  144. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project12/roads/contractor.dimension.yaml +0 -0
  145. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project12/roads/contractors.source.yaml +0 -0
  146. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project12/roads/us_state.dimension.yaml +0 -0
  147. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project12/roads/us_states.source.yaml +0 -0
  148. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project2/dj.yaml +0 -0
  149. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project2/some_node.source.yaml +0 -0
  150. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project3/dj.yaml +0 -0
  151. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project3/some_node.yaml +0 -0
  152. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project4/dj.yaml +0 -0
  153. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project4/very/very/deeply/nested/namespace/some_node.source.yaml +0 -0
  154. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project5/dj.yaml +0 -0
  155. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project5/some_node.a.b.c.source.yaml +0 -0
  156. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project6/dj.yaml +0 -0
  157. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project6/roads/contractor.dimension.yaml +0 -0
  158. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project6/roads/contractors.source.yaml +0 -0
  159. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project7/dj.yaml +0 -0
  160. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project7/roads/contractor.dimension.yaml +0 -0
  161. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project7/roads/contractors.source.yaml +0 -0
  162. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project8/dj.yaml +0 -0
  163. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project9/dj.yaml +0 -0
  164. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project9/roads/companies.source.yaml +0 -0
  165. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project9/roads/companies_dim.dimension.yaml +0 -0
  166. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project9/roads/contractor.dimension.yaml +0 -0
  167. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project9/roads/contractors.source.yaml +0 -0
  168. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project9/roads/us_state.dimension.yaml +0 -0
  169. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples/project9/roads/us_states.source.yaml +0 -0
  170. {datajunction-0.0.243 → datajunction-0.0.245}/tests/examples.py +0 -0
  171. {datajunction-0.0.243 → datajunction-0.0.245}/tests/mcp/README.md +0 -0
  172. {datajunction-0.0.243 → datajunction-0.0.245}/tests/mcp/__init__.py +0 -0
  173. {datajunction-0.0.243 → datajunction-0.0.245}/tests/mcp/test_cli.py +0 -0
  174. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_admin.py +0 -0
  175. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_base.py +0 -0
  176. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_builder.py +0 -0
  177. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_client.py +0 -0
  178. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_compile.py +0 -0
  179. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_generated_client.py +0 -0
  180. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_integration.py +0 -0
  181. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_models.py +0 -0
  182. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_plugin_mirror.py +0 -0
  183. {datajunction-0.0.243 → datajunction-0.0.245}/tests/test_skills.py +0 -0
  184. {datajunction-0.0.243 → datajunction-0.0.245}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: datajunction
3
- Version: 0.0.243
3
+ Version: 0.0.245
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>
@@ -2,4 +2,4 @@
2
2
  Version for Hatch
3
3
  """
4
4
 
5
- __version__ = "0.0.243"
5
+ __version__ = "0.0.245"
@@ -4,6 +4,7 @@
4
4
  import logging
5
5
  import os
6
6
  import platform
7
+ import time
7
8
  from dataclasses import asdict, dataclass
8
9
  from typing import TYPE_CHECKING, Any, TypedDict, Union
9
10
  from urllib.parse import urljoin
@@ -235,13 +236,29 @@ class DJClient:
235
236
  def get_deployment_impact(self, deployment_spec: dict[str, Any]):
236
237
  """
237
238
  Get impact analysis for a deployment spec without deploying.
239
+
240
+ The endpoint is asynchronous: it submits a dry-run deployment and
241
+ returns immediately, so this polls ``check_deployment`` until the
242
+ deployment reaches a terminal status (success/failed).
238
243
  """
239
244
  response = self._session.post(
240
245
  "/deployments/impact",
241
246
  json=deployment_spec,
247
+ headers={"Prefer": "respond-async"},
242
248
  timeout=self._timeout,
243
249
  )
244
- return response.json()
250
+ deployment_data = response.json()
251
+ deployment_uuid = deployment_data["uuid"]
252
+
253
+ timeout = time.time() + 300 # 5 minutes
254
+ while deployment_data.get("status") not in ("failed", "success"):
255
+ time.sleep(1)
256
+ deployment_data = self.check_deployment(deployment_uuid)
257
+ if time.time() > timeout:
258
+ raise DJClientException(
259
+ "Deployment impact analysis timed out after 5 minutes",
260
+ )
261
+ return deployment_data
245
262
 
246
263
  @staticmethod
247
264
  def _primary_key_from_columns(columns) -> list[str]:
@@ -299,7 +299,7 @@ class DeploymentService:
299
299
  deployment = DeploymentInfo.from_dict(data)
300
300
  if display:
301
301
  print_results(
302
- "dry_run",
302
+ data.get("uuid", "dry_run"),
303
303
  deployment,
304
304
  console,
305
305
  verbose=verbose,
@@ -406,6 +406,9 @@ class DeploymentResult:
406
406
  deploy_type: str = ""
407
407
  change_tier: Literal["none", "minor", "major"] | None = None
408
408
  semantic_fingerprint: SemanticFingerprintValue | None = None
409
+ # True when the node was re-deployed only to retry a pre-existing failure.
410
+ # None on responses from servers that predate the field.
411
+ revalidation_only: bool | None = None
409
412
 
410
413
  @classmethod
411
414
  def from_dict(cls, d: dict) -> DeploymentResult:
@@ -419,6 +422,7 @@ class DeploymentResult:
419
422
  deploy_type=d.get("deploy_type", ""),
420
423
  change_tier=d.get("change_tier"),
421
424
  semantic_fingerprint=_parse_semantic_fingerprint(fingerprint),
425
+ revalidation_only=d.get("revalidation_only"),
422
426
  )
423
427
 
424
428
 
@@ -38,6 +38,82 @@ class TestDJClient: # pylint: disable=too-many-public-methods, protected-access
38
38
  json={"email": "foo", "username": "bar", "password": "baz"},
39
39
  )
40
40
 
41
+ def test_get_deployment_impact_polls_until_terminal(self, client):
42
+ """
43
+ `get_deployment_impact()` submits the dry-run with the required
44
+ `Prefer: respond-async` header, then polls `check_deployment()`
45
+ until the deployment reaches a terminal status.
46
+ """
47
+ client._session.post = MagicMock(
48
+ return_value=MagicMock(
49
+ json=MagicMock(
50
+ return_value={
51
+ "uuid": "abc-123",
52
+ "namespace": "test.ns",
53
+ "status": "pending",
54
+ },
55
+ ),
56
+ ),
57
+ )
58
+ client.check_deployment = MagicMock(
59
+ side_effect=[
60
+ {"uuid": "abc-123", "namespace": "test.ns", "status": "running"},
61
+ {
62
+ "uuid": "abc-123",
63
+ "namespace": "test.ns",
64
+ "status": "success",
65
+ "results": [],
66
+ "downstream_impacts": [],
67
+ },
68
+ ],
69
+ )
70
+
71
+ with patch("datajunction._internal.time.sleep"):
72
+ result = client.get_deployment_impact({"namespace": "test.ns", "nodes": []})
73
+
74
+ assert client._session.post.call_args == call(
75
+ "/deployments/impact",
76
+ json={"namespace": "test.ns", "nodes": []},
77
+ headers={"Prefer": "respond-async"},
78
+ timeout=client._timeout,
79
+ )
80
+ assert client.check_deployment.call_count == 2
81
+ assert result["status"] == "success"
82
+
83
+ def test_get_deployment_impact_times_out(self, client):
84
+ """
85
+ `get_deployment_impact()` raises if the deployment never reaches a
86
+ terminal status within the timeout window.
87
+ """
88
+ client._session.post = MagicMock(
89
+ return_value=MagicMock(
90
+ json=MagicMock(
91
+ return_value={
92
+ "uuid": "abc-123",
93
+ "namespace": "test.ns",
94
+ "status": "pending",
95
+ },
96
+ ),
97
+ ),
98
+ )
99
+ client.check_deployment = MagicMock(
100
+ return_value={
101
+ "uuid": "abc-123",
102
+ "namespace": "test.ns",
103
+ "status": "running",
104
+ },
105
+ )
106
+
107
+ with (
108
+ patch("datajunction._internal.time.sleep"),
109
+ patch(
110
+ "datajunction._internal.time.time",
111
+ side_effect=[0, 0, 400],
112
+ ),
113
+ ):
114
+ with pytest.raises(DJClientException, match="timed out"):
115
+ client.get_deployment_impact({"namespace": "test.ns", "nodes": []})
116
+
41
117
  def test_basic_login(self, client):
42
118
  """
43
119
  Check that `client.basic_login()` works as expected.
@@ -1221,8 +1221,8 @@ class TestImpactAnalysis:
1221
1221
  main(builder_client=builder_client)
1222
1222
 
1223
1223
  captured = capsys.readouterr()
1224
- # Panel title includes "dry_run" and namespace
1225
- assert "dry_run" in captured.out
1224
+ # Header shows the "dry run" mode
1225
+ assert "dry run" in captured.out
1226
1226
 
1227
1227
  def test_deploy_dryrun_json_format(
1228
1228
  self,
@@ -1272,7 +1272,7 @@ class TestImpactAnalysis:
1272
1272
  main(builder_client=builder_client)
1273
1273
 
1274
1274
  captured = capsys.readouterr()
1275
- assert "dry_run" in captured.out
1275
+ assert "dry run" in captured.out
1276
1276
 
1277
1277
  def test_push_dryrun_json_format(
1278
1278
  self,
@@ -1329,7 +1329,7 @@ class TestImpactAnalysis:
1329
1329
  main(builder_client=builder_client)
1330
1330
 
1331
1331
  captured = capsys.readouterr()
1332
- assert "dry_run" in captured.out
1332
+ assert "dry run" in captured.out
1333
1333
 
1334
1334
  def test_dryrun_shows_downstream_impacts_in_panel(self, capsys):
1335
1335
  """Downstream impacts appear inside the results panel when predicted_status is invalid."""
@@ -1418,6 +1418,7 @@ class TestGetImpact:
1418
1418
  "version": 1,
1419
1419
  "digest": "a" * 64,
1420
1420
  },
1421
+ "revalidation_only": True,
1421
1422
  },
1422
1423
  ],
1423
1424
  "downstream_impacts": [
@@ -1448,6 +1449,7 @@ class TestGetImpact:
1448
1449
  parsed = DeploymentInfo.from_dict(result)
1449
1450
  assert parsed.results[0].deploy_type == "node"
1450
1451
  assert parsed.results[0].change_tier == "none"
1452
+ assert parsed.results[0].revalidation_only is True
1451
1453
  assert parsed.results[0].semantic_fingerprint == SemanticFingerprint(
1452
1454
  digest="a" * 64,
1453
1455
  )
File without changes
File without changes
File without changes
File without changes