tinybird-cli 5.20.1.dev1__tar.gz → 5.20.1.dev2__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 (48) hide show
  1. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/PKG-INFO +6 -1
  2. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/__cli__.py +2 -2
  3. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/ch_utils/constants.py +14 -0
  4. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/client.py +1 -1
  5. tinybird_cli-5.20.1.dev1/tinybird/datafile.py → tinybird_cli-5.20.1.dev2/tinybird/datafile_common.py +5 -3
  6. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/sql.py +11 -1
  7. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/sql_template.py +6 -2
  8. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/sql_toolset.py +39 -5
  9. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/auth.py +2 -3
  10. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/branch.py +3 -4
  11. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/cli.py +9 -11
  12. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/datasource.py +1 -1
  13. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/fmt.py +5 -3
  14. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/pipe.py +1 -1
  15. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/workspace.py +12 -13
  16. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird_cli.egg-info/PKG-INFO +6 -1
  17. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird_cli.egg-info/SOURCES.txt +1 -1
  18. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/setup.cfg +0 -0
  19. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/ch_utils/engine.py +0 -0
  20. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/check_pypi.py +0 -0
  21. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/config.py +0 -0
  22. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/connectors.py +0 -0
  23. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/context.py +0 -0
  24. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/datatypes.py +0 -0
  25. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/feedback_manager.py +0 -0
  26. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/git_settings.py +0 -0
  27. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/sql_template_fmt.py +0 -0
  28. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/syncasync.py +0 -0
  29. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli.py +0 -0
  30. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/cicd.py +0 -0
  31. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/common.py +0 -0
  32. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/config.py +0 -0
  33. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/connection.py +0 -0
  34. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/exceptions.py +0 -0
  35. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/job.py +0 -0
  36. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/regions.py +0 -0
  37. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/tag.py +0 -0
  38. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/telemetry.py +0 -0
  39. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/test.py +0 -0
  40. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  41. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  42. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/token.py +0 -0
  43. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  44. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird/tornado_template.py +0 -0
  45. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird_cli.egg-info/dependency_links.txt +0 -0
  46. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird_cli.egg-info/entry_points.txt +0 -0
  47. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird_cli.egg-info/requires.txt +0 -0
  48. {tinybird_cli-5.20.1.dev1 → tinybird_cli-5.20.1.dev2}/tinybird_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird_cli
3
- Version: 5.20.1.dev1
3
+ Version: 5.20.1.dev2
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli
6
6
  Author: Tinybird
@@ -61,6 +61,11 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
61
61
  Changelog
62
62
  ----------
63
63
 
64
+ 5.20.1.dev2
65
+ ***********
66
+
67
+ - `Fixed` Templating when using `id` parameter and the value was not provided.
68
+
64
69
  5.20.1.dev1
65
70
  ***********
66
71
 
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
4
4
  __url__ = 'https://www.tinybird.co/docs/cli'
5
5
  __author__ = 'Tinybird'
6
6
  __author_email__ = 'support@tinybird.co'
7
- __version__ = '5.20.1.dev1'
8
- __revision__ = '6ec3b53'
7
+ __version__ = '5.20.1.dev2'
8
+ __revision__ = 'afe97eb'
@@ -242,3 +242,17 @@ FORBIDDEN_SQL_KEYWORDS = {
242
242
 
243
243
  CH_SETTINGS_JOIN_ALGORITHM_HASH = "hash" # uses 'hash' by default, https://clickhouse.com/docs/en/operations/settings/settings/#settings-join_algorithm
244
244
  CH_SETTINGS_JOIN_ALGORITHM_AUTO = "auto,hash"
245
+
246
+ VALID_QUERY_FORMATS = (
247
+ "JSON",
248
+ "CSV",
249
+ "CSVWithNames",
250
+ "TSV",
251
+ "TSVWithNames",
252
+ "PrettyCompact",
253
+ "JSONEachRow",
254
+ "Parquet",
255
+ "JSONStrings",
256
+ "Prometheus",
257
+ "Native",
258
+ )
@@ -552,7 +552,7 @@ class TinyB:
552
552
  async def analyze_pipe_node(
553
553
  self, pipe_name: str, node: Dict[str, Any], dry_run: str = "false", datasource_name: Optional[str] = None
554
554
  ):
555
- params = {**{"include_datafile": "true", "dry_run": dry_run}, **node.get("params", node)}
555
+ params = {"include_datafile": "true", "dry_run": dry_run, **node.get("params", node)}
556
556
  if "mode" in params:
557
557
  params.pop("mode")
558
558
  node_name = node["params"]["name"] if node.get("params", None) else node["name"]
@@ -395,7 +395,7 @@ class CLIGitRelease:
395
395
 
396
396
  def is_head_outdated(self, current_ws_commit: str) -> bool:
397
397
  try:
398
- return self.repo.is_ancestor(current_ws_commit, self.head_commit())
398
+ return self.repo.is_ancestor(current_ws_commit, self.head().commit) # type: ignore
399
399
  except GitCommandError:
400
400
  raise CLIGitReleaseException(
401
401
  FeedbackManager.error_in_git_ancestor_commits(
@@ -405,7 +405,9 @@ class CLIGitRelease:
405
405
 
406
406
  def has_untracked_files(self) -> bool:
407
407
  current_pwd = os.getcwd()
408
- working_dir = f"{self.repo.working_dir}/" if os.getcwd() != self.repo.working_dir else self.repo.working_dir
408
+ working_dir = (
409
+ f"{self.repo.working_dir}/" if os.getcwd() != self.repo.working_dir else str(self.repo.working_dir)
410
+ )
409
411
  project_path = current_pwd[current_pwd.startswith(working_dir) and len(working_dir) :]
410
412
  for untracked_file in self.repo.untracked_files:
411
413
  for path in PROJECT_PATHS:
@@ -426,7 +428,7 @@ class CLIGitRelease:
426
428
  return self.head().commit.hexsha != current_ws_commit
427
429
 
428
430
  def diff(self, current_ws_commit: str) -> List[Diff]:
429
- return self.repo.commit(current_ws_commit).diff(self.head(), paths=self.paths)
431
+ return self.repo.commit(current_ws_commit).diff(self.head().commit, paths=self.paths)
430
432
 
431
433
  def diff_datafiles(self, current_ws_commit: str) -> List[Diff]:
432
434
  # ignore diffs if:
@@ -67,8 +67,18 @@ class TableIndex:
67
67
  if index_supported_types:
68
68
  for supported_type in INDEX_SUPPORTED_TYPES.get(index_supported_types, []):
69
69
  # Convert supported type to regex pattern
70
- # Replace * with \d+ to match any number
71
70
  pattern = supported_type.replace("*", r"\d+")
71
+
72
+ # Special handling for complex types that can have parameters
73
+ if supported_type == "Array":
74
+ pattern = r"Array\(.*\)"
75
+ elif supported_type == "Map":
76
+ pattern = r"Map\(.*\)"
77
+ elif supported_type == "LowCardinality":
78
+ pattern = r"LowCardinality\(.*\)"
79
+ elif supported_type == "Nullable":
80
+ pattern = r"Nullable\(.*\)"
81
+
72
82
  if re.match(f"^{pattern}$", col_type):
73
83
  return
74
84
  raise ValueError(
@@ -435,8 +435,10 @@ def sql_unescape(x, what=""):
435
435
  "'testing%'"
436
436
  >>> sql_unescape('testing%', '$')
437
437
  "'testing\\\\%'"
438
+ >>> sql_unescape('testing"')
439
+ '\\'testing"\\''
438
440
  """
439
- return Expression("'" + sqlescape(x).replace(f"\\{what}", what) + "'")
441
+ return Expression("'" + sqlescape_for_string_expression(x).replace(f"\\{what}", what) + "'")
440
442
 
441
443
 
442
444
  def split_to_array(x, default="", separator: str = ","):
@@ -1386,6 +1388,7 @@ _namespace = {
1386
1388
  "close": None,
1387
1389
  "print": None,
1388
1390
  "input": None,
1391
+ "id": None,
1389
1392
  }
1390
1393
 
1391
1394
 
@@ -2018,6 +2021,7 @@ def render_sql_template(
2018
2021
  test_mode: bool = False,
2019
2022
  name: Optional[str] = None,
2020
2023
  local_variables: Optional[dict] = None,
2024
+ secrets_in_test_mode: Optional[bool] = True,
2021
2025
  ) -> Tuple[str, TemplateExecutionResults, list]:
2022
2026
  """
2023
2027
  >>> render_sql_template("select * from table where f = {{Float32(foo)}}", { 'foo': -1 })
@@ -2300,7 +2304,7 @@ def render_sql_template(
2300
2304
  if secrets:
2301
2305
  v.update({"tb_secrets": secrets})
2302
2306
 
2303
- if is_tb_secret:
2307
+ if is_tb_secret and secrets_in_test_mode:
2304
2308
  v.update({TB_SECRET_IN_TEST_MODE: None})
2305
2309
 
2306
2310
  v.update(type_fns_check)
@@ -227,25 +227,56 @@ def sql_get_used_tables(
227
227
 
228
228
 
229
229
  class ReplacementsDict(dict):
230
+ def __init__(self, *args, enabled_table_functions=None, **kwargs):
231
+ self.enabled_table_functions = enabled_table_functions
232
+ super().__init__(*args, **kwargs)
233
+
230
234
  def __getitem__(self, key):
231
235
  v = super().__getitem__(key)
232
236
  if isinstance(v, tuple):
233
237
  k, r = v
234
238
  if callable(r):
235
- r = r()
239
+ r = update_callable_signature(r)(self.enabled_table_functions)
236
240
  super().__setitem__(key, (k, r))
237
241
  return k, r
238
242
  if callable(v):
239
- v = v()
243
+ v = update_callable_signature(v)(self.enabled_table_functions)
240
244
  super().__setitem__(key, v)
241
245
  return v
242
246
 
243
247
 
244
- def tables_or_sql(replacement: dict, table_functions=False) -> set:
248
+ def update_callable_signature(func):
249
+ """
250
+ Utility function to provide backward compatibility for callable functions
251
+ that don't accept the enabled_table_functions parameter.
252
+ """
253
+ if callable(func):
254
+
255
+ def wrapper(enabled_table_functions=None):
256
+ # Check if the function accepts the enabled_table_functions parameter
257
+ import inspect
258
+
259
+ sig = inspect.signature(func)
260
+ if len(sig.parameters) == 0:
261
+ # Old-style callable with no parameters
262
+ return func()
263
+ else:
264
+ # New-style callable that accepts enabled_table_functions
265
+ return func(enabled_table_functions)
266
+
267
+ return wrapper
268
+ return func
269
+
270
+
271
+ def tables_or_sql(replacement: dict, table_functions=False, function_allow_list=None) -> set:
245
272
  try:
246
273
  return set(
247
274
  sql_get_used_tables(
248
- replacement[1], default_database=replacement[0], raising=True, table_functions=table_functions
275
+ replacement[1],
276
+ default_database=replacement[0],
277
+ raising=True,
278
+ table_functions=table_functions,
279
+ function_allow_list=frozenset(function_allow_list),
249
280
  )
250
281
  )
251
282
  except Exception as e:
@@ -342,6 +373,7 @@ def replace_tables(
342
373
  _enabled_table_functions = ENABLED_TABLE_FUNCTIONS
343
374
  else:
344
375
  _enabled_table_functions = ENABLED_TABLE_FUNCTIONS.union(set(function_allow_list))
376
+ _replacements.enabled_table_functions = frozenset(_enabled_table_functions)
345
377
  while _tables:
346
378
  table = _tables.pop()
347
379
  if len(table) == 3:
@@ -355,7 +387,9 @@ def replace_tables(
355
387
  seen_tables.add(table)
356
388
  if table in _replacements:
357
389
  replacement = _replacements[table]
358
- dependent_tables = tables_or_sql(replacement, table_functions=check_functions)
390
+ dependent_tables = tables_or_sql(
391
+ replacement, table_functions=check_functions, function_allow_list=_enabled_table_functions
392
+ )
359
393
  deps[table] |= {(d[0], d[1]) for d in dependent_tables}
360
394
  for dependent_table in list(dependent_tables):
361
395
  if len(dependent_table) == 3:
@@ -74,9 +74,8 @@ async def auth(ctx: click.Context, token: str, host: str, region: str, connector
74
74
  # do a clean auth
75
75
  if not token and not ctx.parent.params.get("token") and not env_token:
76
76
  config.set_token(None)
77
- else:
78
- if env_token and not token:
79
- click.echo(FeedbackManager.info_reading_from_env(value="token", envvar="TB_TOKEN"))
77
+ elif env_token and not token:
78
+ click.echo(FeedbackManager.info_reading_from_env(value="token", envvar="TB_TOKEN"))
80
79
 
81
80
  regions: Optional[List[Region]] = None
82
81
  try_all_regions = True
@@ -11,7 +11,7 @@ import aiofiles
11
11
  import click
12
12
  import yaml
13
13
 
14
- from tinybird.datafile import create_release, wait_job
14
+ from tinybird.datafile_common import create_release, wait_job
15
15
  from tinybird.feedback_manager import FeedbackManager
16
16
  from tinybird.tb_cli_modules.cli import cli
17
17
  from tinybird.tb_cli_modules.common import (
@@ -597,9 +597,8 @@ async def regression_tests(
597
597
  await print_branch_regression_tests_summary(client, job_id, config["host"])
598
598
  except Exception as e:
599
599
  raise CLIBranchException(FeedbackManager.error_exception(error=str(e)))
600
- else:
601
- if not ctx.invoked_subcommand:
602
- await _run_regression(type="coverage", wait=wait, run_in_main=main)
600
+ elif not ctx.invoked_subcommand:
601
+ await _run_regression(type="coverage", wait=wait, run_in_main=main)
603
602
 
604
603
 
605
604
  async def _run_regression(
@@ -28,7 +28,7 @@ from tinybird.client import (
28
28
  TinyB,
29
29
  )
30
30
  from tinybird.config import CURRENT_VERSION, SUPPORTED_CONNECTORS, VERSION, FeatureFlags, get_config
31
- from tinybird.datafile import (
31
+ from tinybird.datafile_common import (
32
32
  AlreadyExistsException,
33
33
  CLIGitRelease,
34
34
  CLIGitReleaseException,
@@ -431,10 +431,9 @@ async def init(
431
431
  error = True
432
432
  else:
433
433
  click.echo(FeedbackManager.info_cicd_already_exists(provider=cicd_provider.name))
434
- else:
435
- if cicd:
436
- data_project_dir = os.path.relpath(folder, cli_git_release.working_dir())
437
- await init_cicd(client, path=cli_git_release.working_dir(), data_project_dir=data_project_dir)
434
+ elif cicd:
435
+ data_project_dir = os.path.relpath(folder, cli_git_release.working_dir())
436
+ await init_cicd(client, path=cli_git_release.working_dir(), data_project_dir=data_project_dir)
438
437
 
439
438
  if final_response:
440
439
  if error:
@@ -1463,12 +1462,11 @@ async def deploy(
1463
1462
  )
1464
1463
  else:
1465
1464
  click.echo(FeedbackManager.info_minor_patch_release_with_autopromote(version=new_version))
1466
- else:
1467
- if show_feedback:
1468
- if dry_run:
1469
- click.echo(FeedbackManager.info_dry_minor_patch_release_no_autopromote(version=new_version))
1470
- else:
1471
- click.echo(FeedbackManager.info_minor_patch_release_no_autopromote(version=new_version))
1465
+ elif show_feedback:
1466
+ if dry_run:
1467
+ click.echo(FeedbackManager.info_dry_minor_patch_release_no_autopromote(version=new_version))
1468
+ else:
1469
+ click.echo(FeedbackManager.info_minor_patch_release_no_autopromote(version=new_version))
1472
1470
  new_release = True
1473
1471
 
1474
1472
  if new_release:
@@ -20,7 +20,7 @@ from tinybird.tb_cli_modules.config import CLIConfig
20
20
  if TYPE_CHECKING:
21
21
  from tinybird.connectors import Connector
22
22
 
23
- from tinybird.datafile import get_name_version, wait_job
23
+ from tinybird.datafile_common import get_name_version, wait_job
24
24
  from tinybird.feedback_manager import FeedbackManager
25
25
  from tinybird.tb_cli_modules.branch import warn_if_in_live
26
26
  from tinybird.tb_cli_modules.cli import cli
@@ -7,7 +7,7 @@ import aiofiles
7
7
  import click
8
8
  from click import Context
9
9
 
10
- from tinybird.datafile import color_diff, format_datasource, format_pipe, is_file_a_datasource, peek
10
+ from tinybird.datafile_common import color_diff, format_datasource, format_pipe, is_file_a_datasource, peek
11
11
  from tinybird.feedback_manager import FeedbackManager
12
12
  from tinybird.tb_cli_modules.cli import cli
13
13
  from tinybird.tb_cli_modules.common import coro
@@ -29,10 +29,11 @@ from tinybird.tb_cli_modules.common import coro
29
29
  default=False,
30
30
  help="Formats local file, prints the diff and exits 1 if different, 0 if equal",
31
31
  )
32
+ @click.option("--no-color", is_flag=True, default=False, help="Don't colorize diff")
32
33
  @click.pass_context
33
34
  @coro
34
35
  async def fmt(
35
- ctx: Context, filenames: List[str], line_length: int, dry_run: bool, yes: bool, diff: bool
36
+ ctx: Context, filenames: List[str], line_length: int, dry_run: bool, yes: bool, diff: bool, no_color: bool
36
37
  ) -> Optional[str]:
37
38
  """
38
39
  Formats a .datasource, .pipe or .incl file
@@ -66,7 +67,8 @@ async def fmt(
66
67
  diff_result = difflib.unified_diff(
67
68
  lines_file, lines_fmt, fromfile=f"{Path(filename).name} local", tofile="fmt datafile"
68
69
  )
69
- diff_result = color_diff(diff_result)
70
+ if not no_color:
71
+ diff_result = color_diff(diff_result)
70
72
  not_empty, diff_lines = peek(diff_result)
71
73
  if not_empty:
72
74
  sys.stdout.writelines(diff_lines)
@@ -16,7 +16,7 @@ from click import Context
16
16
  import tinybird.context as context
17
17
  from tinybird.client import AuthNoTokenException, DoesNotExistException, TinyB
18
18
  from tinybird.config import DEFAULT_API_HOST, FeatureFlags
19
- from tinybird.datafile import PipeNodeTypes, PipeTypes, folder_push, get_name_version, process_file, wait_job
19
+ from tinybird.datafile_common import PipeNodeTypes, PipeTypes, folder_push, get_name_version, process_file, wait_job
20
20
  from tinybird.feedback_manager import FeedbackManager
21
21
  from tinybird.tb_cli_modules.branch import warn_if_in_live
22
22
  from tinybird.tb_cli_modules.cli import cli
@@ -10,7 +10,7 @@ from click import Context
10
10
 
11
11
  from tinybird.client import CanNotBeDeletedException, DoesNotExistException, TinyB
12
12
  from tinybird.config import get_display_host
13
- from tinybird.datafile import PipeTypes
13
+ from tinybird.datafile_common import PipeTypes
14
14
  from tinybird.feedback_manager import FeedbackManager
15
15
  from tinybird.tb_cli_modules.cli import cli
16
16
  from tinybird.tb_cli_modules.common import (
@@ -234,20 +234,19 @@ async def create_workspace(
234
234
  if not organization:
235
235
  raise CLIWorkspaceException(FeedbackManager.error_organization_not_found(organization_id=organization_id))
236
236
  organization_name = organization.get("name")
237
+ elif len(organizations) == 0:
238
+ click.echo(FeedbackManager.warning_none_organization(ui_host=ui_host))
239
+ elif len(organizations) == 1:
240
+ organization_id = organizations[0].get("id")
241
+ organization_name = organizations[0].get("name")
237
242
  else:
238
- if len(organizations) == 0:
239
- click.echo(FeedbackManager.warning_none_organization(ui_host=ui_host))
240
- elif len(organizations) == 1:
241
- organization_id = organizations[0].get("id")
242
- organization_name = organizations[0].get("name")
243
+ sorted_organizations = sort_organizations_by_user(organizations, user_email=config.get_user_email())
244
+ current_organization = await ask_for_organization_interactively(sorted_organizations)
245
+ if current_organization:
246
+ organization_id = current_organization.get("id")
247
+ organization_name = current_organization.get("name")
243
248
  else:
244
- sorted_organizations = sort_organizations_by_user(organizations, user_email=config.get_user_email())
245
- current_organization = await ask_for_organization_interactively(sorted_organizations)
246
- if current_organization:
247
- organization_id = current_organization.get("id")
248
- organization_name = current_organization.get("name")
249
- else:
250
- return
249
+ return
251
250
 
252
251
  # If we have at least workspace_name, we start the non interactive
253
252
  # process, creating an empty workspace
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird_cli
3
- Version: 5.20.1.dev1
3
+ Version: 5.20.1.dev2
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli
6
6
  Author: Tinybird
@@ -61,6 +61,11 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
61
61
  Changelog
62
62
  ----------
63
63
 
64
+ 5.20.1.dev2
65
+ ***********
66
+
67
+ - `Fixed` Templating when using `id` parameter and the value was not provided.
68
+
64
69
  5.20.1.dev1
65
70
  ***********
66
71
 
@@ -4,7 +4,7 @@ tinybird/client.py
4
4
  tinybird/config.py
5
5
  tinybird/connectors.py
6
6
  tinybird/context.py
7
- tinybird/datafile.py
7
+ tinybird/datafile_common.py
8
8
  tinybird/datatypes.py
9
9
  tinybird/feedback_manager.py
10
10
  tinybird/git_settings.py