tinybird 0.0.1.dev291__tar.gz → 0.0.1.dev293__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.

Potentially problematic release.


This version of tinybird might be problematic. Click here for more details.

Files changed (150) hide show
  1. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/PKG-INFO +1 -1
  2. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/context.py +3 -2
  3. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/datafile/parse_pipe.py +2 -2
  4. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/sql_template.py +11 -3
  5. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/__cli__.py +2 -2
  6. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/agent.py +10 -0
  7. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/explore_agent.py +5 -0
  8. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/mock_agent.py +5 -1
  9. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/prompts.py +49 -2
  10. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/run_command.py +9 -0
  11. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/build.py +143 -1
  12. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/feedback_manager.py +1 -1
  13. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird.egg-info/PKG-INFO +1 -1
  14. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/setup.cfg +0 -0
  15. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/__cli__.py +0 -0
  16. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/ch_utils/constants.py +0 -0
  17. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/ch_utils/engine.py +0 -0
  18. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/check_pypi.py +0 -0
  19. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/client.py +0 -0
  20. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/config.py +0 -0
  21. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/connectors.py +0 -0
  22. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/datafile/common.py +0 -0
  23. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/datafile/exceptions.py +0 -0
  24. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/datafile/parse_connection.py +0 -0
  25. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/datafile/parse_datasource.py +0 -0
  26. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/datatypes.py +0 -0
  27. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/feedback_manager.py +0 -0
  28. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/git_settings.py +0 -0
  29. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/prompts.py +0 -0
  30. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/service_datasources.py +0 -0
  31. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/sql.py +0 -0
  32. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/sql_template_fmt.py +0 -0
  33. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/sql_toolset.py +0 -0
  34. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/syncasync.py +0 -0
  35. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/check_pypi.py +0 -0
  36. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/cli.py +0 -0
  37. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/client.py +0 -0
  38. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/config.py +0 -0
  39. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/__init__.py +0 -0
  40. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/animations.py +0 -0
  41. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/banner.py +0 -0
  42. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/command_agent.py +0 -0
  43. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/compactor.py +0 -0
  44. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/file_agent.py +0 -0
  45. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/memory.py +0 -0
  46. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/models.py +0 -0
  47. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/testing_agent.py +0 -0
  48. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/__init__.py +0 -0
  49. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/analyze.py +0 -0
  50. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/append.py +0 -0
  51. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/build.py +0 -0
  52. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/datafile.py +0 -0
  53. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/deploy.py +0 -0
  54. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/deploy_check.py +0 -0
  55. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/diff_resource.py +0 -0
  56. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/execute_query.py +0 -0
  57. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/file.py +0 -0
  58. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/get_endpoint_stats.py +0 -0
  59. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/get_openapi_definition.py +0 -0
  60. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/mock.py +0 -0
  61. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/plan.py +0 -0
  62. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/request_endpoint.py +0 -0
  63. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/secret.py +0 -0
  64. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/tools/test.py +0 -0
  65. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/agent/utils.py +0 -0
  66. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/build_common.py +0 -0
  67. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/cicd.py +0 -0
  68. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/cli.py +0 -0
  69. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/common.py +0 -0
  70. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/config.py +0 -0
  71. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/connection.py +0 -0
  72. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/copy.py +0 -0
  73. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/create.py +0 -0
  74. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/build.py +0 -0
  75. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/build_common.py +0 -0
  76. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  77. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  78. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/diff.py +0 -0
  79. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/fixture.py +0 -0
  80. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/format_common.py +0 -0
  81. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  82. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  83. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  84. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/playground.py +0 -0
  85. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datafile/pull.py +0 -0
  86. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/datasource.py +0 -0
  87. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/deployment.py +0 -0
  88. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/deployment_common.py +0 -0
  89. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/deprecations.py +0 -0
  90. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/dev_server.py +0 -0
  91. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/endpoint.py +0 -0
  92. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/exceptions.py +0 -0
  93. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/info.py +0 -0
  94. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/infra.py +0 -0
  95. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/job.py +0 -0
  96. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/llm.py +0 -0
  97. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/llm_utils.py +0 -0
  98. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/local.py +0 -0
  99. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/local_common.py +0 -0
  100. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/login.py +0 -0
  101. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/login_common.py +0 -0
  102. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/logout.py +0 -0
  103. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/materialization.py +0 -0
  104. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/mock.py +0 -0
  105. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/mock_common.py +0 -0
  106. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/open.py +0 -0
  107. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/pipe.py +0 -0
  108. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/project.py +0 -0
  109. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/regions.py +0 -0
  110. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/secret.py +0 -0
  111. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/secret_common.py +0 -0
  112. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/shell.py +0 -0
  113. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/sink.py +0 -0
  114. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/table.py +0 -0
  115. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/telemetry.py +0 -0
  116. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/test.py +0 -0
  117. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/test_common.py +0 -0
  118. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  119. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  120. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/token.py +0 -0
  121. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/watch.py +0 -0
  122. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/workspace.py +0 -0
  123. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb/modules/workspace_members.py +0 -0
  124. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli.py +0 -0
  125. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/auth.py +0 -0
  126. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/branch.py +0 -0
  127. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/cicd.py +0 -0
  128. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/cli.py +0 -0
  129. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/common.py +0 -0
  130. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/config.py +0 -0
  131. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/connection.py +0 -0
  132. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/datasource.py +0 -0
  133. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/exceptions.py +0 -0
  134. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/fmt.py +0 -0
  135. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/job.py +0 -0
  136. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/pipe.py +0 -0
  137. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/regions.py +0 -0
  138. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/tag.py +0 -0
  139. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/telemetry.py +0 -0
  140. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/test.py +0 -0
  141. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  142. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  143. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/workspace.py +0 -0
  144. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  145. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird/tornado_template.py +0 -0
  146. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird.egg-info/SOURCES.txt +0 -0
  147. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird.egg-info/dependency_links.txt +0 -0
  148. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird.egg-info/entry_points.txt +0 -0
  149. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/tinybird.egg-info/requires.txt +0 -0
  150. {tinybird-0.0.1.dev291 → tinybird-0.0.1.dev293}/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.dev291
3
+ Version: 0.0.1.dev293
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -3,10 +3,11 @@ from typing import TYPE_CHECKING
3
3
 
4
4
  # Avoid circular import error
5
5
  if TYPE_CHECKING:
6
- from tinybird.user import User
6
+ from hfi.hfi_workspace_data import HfiWorkspaceData
7
+
7
8
 
8
9
  workspace_id: ContextVar[str] = ContextVar("workspace_id")
9
- workspace: ContextVar["User"] = ContextVar("workspace")
10
+ hfi_workspace_data: ContextVar["HfiWorkspaceData"] = ContextVar("hfi_workspace_data")
10
11
  table_id: ContextVar[str] = ContextVar("table_id")
11
12
  hfi_frequency: ContextVar[float] = ContextVar("hfi_frequency")
12
13
  hfi_frequency_gatherer: ContextVar[float] = ContextVar("hfi_frequency_gatherer")
@@ -11,7 +11,7 @@ from tinybird.datafile.common import (
11
11
  parse,
12
12
  )
13
13
  from tinybird.datafile.exceptions import IncludeFileNotFoundException, ParseException
14
- from tinybird.sql_template import get_template_and_variables, render_sql_template, secret_template_key
14
+ from tinybird.sql_template import get_template_and_variables, render_sql_template
15
15
  from tinybird.tb.modules.feedback_manager import FeedbackManager
16
16
  from tinybird.tornado_template import UnClosedIfError
17
17
 
@@ -54,7 +54,7 @@ def parse_pipe(
54
54
  if sql.strip()[0] == "%":
55
55
  secrets_list: Optional[List[str]] = None
56
56
  if secrets:
57
- secrets_list = [f"{secret_template_key(secret)}" for secret in secrets.keys()]
57
+ secrets_list = list(secrets.keys())
58
58
  # Setting test_mode=True to ignore errors on required parameters and
59
59
  # secrets_in_test_mode=False to raise errors on missing secrets
60
60
  sql, _, variable_warnings = render_sql_template(
@@ -1405,8 +1405,11 @@ def generate(self, **kwargs) -> Tuple[str, TemplateExecutionResults]:
1405
1405
  namespace = {}
1406
1406
  template_execution_results = TemplateExecutionResults()
1407
1407
  for key in kwargs.get("tb_secrets", []):
1408
+ # Avoid double-prefixing if the key already has the tb_secret_ prefix
1408
1409
  if is_secret_template_key(key):
1409
1410
  template_execution_results.add_template_param(key)
1411
+ else:
1412
+ template_execution_results.add_template_param(secret_template_key(key))
1410
1413
 
1411
1414
  if TB_SECRET_IN_TEST_MODE in kwargs:
1412
1415
  template_execution_results[TB_SECRET_IN_TEST_MODE] = None
@@ -1415,15 +1418,20 @@ def generate(self, **kwargs) -> Tuple[str, TemplateExecutionResults]:
1415
1418
  try:
1416
1419
  key = secret_template_key(x)
1417
1420
  if key in template_execution_results.template_params:
1421
+ # secret available: Always use workspace secret regardless of test mode
1418
1422
  template_execution_results.add_ch_param(x)
1419
1423
  return Symbol("{" + sqlescape(x) + ": String}")
1420
1424
  else:
1425
+ # secret not available: Check test mode and defaults
1421
1426
  is_test_mode = TB_SECRET_IN_TEST_MODE in template_execution_results
1422
- if is_test_mode and default is None:
1423
- return Symbol("{" + sqlescape(x) + ": String}")
1424
- elif default is not None:
1427
+ if default is not None:
1428
+ # Use provided default value
1425
1429
  return default
1430
+ elif is_test_mode:
1431
+ # In test mode without default - return placeholder
1432
+ return Symbol("{" + sqlescape(x) + ": String}")
1426
1433
  else:
1434
+ # Not in test mode, no secret, no default - raise error
1427
1435
  raise SQLTemplateException(
1428
1436
  f"Cannot access secret '{x}'. Check the secret exists in the Workspace and the token has the required scope."
1429
1437
  )
@@ -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.dev291'
8
- __revision__ = '87da698'
7
+ __version__ = '0.0.1.dev293'
8
+ __revision__ = '8c3de05'
@@ -34,10 +34,12 @@ from tinybird.tb.modules.agent.mock_agent import MockAgent
34
34
  from tinybird.tb.modules.agent.models import create_model
35
35
  from tinybird.tb.modules.agent.prompts import (
36
36
  agent_system_prompt,
37
+ fixtures_prompt,
37
38
  load_custom_project_rules,
38
39
  resources_prompt,
39
40
  secrets_prompt,
40
41
  service_datasources_prompt,
42
+ vendor_files_prompt,
41
43
  )
42
44
  from tinybird.tb.modules.agent.testing_agent import TestingAgent
43
45
  from tinybird.tb.modules.agent.tools.analyze import analyze_file, analyze_url
@@ -322,6 +324,14 @@ class TinybirdAgent:
322
324
  def get_project_files(ctx: RunContext[TinybirdAgentContext]) -> str:
323
325
  return resources_prompt(self.project)
324
326
 
327
+ @self.agent.instructions
328
+ def get_vendor_files(ctx: RunContext[TinybirdAgentContext]) -> str:
329
+ return vendor_files_prompt(self.project)
330
+
331
+ @self.agent.instructions
332
+ def get_fixture_files(ctx: RunContext[TinybirdAgentContext]) -> str:
333
+ return fixtures_prompt(self.project)
334
+
325
335
  @self.agent.instructions
326
336
  def get_service_datasources(ctx: RunContext[TinybirdAgentContext]) -> str:
327
337
  return service_datasources_prompt()
@@ -12,6 +12,7 @@ from tinybird.tb.modules.agent.prompts import (
12
12
  resources_prompt,
13
13
  service_datasources_prompt,
14
14
  tone_and_style_instructions,
15
+ vendor_files_prompt,
15
16
  )
16
17
  from tinybird.tb.modules.agent.tools.diff_resource import diff_resource
17
18
  from tinybird.tb.modules.agent.tools.execute_query import execute_query
@@ -76,6 +77,10 @@ Once you finish the task, return a valid response for the task to complete.
76
77
  def get_project_files(ctx: RunContext[TinybirdAgentContext]) -> str:
77
78
  return resources_prompt(self.project)
78
79
 
80
+ @self.agent.instructions
81
+ def get_vendor_files(ctx: RunContext[TinybirdAgentContext]) -> str:
82
+ return vendor_files_prompt(self.project)
83
+
79
84
  @self.agent.instructions
80
85
  def get_service_datasources(ctx: RunContext[TinybirdAgentContext]) -> str:
81
86
  return service_datasources_prompt()
@@ -6,7 +6,7 @@ from pydantic_ai.usage import Usage
6
6
 
7
7
  from tinybird.tb.modules.agent.animations import ThinkingAnimation
8
8
  from tinybird.tb.modules.agent.models import create_model
9
- from tinybird.tb.modules.agent.prompts import resources_prompt
9
+ from tinybird.tb.modules.agent.prompts import fixtures_prompt, resources_prompt
10
10
  from tinybird.tb.modules.agent.tools.mock import generate_mock_fixture
11
11
  from tinybird.tb.modules.agent.utils import TinybirdAgentContext
12
12
  from tinybird.tb.modules.project import Project
@@ -194,6 +194,10 @@ Today is {datetime.now().strftime("%Y-%m-%d")}
194
194
  def get_project_files(ctx: RunContext[TinybirdAgentContext]) -> str:
195
195
  return resources_prompt(self.project)
196
196
 
197
+ @self.agent.instructions
198
+ def get_fixture_files(ctx: RunContext[TinybirdAgentContext]) -> str:
199
+ return fixtures_prompt(self.project)
200
+
197
201
  def run(self, task: str, deps: TinybirdAgentContext, usage: Usage):
198
202
  result = self.agent.run_sync(
199
203
  task,
@@ -35,8 +35,10 @@ available_commands = [
35
35
  "`tb sink ls`: List all sinks",
36
36
  "`tb workspace current`: Show the current workspace",
37
37
  "`tb workspace clear --yes`: Delete all resources in the workspace (Only available in Tinybird Local)",
38
+ "`tb workspace ls`: List all workspaces",
38
39
  "`tb local start --skip-new-version`: Start Tinybird Local container in non-interactive mode",
39
40
  "`tb local restart --skip-new-version --yes`: Restart Tinybird Local container in non-interactive mode",
41
+ "`tb pull --only-vendored`: Pull only the vendored datasources from other workspaces",
40
42
  ]
41
43
 
42
44
  plan_instructions = """
@@ -166,7 +168,6 @@ SQL >
166
168
 
167
169
  def resources_prompt(project: Project) -> str:
168
170
  files = project.get_project_files()
169
- fixture_files = project.get_fixture_files()
170
171
 
171
172
  resources_content = "# Existing resources in the project:\n"
172
173
  if files:
@@ -184,7 +185,36 @@ def resources_prompt(project: Project) -> str:
184
185
  else:
185
186
  resources_content += "No resources found"
186
187
 
188
+ return resources_content
189
+
190
+
191
+ def vendor_files_prompt(project: Project) -> str:
192
+ files = project.get_vendored_files()
193
+ content = "# Datasources shared from other workspaces:\n"
194
+ if files:
195
+ resources: list[dict[str, Any]] = []
196
+ for filename in files:
197
+ file_path = Path(filename)
198
+ workspace_name = file_path.parent.parent.name
199
+ resource = {
200
+ "path": str(file_path.relative_to(project.folder)),
201
+ "type": get_resource_type(file_path),
202
+ "name": f"{workspace_name}.{file_path.stem}",
203
+ "content": file_path.read_text(),
204
+ "origin_workspace": workspace_name,
205
+ }
206
+ resources.append(resource)
207
+ content += format_as_xml(resources, root_tag="resources", item_tag="resource")
208
+ else:
209
+ content += "No datasources shared from other workspaces"
210
+
211
+ return content
212
+
213
+
214
+ def fixtures_prompt(project: Project) -> str:
215
+ fixture_files = project.get_fixture_files()
187
216
  fixture_content = "# Fixture files in the project:\n"
217
+
188
218
  if fixture_files:
189
219
  fixtures: list[dict[str, Any]] = []
190
220
  for filename in fixture_files:
@@ -199,7 +229,7 @@ def resources_prompt(project: Project) -> str:
199
229
  else:
200
230
  fixture_content += "No fixture files found"
201
231
 
202
- return resources_content + "\n" + fixture_content
232
+ return fixture_content
203
233
 
204
234
 
205
235
  def service_datasources_prompt() -> str:
@@ -954,6 +984,23 @@ After changes have been deployed and promoted, if you want to deploy other chang
954
984
  If after running a deployment, the error contains a recommended forward query, use it to update the .datasource file.
955
985
  </dev_notes>
956
986
 
987
+ ## Sharing datasources with other workspaces
988
+ To share a Data Source, in the .datasource file you want to share, add the destination workspace(s). For example:
989
+
990
+ ```
991
+ SHARED_WITH >
992
+ destination_workspace,
993
+ other_destination_workspace
994
+ ```
995
+
996
+ ## Working with shared datasources:
997
+
998
+ The following limitations apply to shared datasources:
999
+ - Shared datasources are read-only.
1000
+ - You can't share a shared datasource, only the original.
1001
+ - You can't check the quarantine of a shared datasource.
1002
+ - You can't create a Materialized View from a shared datasource.
1003
+
957
1004
  # Working with any type of pipe file:
958
1005
  {pipe_instructions}
959
1006
  {pipe_example}
@@ -3,6 +3,7 @@ import subprocess
3
3
  import click
4
4
  from pydantic_ai import RunContext
5
5
 
6
+ from tinybird.tb.modules.agent.prompts import available_commands
6
7
  from tinybird.tb.modules.agent.utils import (
7
8
  AgentRunCancelled,
8
9
  SubAgentRunCancelled,
@@ -20,6 +21,14 @@ def run_command(ctx: RunContext[TinybirdAgentContext], command: str):
20
21
  command (str): The command to run. Required. Examples: `tb --local sql "select 1"`, `tb --cloud datasource ls`, `tb --help`
21
22
  """
22
23
  try:
24
+ clean_commands = [cmd.split(":")[0].replace("`", "").split("[")[0] for cmd in available_commands]
25
+ available_commands_to_cloud = [f"tb --cloud {command.replace('tb ', '')}" for command in clean_commands]
26
+ available_commands_to_local = [f"tb --local {command.replace('tb ', '')}" for command in clean_commands]
27
+ all_commands = clean_commands + available_commands_to_cloud + available_commands_to_local
28
+
29
+ if not any(cmd.startswith(command) for cmd in all_commands):
30
+ raise SubAgentRunCancelled(f"Command {command} not found in the list of available commands")
31
+
23
32
  ctx.deps.thinking_animation.stop()
24
33
  force_confirmation = " deploy" in command.lower() or " truncate" in command.lower()
25
34
  confirmation = show_confirmation(
@@ -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
@@ -19,6 +19,7 @@ from tinybird.tb.modules.config import CLIConfig
19
19
  from tinybird.tb.modules.datafile.playground import folder_playground
20
20
  from tinybird.tb.modules.dev_server import BuildStatus, start_server
21
21
  from tinybird.tb.modules.feedback_manager import FeedbackManager
22
+ from tinybird.tb.modules.local_common import get_local_tokens
22
23
  from tinybird.tb.modules.project import Project
23
24
  from tinybird.tb.modules.shell import Shell, print_table_formatted
24
25
  from tinybird.tb.modules.watch import watch_files, watch_project
@@ -34,6 +35,7 @@ def build(ctx: click.Context, watch: bool) -> None:
34
35
  obj: Dict[str, Any] = ctx.ensure_object(dict)
35
36
  project: Project = ctx.ensure_object(dict)["project"]
36
37
  tb_client: TinyB = ctx.ensure_object(dict)["client"]
38
+ config: Dict[str, Any] = ctx.ensure_object(dict)["config"]
37
39
  if obj["env"] == "cloud":
38
40
  raise click.ClickException(FeedbackManager.error_build_only_supported_in_local())
39
41
 
@@ -46,6 +48,12 @@ def build(ctx: click.Context, watch: bool) -> None:
46
48
  )
47
49
  )
48
50
 
51
+ # First, build vendored workspaces if present
52
+
53
+ build_vendored_workspaces(project=project, tb_client=tb_client, config=config)
54
+ # Ensure SHARED_WITH workspaces exist before building and sharing
55
+ build_shared_with_workspaces(project=project, tb_client=tb_client, config=config)
56
+
49
57
  click.echo(FeedbackManager.highlight_building_project())
50
58
  process(project=project, tb_client=tb_client, watch=False)
51
59
  if watch:
@@ -65,6 +73,7 @@ def dev(ctx: click.Context, data_origin: str, ui: bool) -> None:
65
73
  return dev_cloud(ctx)
66
74
  project: Project = ctx.ensure_object(dict)["project"]
67
75
  tb_client: TinyB = ctx.ensure_object(dict)["client"]
76
+ config: Dict[str, Any] = ctx.ensure_object(dict)["config"]
68
77
  build_status = BuildStatus()
69
78
  if ui:
70
79
  server_thread = threading.Thread(
@@ -74,6 +83,11 @@ def dev(ctx: click.Context, data_origin: str, ui: bool) -> None:
74
83
  # Wait for the server to start
75
84
  time.sleep(0.5)
76
85
 
86
+ # Build vendored workspaces before starting dev build/watch
87
+ build_vendored_workspaces(project=project, tb_client=tb_client, config=config)
88
+ # Ensure SHARED_WITH workspaces exist before dev build/watch
89
+ build_shared_with_workspaces(project=project, tb_client=tb_client, config=config)
90
+
77
91
  click.echo(FeedbackManager.highlight_building_project())
78
92
  process(project=project, tb_client=tb_client, watch=True, build_status=build_status)
79
93
  run_watch(
@@ -127,6 +141,134 @@ def check_filenames(filenames: List[str]):
127
141
  parser(filename)
128
142
 
129
143
 
144
+ def find_workspace_or_create(user_client: TinyB, workspace_name: str) -> Optional[str]:
145
+ # Get a client scoped to the vendored workspace using the user token
146
+ ws_token = None
147
+ org_id = None
148
+ try:
149
+ # Fetch org id and workspaces with tokens
150
+ info = user_client.user_workspaces_with_organization(version="v1")
151
+ org_id = info.get("organization_id")
152
+ workspaces = info.get("workspaces", [])
153
+ found = next((w for w in workspaces if w.get("name") == workspace_name), None)
154
+ if found:
155
+ ws_token = found.get("token")
156
+ # If still not found, try the generic listing
157
+ if not ws_token:
158
+ workspaces_full = user_client.user_workspaces_and_branches(version="v1")
159
+ created_ws = next(
160
+ (w for w in workspaces_full.get("workspaces", []) if w.get("name") == workspace_name), None
161
+ )
162
+ if created_ws:
163
+ ws_token = created_ws.get("token")
164
+ except Exception:
165
+ ws_token = None
166
+
167
+ # If workspace doesn't exist, try to create it and fetch its token
168
+ if not ws_token:
169
+ try:
170
+ user_client.create_workspace(workspace_name, assign_to_organization_id=org_id, version="v1")
171
+ # Fetch token for newly created workspace
172
+ info_after = user_client.user_workspaces_and_branches(version="v1")
173
+ created = next((w for w in info_after.get("workspaces", []) if w.get("name") == workspace_name), None)
174
+ ws_token = created.get("token") if created else None
175
+ except Exception as e:
176
+ click.echo(
177
+ FeedbackManager.warning(
178
+ message=(f"Skipping vendored workspace '{workspace_name}': unable to create or resolve token ({e})")
179
+ )
180
+ )
181
+
182
+ return ws_token
183
+
184
+
185
+ def build_vendored_workspaces(project: Project, tb_client: TinyB, config: Dict[str, Any]) -> None:
186
+ """Build each vendored workspace under project.vendor_path if present.
187
+
188
+ Directory structure expected: vendor/<workspace_name>/<data_project_inside>
189
+ Each top-level directory under vendor is treated as a separate workspace
190
+ whose project files will be built using that workspace's token.
191
+ """
192
+ try:
193
+ vendor_root = Path(project.vendor_path)
194
+
195
+ if not vendor_root.exists() or not vendor_root.is_dir():
196
+ return
197
+
198
+ tokens = get_local_tokens()
199
+ user_token = tokens["user_token"]
200
+ user_client = deepcopy(tb_client)
201
+ user_client.token = user_token
202
+
203
+ # Iterate over vendored workspace folders
204
+ for ws_dir in sorted([p for p in vendor_root.iterdir() if p.is_dir()]):
205
+ workspace_name = ws_dir.name
206
+ ws_token = find_workspace_or_create(user_client, workspace_name)
207
+
208
+ if not ws_token:
209
+ click.echo(
210
+ FeedbackManager.warning(
211
+ message=f"Skipping vendored workspace '{workspace_name}': could not resolve token after creation"
212
+ )
213
+ )
214
+ continue
215
+
216
+ # Build using a client scoped to the vendor workspace token
217
+ vendor_client = deepcopy(tb_client)
218
+ vendor_client.token = ws_token
219
+ vendor_project = Project(folder=str(ws_dir), workspace_name=workspace_name, max_depth=project.max_depth)
220
+
221
+ # Do not exit on error to allow main project to continue
222
+ process(
223
+ project=vendor_project,
224
+ tb_client=vendor_client,
225
+ watch=False,
226
+ silent=False,
227
+ exit_on_error=True,
228
+ load_fixtures=True,
229
+ )
230
+ except Exception as e:
231
+ # Never break the main build due to vendored build errors
232
+ click.echo(FeedbackManager.error_exception(error=e))
233
+
234
+
235
+ def build_shared_with_workspaces(project: Project, tb_client: TinyB, config: Dict[str, Any]) -> None:
236
+ """Scan project for .datasource files and ensure SHARED_WITH workspaces exist."""
237
+
238
+ try:
239
+ # Gather SHARED_WITH workspace names from all .datasource files
240
+ datasource_files = project.get_datasource_files()
241
+ shared_ws_names = set()
242
+
243
+ for filename in datasource_files:
244
+ try:
245
+ doc = parse_datasource(filename).datafile
246
+ for ws_name in doc.shared_with or []:
247
+ shared_ws_names.add(ws_name)
248
+ except Exception:
249
+ # Ignore parse errors here; they'll be handled during the main process()
250
+ continue
251
+
252
+ if not shared_ws_names:
253
+ return
254
+
255
+ # Need a user token to list/create workspaces
256
+ tokens = get_local_tokens()
257
+ user_token = tokens.get("user_token")
258
+ if not user_token:
259
+ click.echo(FeedbackManager.info_skipping_shared_with_entry())
260
+ return
261
+
262
+ user_client = deepcopy(tb_client)
263
+ user_client.token = user_token
264
+
265
+ # Ensure each SHARED_WITH workspace exists
266
+ for ws_name in sorted(shared_ws_names):
267
+ find_workspace_or_create(user_client, ws_name)
268
+ except Exception as e:
269
+ click.echo(FeedbackManager.error_exception(error=e))
270
+
271
+
130
272
  def dev_cloud(
131
273
  ctx: click.Context,
132
274
  ) -> None:
@@ -1209,7 +1209,7 @@ STEP 3: ADD KEY TO SERVICE ACCOUNT
1209
1209
 
1210
1210
  debug_running_file = print_message("** Running {file}", bcolors.CGREY)
1211
1211
 
1212
- highlight_building_project = info_highlight_message("\n» Building project...")
1212
+ highlight_building_project = info_highlight_message("» Building project...")
1213
1213
 
1214
1214
  success = success_message("{message}")
1215
1215
  info = info_message("{message}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev291
3
+ Version: 0.0.1.dev293
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird