tinybird 4.5.11__tar.gz → 4.5.11.dev0__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 (127) hide show
  1. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/PKG-INFO +2 -8
  2. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/__cli__.py +2 -2
  3. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/client.py +3 -17
  4. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/branch.py +5 -14
  5. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/cli.py +3 -32
  6. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/common.py +14 -47
  7. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/connection.py +2 -23
  8. tinybird-4.5.11.dev0/tinybird/tb/modules/connection_kafka.py +433 -0
  9. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/create.py +11 -34
  10. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/build.py +5 -32
  11. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/feedback_manager.py +0 -3
  12. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/preview.py +2 -3
  13. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/connection.py +9 -80
  14. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird.egg-info/PKG-INFO +2 -8
  15. tinybird-4.5.11/tinybird/tb/modules/connection_kafka.py +0 -804
  16. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/setup.cfg +0 -0
  17. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/__cli__.py +0 -0
  18. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/ch_utils/constants.py +0 -0
  19. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/ch_utils/engine.py +0 -0
  20. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/check_pypi.py +0 -0
  21. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/client.py +0 -0
  22. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/config.py +0 -0
  23. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/context.py +0 -0
  24. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/datafile/common.py +0 -0
  25. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/datafile/exceptions.py +0 -0
  26. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/datafile/parse_connection.py +0 -0
  27. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/datafile/parse_datasource.py +0 -0
  28. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/datafile/parse_pipe.py +0 -0
  29. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/datatypes.py +0 -0
  30. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/feedback_manager.py +0 -0
  31. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/git_settings.py +0 -0
  32. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/prompts.py +0 -0
  33. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/service_datasources.py +0 -0
  34. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/sql.py +0 -0
  35. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/sql_template.py +0 -0
  36. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/sql_template_fmt.py +0 -0
  37. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/sql_toolset.py +0 -0
  38. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/syncasync.py +0 -0
  39. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/check_pypi.py +0 -0
  40. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/cli.py +0 -0
  41. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/config.py +0 -0
  42. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/build.py +0 -0
  43. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/build_common.py +0 -0
  44. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/cicd.py +0 -0
  45. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/config.py +0 -0
  46. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/connection_s3.py +0 -0
  47. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/copy.py +0 -0
  48. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/build_common.py +0 -0
  49. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  50. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  51. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/diff.py +0 -0
  52. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/fixture.py +0 -0
  53. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/format_common.py +0 -0
  54. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/format_connection.py +0 -0
  55. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  56. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  57. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  58. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/playground.py +0 -0
  59. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datafile/pull.py +0 -0
  60. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/datasource.py +0 -0
  61. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/deployment.py +0 -0
  62. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/deployment_common.py +0 -0
  63. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/deprecations.py +0 -0
  64. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/endpoint.py +0 -0
  65. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/exceptions.py +0 -0
  66. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/fmt.py +0 -0
  67. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/info.py +0 -0
  68. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/infra.py +0 -0
  69. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/job.py +0 -0
  70. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/job_common.py +0 -0
  71. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/llm.py +0 -0
  72. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/llm_utils.py +0 -0
  73. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/local.py +0 -0
  74. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/local_common.py +0 -0
  75. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/local_logs.py +0 -0
  76. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/login.py +0 -0
  77. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/login_common.py +0 -0
  78. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/logout.py +0 -0
  79. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/logs.py +0 -0
  80. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/materialization.py +0 -0
  81. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/open.py +0 -0
  82. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/pipe.py +0 -0
  83. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/project.py +0 -0
  84. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/project_commands.py +0 -0
  85. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/py_project.py +0 -0
  86. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/query_output.py +0 -0
  87. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/regions.py +0 -0
  88. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/secret.py +0 -0
  89. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/secret_common.py +0 -0
  90. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/sink.py +0 -0
  91. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/table.py +0 -0
  92. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/telemetry.py +0 -0
  93. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/test.py +0 -0
  94. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/test_common.py +0 -0
  95. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  96. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  97. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/token.py +0 -0
  98. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/ts_project.py +0 -0
  99. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/watch.py +0 -0
  100. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/workspace.py +0 -0
  101. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb/modules/workspace_members.py +0 -0
  102. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli.py +0 -0
  103. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/auth.py +0 -0
  104. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/branch.py +0 -0
  105. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/cicd.py +0 -0
  106. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/cli.py +0 -0
  107. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/common.py +0 -0
  108. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/config.py +0 -0
  109. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/datasource.py +0 -0
  110. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/exceptions.py +0 -0
  111. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/fmt.py +0 -0
  112. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/job.py +0 -0
  113. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/pipe.py +0 -0
  114. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/regions.py +0 -0
  115. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/tag.py +0 -0
  116. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/telemetry.py +0 -0
  117. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/test.py +0 -0
  118. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  119. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  120. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/workspace.py +0 -0
  121. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  122. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird/tornado_template.py +0 -0
  123. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird.egg-info/SOURCES.txt +0 -0
  124. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird.egg-info/dependency_links.txt +0 -0
  125. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird.egg-info/entry_points.txt +0 -0
  126. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird.egg-info/requires.txt +0 -0
  127. {tinybird-4.5.11 → tinybird-4.5.11.dev0}/tinybird.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 4.5.11
3
+ Version: 4.5.11.dev0
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -52,16 +52,10 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
52
52
  Changelog
53
53
  ----------
54
54
 
55
- 4.5.11
55
+ 4.5.10
56
56
  *******
57
57
 
58
- - `Added` `tb connection create kafka` now supports SASL ``OAUTHBEARER`` for Amazon MSK clusters with IAM-based authentication. The wizard asks up-front whether the user already has an IAM role for the cluster — if yes, it collects region + role ARN + external ID directly; if no, it walks the user through creating the IAM access policy and trust policy in the AWS Console, copying them to the clipboard.
59
- - `Added` ``--oauthbearer-aws-external-id`` flag (and matching interactive prompt) so users can supply a pre-shared external ID instead of the one Tinybird auto-generates for the connection.
60
- - `Added` ``PLAINTEXT`` security protocol now skips the SASL mechanism prompt entirely.
61
- - `Added` ``.connection`` files generated by the wizard now emit ``KAFKA_SASL_OAUTHBEARER_METHOD``, ``KAFKA_SASL_OAUTHBEARER_AWS_REGION``, ``KAFKA_SASL_OAUTHBEARER_AWS_ROLE_ARN``, and ``KAFKA_SASL_OAUTHBEARER_AWS_EXTERNAL_ID``, with the role ARN stored as a ``tb_secret``.
62
- - `Fixed` ``tb connection create kafka`` now accepts comma-separated bootstrap-server lists (e.g. ``b-1.kafka:9092,b-2.kafka:9092``) instead of rejecting them as malformed. Validation passes as soon as any one broker is reachable, matching Kafka bootstrap semantics.
63
58
  - `Fixed` `tb init` now persists `folder` in `tinybird.config.json`, so subsequent resource creation targets the configured project folder instead of the repository root.
64
- - `Fixed` Branch names derived from Git refs are now sanitized in `tb preview --name` and `tb branch create/rm/clear`, preventing CI/CD failures with invalid workspace names.
65
59
 
66
60
  4.5.9
67
61
  *******
@@ -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__ = '4.5.11'
8
- __revision__ = 'c7c08df'
7
+ __version__ = '4.5.11.dev0'
8
+ __revision__ = 'e0b2a62'
@@ -1010,29 +1010,16 @@ class TinyB:
1010
1010
  kafka_sasl_mechanism="PLAIN",
1011
1011
  kafka_security_protocol="SASL_SSL",
1012
1012
  kafka_ssl_ca_pem=None,
1013
- kafka_sasl_oauthbearer_method=None,
1014
- kafka_sasl_oauthbearer_aws_region=None,
1015
- kafka_sasl_oauthbearer_aws_role_arn=None,
1016
- kafka_sasl_oauthbearer_aws_external_id=None,
1017
1013
  ):
1018
- is_oauthbearer = kafka_sasl_mechanism == "OAUTHBEARER"
1019
1014
  params = {
1020
1015
  "service": "kafka",
1021
1016
  "kafka_security_protocol": kafka_security_protocol,
1022
1017
  "kafka_sasl_mechanism": kafka_sasl_mechanism,
1023
1018
  "kafka_bootstrap_servers": kafka_bootstrap_servers,
1019
+ "kafka_sasl_plain_username": kafka_key,
1020
+ "kafka_sasl_plain_password": kafka_secret,
1024
1021
  "name": kafka_connection_name,
1025
1022
  }
1026
- if is_oauthbearer:
1027
- params["kafka_sasl_oauthbearer_method"] = kafka_sasl_oauthbearer_method
1028
- params["kafka_sasl_oauthbearer_aws_region"] = kafka_sasl_oauthbearer_aws_region
1029
- params["kafka_sasl_oauthbearer_aws_role_arn"] = kafka_sasl_oauthbearer_aws_role_arn
1030
- # external_id is optional; the server fills it in from the workspace if absent.
1031
- if kafka_sasl_oauthbearer_aws_external_id:
1032
- params["kafka_sasl_oauthbearer_aws_external_id"] = kafka_sasl_oauthbearer_aws_external_id
1033
- else:
1034
- params["kafka_sasl_plain_username"] = kafka_key
1035
- params["kafka_sasl_plain_password"] = kafka_secret
1036
1023
 
1037
1024
  if kafka_schema_registry_url:
1038
1025
  params["kafka_schema_registry_url"] = kafka_schema_registry_url
@@ -1198,8 +1185,7 @@ class TinyB:
1198
1185
  def get_access_read_policy(self, service: str, bucket: Optional[str] = None) -> Dict[str, Any]:
1199
1186
  params = {}
1200
1187
  if bucket:
1201
- # The Kafka endpoint scopes the policy via `msk_cluster_arn`, not `bucket`.
1202
- params["msk_cluster_arn" if service == "kafka" else "bucket"] = bucket
1188
+ params["bucket"] = bucket
1203
1189
  return self._req(f"/v0/integrations/{service}/policies/read-access-policy?{urlencode(params)}")
1204
1190
 
1205
1191
  def sql_get_format(self, sql: str, with_clickhouse_format: bool = False) -> str:
@@ -7,7 +7,7 @@ from typing import Any, Dict, List, Optional, Tuple
7
7
 
8
8
  import click
9
9
 
10
- from tinybird.tb.modules.cli import _looks_like_uuid, cli, ensure_valid_workspace_name
10
+ from tinybird.tb.modules.cli import cli
11
11
  from tinybird.tb.modules.common import (
12
12
  MAIN_BRANCH,
13
13
  create_workspace_branch,
@@ -93,8 +93,7 @@ def branch_ls(sort: bool) -> None:
93
93
  help="Wait for data branch jobs to finish, showing a progress bar. Disabled by default.",
94
94
  )
95
95
  def create_branch(branch_name: Optional[str], last_partition: bool, ignore_datasources: List[str], wait: bool) -> None:
96
- normalized_branch_name = ensure_valid_workspace_name(branch_name) if branch_name else branch_name
97
- create_workspace_branch(normalized_branch_name, last_partition, False, list(ignore_datasources), wait)
96
+ create_workspace_branch(branch_name, last_partition, False, list(ignore_datasources), wait)
98
97
 
99
98
 
100
99
  @branch.command(name="rm", short_help="Removes an branch from the workspace. It can't be recovered.")
@@ -195,14 +194,11 @@ def clear_branch(
195
194
  if branch_name_or_id:
196
195
  if branch_name_or_id == MAIN_BRANCH:
197
196
  raise CLIException(FeedbackManager.error_not_allowed_in_main_branch())
198
- lookup_branch_name_or_id = (
199
- branch_name_or_id if _looks_like_uuid(branch_name_or_id) else ensure_valid_workspace_name(branch_name_or_id)
200
- )
201
197
  workspace_to_clear = next(
202
198
  (
203
199
  workspace
204
200
  for workspace in workspace_branches
205
- if workspace["name"] == lookup_branch_name_or_id or workspace["id"] == lookup_branch_name_or_id
201
+ if workspace["name"] == branch_name_or_id or workspace["id"] == branch_name_or_id
206
202
  ),
207
203
  None,
208
204
  )
@@ -214,16 +210,11 @@ def clear_branch(
214
210
  raise CLIBranchException(FeedbackManager.error_not_a_branch(cli=get_cli_name()))
215
211
 
216
212
  if not workspace_to_clear:
217
- raise CLIBranchException(
218
- FeedbackManager.error_branch(
219
- branch=lookup_branch_name_or_id if branch_name_or_id else "",
220
- cli=get_cli_name(),
221
- )
222
- )
213
+ raise CLIBranchException(FeedbackManager.error_branch(branch=branch_name_or_id or "", cli=get_cli_name()))
223
214
 
224
215
  branch_name = workspace_to_clear["name"]
225
216
  if yes or click.confirm(FeedbackManager.warning_confirm_clear_workspace()):
226
- was_current_branch = workspace_to_clear["id"] == config["id"]
217
+ was_current_branch = workspace_to_clear["id"] == config.get("id")
227
218
  client = config.get_client(token=current_main_workspace.get("token"))
228
219
  try:
229
220
  client.delete_branch(workspace_to_clear["id"])
@@ -68,7 +68,6 @@ PROJECT_TYPE_TYPESCRIPT = "ts-sdk"
68
68
  PROJECT_TYPE_PYTHON = "python-sdk"
69
69
  PROJECT_TYPE_CLI = "cli"
70
70
  PROJECT_TYPES = {PROJECT_TYPE_TYPESCRIPT, PROJECT_TYPE_PYTHON, PROJECT_TYPE_CLI}
71
- UUID_PATTERN = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", re.IGNORECASE)
72
71
 
73
72
 
74
73
  CLI_PROJECT_MARKERS = (
@@ -164,44 +163,16 @@ def is_main_git_branch(branch_name: Optional[str]) -> bool:
164
163
  return branch_name in {"main", "master"}
165
164
 
166
165
 
167
- def sanitize_branch_name(branch_name: str, *, enforce_workspace_prefix_rules: bool = True) -> str:
166
+ def sanitize_branch_name(branch_name: str) -> str:
168
167
  sanitized = re.sub(r"[^a-zA-Z0-9_]", "_", branch_name)
169
168
  sanitized = re.sub(r"_+", "_", sanitized)
170
- sanitized = sanitized.strip("_")
171
- if enforce_workspace_prefix_rules:
172
- if sanitized and sanitized[0].isdigit():
173
- sanitized = f"branch_{sanitized}"
174
- if sanitized.startswith("d_"):
175
- sanitized = f"branch_{sanitized}"
176
- return sanitized
177
-
178
-
179
- def _looks_like_uuid(value: str) -> bool:
180
- return bool(UUID_PATTERN.fullmatch(value))
181
-
182
-
183
- def ensure_valid_workspace_name(name: str, *, context: str = "Branch") -> str:
184
- sanitized = sanitize_branch_name(name)
185
- if not sanitized:
186
- raise CLIException(
187
- FeedbackManager.error(
188
- message=(
189
- f"{context} name '{name}' is not valid. "
190
- "Name must start with a letter and contain only letters, numbers, and underscores."
191
- )
192
- )
193
- )
194
-
195
- if sanitized != name:
196
- click.echo(FeedbackManager.warning_branch_name_sanitized(context=context, original=name, sanitized=sanitized))
197
-
198
- return sanitized
169
+ return sanitized.strip("_")
199
170
 
200
171
 
201
172
  def get_tinybird_branch_name_from_git_branch(branch_name: Optional[str]) -> Optional[str]:
202
173
  if not branch_name:
203
174
  return None
204
- sanitized = sanitize_branch_name(branch_name, enforce_workspace_prefix_rules=False)
175
+ sanitized = sanitize_branch_name(branch_name)
205
176
  return sanitized or None
206
177
 
207
178
 
@@ -1105,57 +1105,26 @@ def is_url_valid(url):
1105
1105
  return False
1106
1106
 
1107
1107
 
1108
- def _parse_kafka_host_port(entry: str) -> tuple[str, int]:
1109
- """Parse a single Kafka bootstrap entry of the form 'host' or 'host:port'.
1110
-
1111
- Raises CLIException on malformed input. Defaults the port to 9092 when omitted.
1112
- """
1113
- parts = entry.split(":")
1108
+ def validate_kafka_bootstrap_servers(host_and_port):
1109
+ if not isinstance(host_and_port, str):
1110
+ raise CLIException(FeedbackManager.error_kafka_bootstrap_server())
1111
+ parts = host_and_port.split(":")
1114
1112
  if len(parts) > 2:
1115
1113
  raise CLIException(FeedbackManager.error_kafka_bootstrap_server())
1116
1114
  host = parts[0]
1117
1115
  port_str = parts[1] if len(parts) == 2 else "9092"
1118
1116
  try:
1119
- return host, int(port_str)
1117
+ port = int(port_str)
1120
1118
  except Exception:
1121
1119
  raise CLIException(FeedbackManager.error_kafka_bootstrap_server())
1122
-
1123
-
1124
- def validate_kafka_bootstrap_servers(host_and_port):
1125
- """Validate a Kafka bootstrap-servers string (single entry or comma-separated list).
1126
-
1127
- Format is checked for every entry. Connectivity is then probed per entry — Kafka
1128
- only needs one reachable bootstrap broker to discover the rest of the cluster,
1129
- so the validator passes as long as at least one host accepts a TCP connection.
1130
- The last connection error is re-raised when every host is unreachable.
1131
- """
1132
- if not isinstance(host_and_port, str):
1133
- raise CLIException(FeedbackManager.error_kafka_bootstrap_server())
1134
-
1135
- entries = [e.strip() for e in host_and_port.split(",") if e.strip()]
1136
- if not entries:
1137
- raise CLIException(FeedbackManager.error_kafka_bootstrap_server())
1138
-
1139
- # Format-check every entry up front so the user hears about all bad ones at
1140
- # once rather than discovering them sequentially.
1141
- hosts = [_parse_kafka_host_port(e) for e in entries]
1142
-
1143
- last_error: Optional[CLIException] = None
1144
- for host, port in hosts:
1145
- with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
1146
- try:
1147
- sock.settimeout(3)
1148
- sock.connect((host, port))
1149
- return # at least one reachable broker is enough
1150
- except TimeoutError:
1151
- last_error = CLIException(
1152
- FeedbackManager.error_kafka_bootstrap_server_conn_timeout(host=host, port=port)
1153
- )
1154
- except Exception:
1155
- last_error = CLIException(FeedbackManager.error_kafka_bootstrap_server_conn(host=host, port=port))
1156
-
1157
- if last_error is not None:
1158
- raise last_error
1120
+ with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
1121
+ try:
1122
+ sock.settimeout(3)
1123
+ sock.connect((host, port))
1124
+ except TimeoutError:
1125
+ raise CLIException(FeedbackManager.error_kafka_bootstrap_server_conn_timeout(host=host, port=port))
1126
+ except Exception:
1127
+ raise CLIException(FeedbackManager.error_kafka_bootstrap_server_conn(host=host, port=port))
1159
1128
 
1160
1129
 
1161
1130
  def validate_kafka_key(s):
@@ -1168,11 +1137,9 @@ def validate_kafka_secret(s):
1168
1137
  raise CLIException("Password format is not correct, it must be a string")
1169
1138
 
1170
1139
 
1171
- def validate_string_connector_param(param: str, s: str) -> None:
1140
+ def validate_string_connector_param(param, s):
1172
1141
  if not isinstance(s, str):
1173
1142
  raise CLIConnectionException(param + " format is not correct, it must be a string")
1174
- if not s or not s.strip():
1175
- raise CLIConnectionException(param + " cannot be empty")
1176
1143
 
1177
1144
 
1178
1145
  def validate_connection_name(client, connection_name, service):
@@ -40,18 +40,6 @@ from tinybird.tb.modules.feedback_manager import FeedbackManager, get_cli_name
40
40
  from tinybird.tb.modules.project import Project
41
41
  from tinybird.tb.modules.secret import save_secret_to_env_file
42
42
 
43
-
44
- def _upper_or_none(_ctx: click.Context, _param: click.Parameter, value: Optional[str]) -> Optional[str]:
45
- """Click callback that uppercases the option value if present.
46
-
47
- Kafka SASL mechanisms and security protocols are matched case-sensitively
48
- downstream (CLI, client, server), so we normalize at the flag layer to
49
- accept user input like `--sasl-mechanism oauthbearer` without silently
50
- falling through the case-sensitive branches and breaking the request.
51
- """
52
- return value.upper() if value else value
53
-
54
-
55
43
  DATA_CONNECTOR_SETTINGS: Dict[DataConnectorType, List[str]] = {
56
44
  DataConnectorType.KAFKA: [
57
45
  "kafka_bootstrap_servers",
@@ -259,22 +247,15 @@ def connection_create_gcs(ctx: Context) -> None:
259
247
  @click.option("--schema-registry-url", default=None, help="Avro Confluent Schema Registry URL")
260
248
  @click.option(
261
249
  "--sasl-mechanism",
262
- default=None,
263
- callback=_upper_or_none,
250
+ default="PLAIN",
264
251
  help="Authentication method for connection-based protocols. Defaults to 'PLAIN'",
265
252
  )
266
253
  @click.option(
267
254
  "--security-protocol",
268
- default=None,
269
- callback=_upper_or_none,
255
+ default="SASL_SSL",
270
256
  help="Security protocol for connection-based protocols. Defaults to 'SASL_SSL'",
271
257
  )
272
258
  @click.option("--ssl-ca-pem", default=None, help="Path or content of the CA Certificate file in PEM format")
273
- @click.option(
274
- "--oauthbearer-aws-external-id",
275
- default=None,
276
- help="Pre-shared external_id for the AWS assume-role call (OAUTHBEARER+AWS only). If omitted, the wizard prompts for one and falls back to a Tinybird-generated value.",
277
- )
278
259
  @click.pass_context
279
260
  def connection_create_kafka_cmd(
280
261
  ctx: Context,
@@ -287,7 +268,6 @@ def connection_create_kafka_cmd(
287
268
  sasl_mechanism: Optional[str],
288
269
  security_protocol: Optional[str],
289
270
  ssl_ca_pem: Optional[str],
290
- oauthbearer_aws_external_id: Optional[str],
291
271
  ) -> None:
292
272
  env: str = ctx.ensure_object(dict)["env"]
293
273
  project: Project = ctx.ensure_object(dict)["project"]
@@ -315,7 +295,6 @@ def connection_create_kafka_cmd(
315
295
  sasl_mechanism=sasl_mechanism,
316
296
  security_protocol=security_protocol,
317
297
  ssl_ca_pem=ssl_ca_pem,
318
- oauthbearer_aws_external_id=oauthbearer_aws_external_id,
319
298
  )
320
299
 
321
300
  if not result["error"]: