tinybird 0.0.1.dev314__tar.gz → 0.0.1.dev316__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 (152) hide show
  1. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/PKG-INFO +1 -1
  2. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/datafile/common.py +4 -1
  3. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/service_datasources.py +24 -0
  4. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/__cli__.py +2 -2
  5. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/cli.py +1 -1
  6. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/execute_query.py +1 -1
  7. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/request_endpoint.py +1 -1
  8. tinybird-0.0.1.dev314/tinybird/tb/modules/environment.py → tinybird-0.0.1.dev316/tinybird/tb/modules/branch.py +14 -16
  9. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/build.py +24 -14
  10. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/build_common.py +3 -3
  11. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/cli.py +15 -14
  12. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/common.py +4 -130
  13. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/build.py +1 -1
  14. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/playground.py +1 -1
  15. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/deployment_common.py +22 -8
  16. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/deprecations.py +4 -4
  17. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/dev_server.py +12 -7
  18. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/feedback_manager.py +3 -3
  19. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/info.py +50 -7
  20. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/shell.py +14 -6
  21. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird.egg-info/PKG-INFO +1 -1
  22. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird.egg-info/SOURCES.txt +1 -1
  23. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/setup.cfg +0 -0
  24. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/__cli__.py +0 -0
  25. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/ch_utils/constants.py +0 -0
  26. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/ch_utils/engine.py +0 -0
  27. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/check_pypi.py +0 -0
  28. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/client.py +0 -0
  29. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/config.py +0 -0
  30. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/connectors.py +0 -0
  31. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/context.py +0 -0
  32. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/datafile/exceptions.py +0 -0
  33. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/datafile/parse_connection.py +0 -0
  34. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/datafile/parse_datasource.py +0 -0
  35. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/datafile/parse_pipe.py +0 -0
  36. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/datatypes.py +0 -0
  37. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/feedback_manager.py +0 -0
  38. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/git_settings.py +0 -0
  39. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/prompts.py +0 -0
  40. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/sql.py +0 -0
  41. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/sql_template.py +0 -0
  42. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/sql_template_fmt.py +0 -0
  43. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/sql_toolset.py +0 -0
  44. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/syncasync.py +0 -0
  45. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/check_pypi.py +0 -0
  46. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/client.py +0 -0
  47. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/config.py +0 -0
  48. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/__init__.py +0 -0
  49. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/agent.py +0 -0
  50. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/animations.py +0 -0
  51. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/banner.py +0 -0
  52. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/command_agent.py +0 -0
  53. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/compactor.py +0 -0
  54. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/explore_agent.py +0 -0
  55. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/file_agent.py +0 -0
  56. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/memory.py +0 -0
  57. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/mock_agent.py +0 -0
  58. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/models.py +0 -0
  59. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/prompts.py +0 -0
  60. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/testing_agent.py +0 -0
  61. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/__init__.py +0 -0
  62. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/analyze.py +0 -0
  63. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/append.py +0 -0
  64. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/build.py +0 -0
  65. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/datafile.py +0 -0
  66. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/deploy.py +0 -0
  67. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/deploy_check.py +0 -0
  68. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/diff_resource.py +0 -0
  69. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/file.py +0 -0
  70. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/get_endpoint_stats.py +0 -0
  71. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/get_openapi_definition.py +0 -0
  72. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/mock.py +0 -0
  73. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/plan.py +0 -0
  74. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/run_command.py +0 -0
  75. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/secret.py +0 -0
  76. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/tools/test.py +0 -0
  77. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/agent/utils.py +0 -0
  78. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/cicd.py +0 -0
  79. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/config.py +0 -0
  80. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/connection.py +0 -0
  81. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/copy.py +0 -0
  82. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/create.py +0 -0
  83. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/build_common.py +0 -0
  84. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  85. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  86. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/diff.py +0 -0
  87. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/fixture.py +0 -0
  88. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/format_common.py +0 -0
  89. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  90. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  91. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  92. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datafile/pull.py +0 -0
  93. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/datasource.py +0 -0
  94. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/deployment.py +0 -0
  95. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/endpoint.py +0 -0
  96. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/exceptions.py +0 -0
  97. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/infra.py +0 -0
  98. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/job.py +0 -0
  99. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/llm.py +0 -0
  100. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/llm_utils.py +0 -0
  101. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/local.py +0 -0
  102. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/local_common.py +0 -0
  103. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/local_logs.py +0 -0
  104. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/login.py +0 -0
  105. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/login_common.py +0 -0
  106. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/logout.py +0 -0
  107. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/materialization.py +0 -0
  108. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/mock.py +0 -0
  109. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/mock_common.py +0 -0
  110. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/open.py +0 -0
  111. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/pipe.py +0 -0
  112. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/project.py +0 -0
  113. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/regions.py +0 -0
  114. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/secret.py +0 -0
  115. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/secret_common.py +0 -0
  116. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/sink.py +0 -0
  117. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/table.py +0 -0
  118. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/telemetry.py +0 -0
  119. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/test.py +0 -0
  120. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/test_common.py +0 -0
  121. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  122. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  123. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/token.py +0 -0
  124. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/watch.py +0 -0
  125. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/workspace.py +0 -0
  126. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb/modules/workspace_members.py +0 -0
  127. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli.py +0 -0
  128. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/auth.py +0 -0
  129. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/branch.py +0 -0
  130. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/cicd.py +0 -0
  131. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/cli.py +0 -0
  132. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/common.py +0 -0
  133. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/config.py +0 -0
  134. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/connection.py +0 -0
  135. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/datasource.py +0 -0
  136. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/exceptions.py +0 -0
  137. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/fmt.py +0 -0
  138. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/job.py +0 -0
  139. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/pipe.py +0 -0
  140. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/regions.py +0 -0
  141. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/tag.py +0 -0
  142. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/telemetry.py +0 -0
  143. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/test.py +0 -0
  144. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  145. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  146. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/workspace.py +0 -0
  147. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  148. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird/tornado_template.py +0 -0
  149. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird.egg-info/dependency_links.txt +0 -0
  150. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird.egg-info/entry_points.txt +0 -0
  151. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird.egg-info/requires.txt +0 -0
  152. {tinybird-0.0.1.dev314 → tinybird-0.0.1.dev316}/tinybird.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev314
3
+ Version: 0.0.1.dev316
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -2127,6 +2127,9 @@ def parse(
2127
2127
  return ParseResult(datafile=doc, warnings=warnings)
2128
2128
 
2129
2129
 
2130
+ # TODO: This class is duplicated in tinybird/datafile_common.py with a slightly different
2131
+ # _REPLACEMENTS tuple. The duplication happened during the CLI/server code split (commit
2132
+ # f86d02cdd7). Consider extracting shared code into a common module that both files can import.
2130
2133
  class ImportReplacements:
2131
2134
  _REPLACEMENTS: Tuple[Tuple[str, str, Optional[str]], ...] = (
2132
2135
  ("import_strategy", "mode", "replace"),
@@ -2146,7 +2149,7 @@ class ImportReplacements:
2146
2149
  return [x[0] for x in ImportReplacements._REPLACEMENTS]
2147
2150
 
2148
2151
  @staticmethod
2149
- def get_api_param_for_datafile_param(connector_service: str, key: str) -> Tuple[Optional[str], Optional[str]]:
2152
+ def get_api_param_for_datafile_param(key: str) -> Tuple[Optional[str], Optional[str]]:
2150
2153
  """Returns the API parameter name and default value for a given
2151
2154
  datafile parameter.
2152
2155
  """
@@ -528,6 +528,30 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
528
528
  {"name": "vcpu_time", "type": "Float64"},
529
529
  ],
530
530
  },
531
+ {
532
+ "name": "tinybird.query_validator_log",
533
+ "description": "Log of failed queries executions in the next available ClickHouse version and their results.",
534
+ "dateColumn": "run_validation",
535
+ "engine": {
536
+ "engine": "MergeTree",
537
+ "sorting_key": "database, host, run_validation, query_hash",
538
+ "partition_key": "toYYYYMM(run_validation)",
539
+ },
540
+ "columns": [
541
+ {"name": "host", "type": "LowCardinality(String)"},
542
+ {"name": "version", "type": "LowCardinality(String)"},
543
+ {"name": "query_hash", "type": "UInt64"},
544
+ {"name": "query_last_execution", "type": "DateTime"},
545
+ {"name": "region", "type": "String"},
546
+ {"name": "workspace", "type": "String"},
547
+ {"name": "database", "type": "String"},
548
+ {"name": "pipe_name", "type": "String"},
549
+ {"name": "query_id", "type": "String"},
550
+ {"name": "error_code", "type": "Int16"},
551
+ {"name": "error", "type": "String"},
552
+ {"name": "run_validation", "type": "DateTime"},
553
+ ],
554
+ },
531
555
  ]
532
556
 
533
557
 
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
4
4
  __url__ = 'https://www.tinybird.co/docs/forward/commands'
5
5
  __author__ = 'Tinybird'
6
6
  __author_email__ = 'support@tinybird.co'
7
- __version__ = '0.0.1.dev314'
8
- __revision__ = 'c7acb8a'
7
+ __version__ = '0.0.1.dev316'
8
+ __revision__ = 'aceca33'
@@ -1,4 +1,5 @@
1
1
  import tinybird.tb.modules.agent
2
+ import tinybird.tb.modules.branch
2
3
  import tinybird.tb.modules.build
3
4
  import tinybird.tb.modules.cli
4
5
  import tinybird.tb.modules.common
@@ -9,7 +10,6 @@ import tinybird.tb.modules.datasource
9
10
  import tinybird.tb.modules.deployment
10
11
  import tinybird.tb.modules.deprecations
11
12
  import tinybird.tb.modules.endpoint
12
- import tinybird.tb.modules.environment
13
13
  import tinybird.tb.modules.info
14
14
  import tinybird.tb.modules.infra
15
15
  import tinybird.tb.modules.job
@@ -148,7 +148,7 @@ def execute_query(
148
148
  ctx.deps.thinking_animation.stop()
149
149
  click.echo(FeedbackManager.error(message=error))
150
150
  ctx.deps.thinking_animation.start()
151
- if "not found" in error.lower() and cloud:
151
+ if "not found" in error.lower() and cloud_or_local == "cloud":
152
152
  return f"Error executing query: {error}. Please run the query against Tinybird local instead of cloud."
153
153
  else:
154
154
  return f"Error executing query: {error}. Please try again."
@@ -87,7 +87,7 @@ def request_endpoint(
87
87
  click.echo(FeedbackManager.error(message=error))
88
88
  ctx.deps.thinking_animation.start()
89
89
  not_found_errors = ["not found", "does not exist"]
90
- if any(not_found_error in error.lower() for not_found_error in not_found_errors) and cloud:
90
+ if any(not_found_error in error.lower() for not_found_error in not_found_errors) and cloud_or_local == "cloud":
91
91
  return f"Error executing query: {error}. Please run the query against Tinybird local instead of cloud."
92
92
  else:
93
93
  return f"Error executing query: {error}. Please try again."
@@ -23,16 +23,16 @@ from tinybird.tb.modules.exceptions import CLIBranchException, CLIException
23
23
  from tinybird.tb.modules.feedback_manager import FeedbackManager
24
24
 
25
25
 
26
- @cli.group(hidden=True)
27
- def environment() -> None:
28
- """Environment commands. Custom environments is an experimental feature in beta."""
26
+ @cli.group()
27
+ def branch() -> None:
28
+ """Branch commands. Custom branches is an experimental feature in beta."""
29
29
  pass
30
30
 
31
31
 
32
- @environment.command(name="ls")
32
+ @branch.command(name="ls")
33
33
  @click.option("--sort/--no-sort", default=False, help="Sort the table rows by name")
34
34
  def branch_ls(sort: bool) -> None:
35
- """List all the environments available in the current workspace"""
35
+ """List all the branches available in the current workspace"""
36
36
 
37
37
  config = CLIConfig.get_project_config()
38
38
  _ = try_update_config_with_remote(config, only_if_needed=True)
@@ -66,17 +66,17 @@ def branch_ls(sort: bool) -> None:
66
66
 
67
67
  sorted_table = current_branch + other_branches
68
68
 
69
- click.echo(FeedbackManager.info(message="\n** Environments:"))
69
+ click.echo(FeedbackManager.info(message="\n** Branches:"))
70
70
  echo_safe_humanfriendly_tables_format_smart_table(sorted_table, column_names=columns)
71
71
 
72
72
 
73
- @environment.command(name="create", short_help="Create a new environment in the current Workspace")
74
- @click.argument("environment_name", required=False)
73
+ @branch.command(name="create", short_help="Create a new branch in the current Workspace")
74
+ @click.argument("branch_name", required=False)
75
75
  @click.option(
76
76
  "--last-partition",
77
77
  is_flag=True,
78
78
  default=False,
79
- help="Attach the last modified partition from the current workspace to the new environment",
79
+ help="Attach the last modified partition from the current workspace to the new branch",
80
80
  )
81
81
  @click.option(
82
82
  "-i",
@@ -92,17 +92,15 @@ def branch_ls(sort: bool) -> None:
92
92
  default=True,
93
93
  help="Wait for data branch jobs to finish, showing a progress bar. Disabled by default.",
94
94
  )
95
- def create_environment(
96
- environment_name: Optional[str], last_partition: bool, ignore_datasources: List[str], wait: bool
97
- ) -> None:
98
- create_workspace_branch(environment_name, last_partition, False, list(ignore_datasources), wait)
95
+ def create_branch(branch_name: Optional[str], last_partition: bool, ignore_datasources: List[str], wait: bool) -> None:
96
+ create_workspace_branch(branch_name, last_partition, False, list(ignore_datasources), wait)
99
97
 
100
98
 
101
- @environment.command(name="rm", short_help="Removes an environment from the workspace. It can't be recovered.")
99
+ @branch.command(name="rm", short_help="Removes an branch from the workspace. It can't be recovered.")
102
100
  @click.argument("branch_name_or_id")
103
101
  @click.option("--yes", is_flag=True, default=False, help="Do not ask for confirmation")
104
- def delete_environment(branch_name_or_id: str, yes: bool) -> None:
105
- """Remove an environment"""
102
+ def delete_branch(branch_name_or_id: str, yes: bool) -> None:
103
+ """Remove an branch"""
106
104
 
107
105
  config = CLIConfig.get_project_config()
108
106
  _ = try_update_config_with_remote(config)
@@ -3,7 +3,7 @@ import time
3
3
  from copy import deepcopy
4
4
  from functools import partial
5
5
  from pathlib import Path
6
- from typing import Any, Callable, Dict, List
6
+ from typing import Any, Callable, Dict, List, Optional
7
7
  from urllib.parse import urlencode
8
8
 
9
9
  import click
@@ -35,10 +35,10 @@ def build(ctx: click.Context, watch: bool) -> None:
35
35
  project: Project = ctx.ensure_object(dict)["project"]
36
36
  tb_client: TinyB = ctx.ensure_object(dict)["client"]
37
37
  config: Dict[str, Any] = ctx.ensure_object(dict)["config"]
38
- is_environment = bool(ctx.ensure_object(dict)["environment"])
38
+ is_branch = bool(ctx.ensure_object(dict)["branch"])
39
39
 
40
- # TODO: Explain that you can use custom environments too once they are open for everyone
41
- if obj["env"] == "cloud" and not is_environment:
40
+ # TODO: Explain that you can use custom branches too once they are open for everyone
41
+ if obj["env"] == "cloud" and not is_branch:
42
42
  raise click.ClickException(FeedbackManager.error_build_only_supported_in_local())
43
43
 
44
44
  if project.has_deeper_level():
@@ -51,7 +51,7 @@ def build(ctx: click.Context, watch: bool) -> None:
51
51
  )
52
52
 
53
53
  click.echo(FeedbackManager.highlight_building_project())
54
- process(project=project, tb_client=tb_client, watch=False, config=config, is_environment=is_environment)
54
+ process(project=project, tb_client=tb_client, watch=False, config=config, is_branch=is_branch)
55
55
  if watch:
56
56
  run_watch(
57
57
  project=project,
@@ -63,7 +63,7 @@ def build(ctx: click.Context, watch: bool) -> None:
63
63
  tb_client=tb_client,
64
64
  watch=True,
65
65
  config=config,
66
- is_environment=is_environment,
66
+ is_branch=is_branch,
67
67
  ),
68
68
  )
69
69
 
@@ -74,13 +74,20 @@ def build(ctx: click.Context, watch: bool) -> None:
74
74
  @click.pass_context
75
75
  def dev(ctx: click.Context, data_origin: str, ui: bool) -> None:
76
76
  obj: Dict[str, Any] = ctx.ensure_object(dict)
77
- is_environment = bool(ctx.ensure_object(dict)["environment"])
78
- # TODO: Explain that you can use custom environments too once they are open for everyone
79
- if obj["env"] == "cloud" and not is_environment:
77
+ branch: Optional[str] = ctx.ensure_object(dict)["branch"]
78
+ is_branch = bool(branch)
79
+
80
+ if obj["env"] == "cloud" and not is_branch:
80
81
  raise click.ClickException(FeedbackManager.error_build_only_supported_in_local())
81
82
 
82
83
  if data_origin == "cloud":
84
+ click.echo(
85
+ FeedbackManager.warning(
86
+ message="--data-origin=cloud is deprecated and will be removed in a future version. Create an branch and use `tb --branch <branch_name> dev`"
87
+ )
88
+ )
83
89
  return dev_cloud(ctx)
90
+
84
91
  project: Project = ctx.ensure_object(dict)["project"]
85
92
  tb_client: TinyB = ctx.ensure_object(dict)["client"]
86
93
  config: Dict[str, Any] = ctx.ensure_object(dict)["config"]
@@ -88,7 +95,7 @@ def dev(ctx: click.Context, data_origin: str, ui: bool) -> None:
88
95
  build_status = BuildStatus()
89
96
  if ui:
90
97
  server_thread = threading.Thread(
91
- target=start_server, args=(project, tb_client, process, build_status), daemon=True
98
+ target=start_server, args=(project, tb_client, process, build_status, branch), daemon=True
92
99
  )
93
100
  server_thread.start()
94
101
  # Wait for the server to start
@@ -101,25 +108,28 @@ def dev(ctx: click.Context, data_origin: str, ui: bool) -> None:
101
108
  watch=True,
102
109
  config=config,
103
110
  build_status=build_status,
104
- is_environment=is_environment,
111
+ is_branch=is_branch,
105
112
  )
106
113
  run_watch(
107
114
  project=project,
108
115
  tb_client=tb_client,
109
116
  config=config,
117
+ branch=branch,
110
118
  process=partial(
111
119
  process,
112
120
  project=project,
113
121
  tb_client=tb_client,
114
122
  build_status=build_status,
115
123
  config=config,
116
- is_environment=is_environment,
124
+ is_branch=is_branch,
117
125
  ),
118
126
  )
119
127
 
120
128
 
121
- def run_watch(project: Project, tb_client: TinyB, process: Callable, config: dict[str, Any]) -> None:
122
- shell = Shell(project=project, tb_client=tb_client, playground=False)
129
+ def run_watch(
130
+ project: Project, tb_client: TinyB, process: Callable, config: dict[str, Any], branch: Optional[str] = None
131
+ ) -> None:
132
+ shell = Shell(project=project, tb_client=tb_client, branch=branch)
123
133
  click.echo(FeedbackManager.gray(message="\nWatching for changes..."))
124
134
  watcher_thread = threading.Thread(
125
135
  target=watch_project,
@@ -33,16 +33,16 @@ def process(
33
33
  exit_on_error: bool = True,
34
34
  load_fixtures: bool = True,
35
35
  project_with_vendors: Optional[Project] = None,
36
- is_environment: bool = False,
36
+ is_branch: bool = False,
37
37
  ) -> Optional[str]:
38
38
  time_start = time.time()
39
39
 
40
40
  # Build vendored workspaces before build
41
- if not project_with_vendors and not is_environment:
41
+ if not project_with_vendors and not is_branch:
42
42
  build_vendored_workspaces(project=project, tb_client=tb_client, config=config)
43
43
 
44
44
  # Ensure SHARED_WITH workspaces exist before build
45
- if not is_environment:
45
+ if not is_branch:
46
46
  build_shared_with_workspaces(project=project, tb_client=tb_client, config=config)
47
47
 
48
48
  build_failed = False
@@ -76,7 +76,7 @@ VERSION = f"{__cli__.__version__} (rev {__cli__.__revision__})"
76
76
  )
77
77
  @click.option("--show-tokens", is_flag=True, default=False, help="Enable the output of tokens.")
78
78
  @click.option("--cloud/--local", is_flag=True, default=False, help="Run against cloud or local.")
79
- @click.option("--environment", help="Run against a custom environment.")
79
+ @click.option("--branch", help="Run against a branch.")
80
80
  @click.option("--staging", is_flag=True, default=False, help="Run against a staging deployment.")
81
81
  @click.option(
82
82
  "--output", type=click.Choice(["human", "json", "csv"], case_sensitive=False), default="human", help="Output format"
@@ -104,7 +104,7 @@ def cli(
104
104
  version_warning: bool,
105
105
  show_tokens: bool,
106
106
  cloud: bool,
107
- environment: Optional[str],
107
+ branch: Optional[str],
108
108
  staging: bool,
109
109
  output: str,
110
110
  max_depth: int,
@@ -205,27 +205,27 @@ def cli(
205
205
  client = create_ctx_client(
206
206
  ctx,
207
207
  config,
208
- cloud or bool(environment),
208
+ cloud or bool(branch),
209
209
  staging,
210
210
  project=project,
211
211
  show_warnings=version_warning,
212
- environment=environment,
212
+ branch=branch,
213
213
  )
214
214
 
215
215
  if client:
216
216
  ctx.ensure_object(dict)["client"] = client
217
217
 
218
- ctx.ensure_object(dict)["env"] = get_target_env(cloud, environment)
219
- ctx.ensure_object(dict)["environment"] = environment
218
+ ctx.ensure_object(dict)["env"] = get_target_env(cloud, branch)
219
+ ctx.ensure_object(dict)["branch"] = branch
220
220
  ctx.ensure_object(dict)["output"] = output
221
221
 
222
222
  is_prompt_mode = prompt is not None
223
223
 
224
224
  if is_agent_mode or is_prompt_mode:
225
- if any(arg in sys.argv for arg in ["--cloud", "--local"]):
225
+ if any(arg in sys.argv for arg in ["--cloud", "--local", "--branch"]):
226
226
  raise CLIException(
227
227
  FeedbackManager.error(
228
- message="Tinybird Code does not support --cloud or --local flags. It will choose the correct environment based on your prompts."
228
+ message="Tinybird Code does not support --cloud, --local or --branch flags. It will choose the correct environment based on your prompts."
229
229
  )
230
230
  )
231
231
 
@@ -501,7 +501,7 @@ def create_ctx_client(
501
501
  staging: bool,
502
502
  project: Project,
503
503
  show_warnings: bool = True,
504
- environment: Optional[str] = None,
504
+ branch: Optional[str] = None,
505
505
  ):
506
506
  commands_without_ctx_client = [
507
507
  "auth",
@@ -515,6 +515,7 @@ def create_ctx_client(
515
515
  "tag",
516
516
  "push",
517
517
  "branch",
518
+ "environment",
518
519
  "diff",
519
520
  "fmt",
520
521
  "init",
@@ -523,8 +524,8 @@ def create_ctx_client(
523
524
  if not command or command in commands_without_ctx_client:
524
525
  return None
525
526
 
526
- commands_always_cloud = ["infra", "environment"]
527
- commands_always_local = ["dev", "create"]
527
+ commands_always_cloud = ["infra", "branch", "environment"]
528
+ commands_always_local = ["create"]
528
529
  command_always_test = ["test"]
529
530
 
530
531
  if (
@@ -547,7 +548,7 @@ def create_ctx_client(
547
548
  if method and show_warnings:
548
549
  click.echo(FeedbackManager.gray(message=f"Authentication method: {method}"))
549
550
 
550
- return _get_tb_client(config.get("token", ""), config["host"], staging=staging, environment=environment)
551
+ return _get_tb_client(config.get("token", ""), config["host"], staging=staging, branch=branch)
551
552
  local = command in commands_always_local
552
553
  test = command in command_always_test
553
554
  if show_warnings and not local and command not in commands_always_local and command:
@@ -555,8 +556,8 @@ def create_ctx_client(
555
556
  return get_tinybird_local_client(config, test=test, staging=staging)
556
557
 
557
558
 
558
- def get_target_env(cloud: bool, environment: Optional[str]) -> str:
559
- if cloud or bool(environment):
559
+ def get_target_env(cloud: bool, branch: Optional[str]) -> str:
560
+ if cloud or bool(branch):
560
561
  return "cloud"
561
562
  return "local"
562
563
 
@@ -30,7 +30,6 @@ import requests
30
30
  from click import Context
31
31
  from click._termui_impl import ProgressBar
32
32
  from humanfriendly.tables import format_pretty_table
33
- from packaging.version import Version
34
33
  from thefuzz import process
35
34
 
36
35
  from tinybird.tb.client import (
@@ -61,7 +60,6 @@ from tinybird.tb.modules.exceptions import (
61
60
  CLIAuthException,
62
61
  CLIConnectionException,
63
62
  CLIException,
64
- CLIReleaseException,
65
63
  CLIWorkspaceException,
66
64
  )
67
65
  from tinybird.tb.modules.feedback_manager import FeedbackManager, warning_message
@@ -378,7 +376,7 @@ def getenv_bool(key: str, default: bool) -> bool:
378
376
  return v.lower() == "true" or v == "1"
379
377
 
380
378
 
381
- def _get_tb_client(token: str, host: str, staging: bool = False, environment: Optional[str] = None) -> TinyB:
379
+ def _get_tb_client(token: str, host: str, staging: bool = False, branch: Optional[str] = None) -> TinyB:
382
380
  disable_ssl: bool = getenv_bool("TB_DISABLE_SSL_CHECKS", False)
383
381
  cloud_client = TinyB(
384
382
  token,
@@ -389,13 +387,13 @@ def _get_tb_client(token: str, host: str, staging: bool = False, environment: Op
389
387
  staging=staging,
390
388
  )
391
389
 
392
- if not environment:
390
+ if not branch:
393
391
  return cloud_client
394
392
 
395
393
  workspaces = cloud_client.user_workspaces_and_branches(version="v1")
396
- workspace = next((w for w in workspaces.get("workspaces", []) if w.get("name") == environment), None)
394
+ workspace = next((w for w in workspaces.get("workspaces", []) if w.get("name") == branch), None)
397
395
  if not workspace:
398
- raise CLIException(FeedbackManager.error_exception(error=f"Environment {environment} not found"))
396
+ raise CLIException(FeedbackManager.error_exception(error=f"Branch {branch} not found"))
399
397
 
400
398
  return TinyB(
401
399
  workspace.get("token", ""),
@@ -1603,130 +1601,6 @@ def _get_current_main_workspace_common(
1603
1601
  return current
1604
1602
 
1605
1603
 
1606
- def is_post_semver(new_version: Version, current_version: Version) -> bool:
1607
- """
1608
- Check if only the post part of the semantic version has changed.
1609
-
1610
- Args:
1611
- new_version (Version): The new version to check.
1612
- current_version (Version): The current version to compare with.
1613
-
1614
- Returns:
1615
- bool: True if only the post part of the version has changed, False otherwise.
1616
-
1617
- Examples:
1618
- >>> is_post_semver(Version("0.0.0-2"), Version("0.0.0-1"))
1619
- True
1620
- >>> is_post_semver(Version("0.0.0-1"), Version("0.0.0-1"))
1621
- False
1622
- >>> is_post_semver(Version("0.0.1-1"), Version("0.0.0-1"))
1623
- False
1624
- >>> is_post_semver(Version("0.1.0-1"), Version("0.0.0-1"))
1625
- False
1626
- >>> is_post_semver(Version("1.0.0-1"), Version("0.0.0-1"))
1627
- False
1628
- >>> is_post_semver(Version("0.0.1-1"), Version("0.0.0"))
1629
- False
1630
- """
1631
- if (
1632
- new_version.major == current_version.major
1633
- and new_version.minor == current_version.minor
1634
- and new_version.micro == current_version.micro
1635
- ):
1636
- return new_version.post is not None and new_version.post != current_version.post
1637
-
1638
- return False
1639
-
1640
-
1641
- def is_major_semver(new_version: Version, current_version: Version) -> bool:
1642
- """
1643
- Check if only the major part of the semantic version has changed.
1644
-
1645
- Args:
1646
- new_version (Version): The new version to check.
1647
- current_version (Version): The current version to compare with.
1648
-
1649
- Returns:
1650
- bool: True if only the major part of the version has changed, False otherwise.
1651
-
1652
- Examples:
1653
- >>> is_major_semver(Version("1.0.0"), Version("0.0.0"))
1654
- True
1655
- >>> is_major_semver(Version("0.0.0"), Version("0.0.0"))
1656
- False
1657
- >>> is_major_semver(Version("1.0.1"), Version("1.0.0"))
1658
- False
1659
- >>> is_major_semver(Version("2.0.0-1"), Version("1.0.1-2"))
1660
- True
1661
- """
1662
-
1663
- return new_version.major != current_version.major
1664
-
1665
-
1666
- def print_release_summary(config: CLIConfig, semver: Optional[str], info: bool = False, dry_run=False):
1667
- if not semver:
1668
- click.echo(FeedbackManager.info_release_no_rollback())
1669
- return
1670
- try:
1671
- client = config.get_client()
1672
- response = client.release_rm(config["id"], semver, confirmation=config["name"], dry_run=True)
1673
- except Exception as e:
1674
- raise CLIReleaseException(FeedbackManager.error_exception(error=str(e)))
1675
- else:
1676
- columns = ["name", "id", "notes"]
1677
- if not response:
1678
- click.echo(FeedbackManager.info_release_no_rollback())
1679
- return
1680
-
1681
- if len(response["datasources"]) or len(response["pipes"]):
1682
- semver = response.get("semver", semver)
1683
- if info:
1684
- if dry_run:
1685
- click.echo(FeedbackManager.info_release_rm_resources_dry_run(semver=semver))
1686
- else:
1687
- click.echo(FeedbackManager.info_release_rm_resources())
1688
- else:
1689
- click.echo(FeedbackManager.info_release_rollback(semver=semver))
1690
-
1691
- if len(response["datasources"]):
1692
- click.echo("\nDatasources:")
1693
- rows = [
1694
- [ds, response["datasources"][ds], response["notes"].get(response["datasources"][ds], "")]
1695
- for ds in response["datasources"]
1696
- ]
1697
- echo_safe_humanfriendly_tables_format_smart_table(rows, column_names=columns)
1698
-
1699
- if len(response["pipes"]):
1700
- click.echo("\nPipes:")
1701
- rows = [
1702
- [pipe, response["pipes"][pipe], response["notes"].get(response["pipes"][pipe], "")]
1703
- for pipe in response["pipes"]
1704
- ]
1705
- echo_safe_humanfriendly_tables_format_smart_table(rows, column_names=columns)
1706
-
1707
-
1708
- def get_oldest_rollback(config: CLIConfig, client: TinyB) -> Optional[str]:
1709
- oldest_rollback_response = client.release_oldest_rollback(config["id"])
1710
- return oldest_rollback_response.get("semver") if oldest_rollback_response else None
1711
-
1712
-
1713
- def remove_release(
1714
- dry_run: bool, config: CLIConfig, semver: Optional[str], client: TinyB, force: bool, show_print=True
1715
- ):
1716
- if semver == OLDEST_ROLLBACK:
1717
- semver = get_oldest_rollback(config, client)
1718
- if show_print:
1719
- print_release_summary(config, semver, info=True, dry_run=True)
1720
- if not dry_run:
1721
- if semver:
1722
- response = client.release_rm(
1723
- config["id"], semver, confirmation=config["name"], dry_run=dry_run, force=force
1724
- )
1725
- click.echo(FeedbackManager.success_release_delete(semver=response.get("semver")))
1726
- else:
1727
- click.echo(FeedbackManager.info_no_release_deleted())
1728
-
1729
-
1730
1604
  def run_aws_iamrole_connection_flow(
1731
1605
  client: TinyB,
1732
1606
  service: str,
@@ -1048,7 +1048,7 @@ def process_file(
1048
1048
  #
1049
1049
  # Note: any unknown import_ parameter is leaved as is.
1050
1050
  for key in ImportReplacements.get_datafile_parameter_keys():
1051
- replacement, default_value = ImportReplacements.get_api_param_for_datafile_param(service, key)
1051
+ replacement, default_value = ImportReplacements.get_api_param_for_datafile_param(key)
1052
1052
  if not replacement:
1053
1053
  continue # We should not reach this never, but just in case...
1054
1054
 
@@ -1200,7 +1200,7 @@ def process_file(
1200
1200
  #
1201
1201
  # Note: any unknown import_ parameter is leaved as is.
1202
1202
  for key in ImportReplacements.get_datafile_parameter_keys():
1203
- replacement, default_value = ImportReplacements.get_api_param_for_datafile_param(service, key)
1203
+ replacement, default_value = ImportReplacements.get_api_param_for_datafile_param(key)
1204
1204
  if not replacement:
1205
1205
  continue # We should not reach this never, but just in case...
1206
1206
 
@@ -338,10 +338,13 @@ def create_deployment(
338
338
  sys_exit("deployment_error", "Error parsing deployment from response")
339
339
  return
340
340
 
341
- if deployment.get("status") == "failed":
341
+ status = deployment.get("status")
342
+ errors = deployment.get("errors")
343
+ feedback = deployment.get("feedback")
344
+
345
+ if status == "failed":
342
346
  click.echo(FeedbackManager.error(message="Deployment failed"))
343
- deploy_errors = deployment.get("errors")
344
- for deploy_error in deploy_errors:
347
+ for deploy_error in errors:
345
348
  click.echo(FeedbackManager.error(message=f"* {deploy_error}"))
346
349
 
347
350
  if auto:
@@ -349,15 +352,26 @@ def create_deployment(
349
352
  discard_deployment(client.host, HEADERS, wait=wait)
350
353
  sys_exit(
351
354
  "deployment_error",
352
- f"Deployment failed. Errors: {str(deployment.get('errors') + deployment.get('feedback', []))}",
355
+ f"Deployment failed. Errors: {str(errors + (feedback or []))}",
353
356
  )
354
357
 
355
- if deployment.get("status") == "data_ready":
358
+ if status == "data_ready":
356
359
  break
357
360
 
358
- if deployment.get("status") in ["deleting", "deleted"]:
359
- click.echo(FeedbackManager.error(message="Deployment was deleted by another process"))
360
- sys_exit("deployment_error", "Deployment was deleted by another process")
361
+ if status in ["deleting", "deleted"]:
362
+ errors = deployment.get("errors")
363
+ if errors:
364
+ verb = "is being" if status == "deleting" else "was"
365
+ click.echo(
366
+ FeedbackManager.error(
367
+ message=f"Deployment failed and {verb} deleted automatically. Deployment errors:"
368
+ )
369
+ )
370
+ for error in errors:
371
+ click.echo(FeedbackManager.error(message=f"* {error}"))
372
+ sys_exit(
373
+ "deployment_error", f"Deployment deleted after failure. Errors: {str(errors + (feedback or []))}"
374
+ )
361
375
 
362
376
  time.sleep(5)
363
377