tinybird-cli 5.1.1.dev0__tar.gz → 5.1.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.
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/PKG-INFO +11 -1
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/__cli__.py +2 -2
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/feedback_manager.py +5 -1
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/sql_template.py +86 -4
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/sql_toolset.py +9 -7
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/pipe.py +69 -1
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/workspace.py +1 -1
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tornado_template.py +1 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird_cli.egg-info/PKG-INFO +11 -1
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/setup.cfg +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/ch_utils/engine.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/check_pypi.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/client.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/config.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/connectors.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/context.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/datafile.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/datatypes.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/git_settings.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/sql.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/syncasync.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/common.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/token.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird_cli.egg-info/SOURCES.txt +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird_cli.egg-info/dependency_links.txt +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird_cli.egg-info/entry_points.txt +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird_cli.egg-info/requires.txt +0 -0
- {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tinybird-cli
|
|
3
|
-
Version: 5.1.1.
|
|
3
|
+
Version: 5.1.1.dev2
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/cli/introduction.html
|
|
6
6
|
Author: Tinybird
|
|
@@ -18,6 +18,16 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
18
18
|
Changelog
|
|
19
19
|
----------
|
|
20
20
|
|
|
21
|
+
5.1.1.dev2
|
|
22
|
+
************
|
|
23
|
+
|
|
24
|
+
- `Added` `tb pipe unlink` command
|
|
25
|
+
|
|
26
|
+
5.1.1.dev1
|
|
27
|
+
***********
|
|
28
|
+
|
|
29
|
+
- `Added` internal release
|
|
30
|
+
|
|
21
31
|
5.1.0
|
|
22
32
|
******
|
|
23
33
|
|
|
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
|
|
|
4
4
|
__url__ = 'https://www.tinybird.co/docs/cli/introduction.html'
|
|
5
5
|
__author__ = 'Tinybird'
|
|
6
6
|
__author_email__ = 'support@tinybird.co'
|
|
7
|
-
__version__ = '5.1.1.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '5.1.1.dev2'
|
|
8
|
+
__revision__ = '1417339'
|
|
@@ -357,6 +357,7 @@ class FeedbackManager:
|
|
|
357
357
|
error_number_of_fixed_params_and_resources_mismatch = error_message(
|
|
358
358
|
"The number of --fixed-params options must not exceed the number of --scope and --resource options."
|
|
359
359
|
)
|
|
360
|
+
error_unlinking_pipe_not_linked = error_message("** {pipe} is not linked (MV, Copy, or Sink).")
|
|
360
361
|
|
|
361
362
|
info_incl_relative_path = info_message("** Relative path {path} does not exist, skipping.")
|
|
362
363
|
info_ignoring_incl_file = info_message(
|
|
@@ -670,7 +671,9 @@ Ready? """
|
|
|
670
671
|
info_materialized_datasource_used = info_message(
|
|
671
672
|
"** Materialized pipe '{pipe}' using the Data Source '{datasource}'"
|
|
672
673
|
)
|
|
673
|
-
|
|
674
|
+
info_unlinking_materialized_pipe = info_message("** Unlinking materialized pipe {pipe}")
|
|
675
|
+
info_unlinking_copy_pipe = info_message("** Unlinking copy pipe {pipe}")
|
|
676
|
+
info_unlinking_sink_pipe = info_message("** Unlinking sink pipe {pipe}")
|
|
674
677
|
info_materialized_unlinking_pipe_not_found = info_message("** {pipe} not found")
|
|
675
678
|
info_materialized_dry_unlinking_pipe = info_message("** [DRY RUN] Unlinking materialized pipe {pipe}")
|
|
676
679
|
info_copy_datasource_created = info_message("** Copy pipe '{pipe}' created the Data Source '{datasource}'")
|
|
@@ -839,6 +842,7 @@ Ready? """
|
|
|
839
842
|
** Pipe URL: {host}/v0/pipes/{pipe}
|
|
840
843
|
"""
|
|
841
844
|
)
|
|
845
|
+
success_pipe_unlinked = success_message("""** Pipe {pipe} unlinked""")
|
|
842
846
|
success_node_copy = success_message(
|
|
843
847
|
"""** Node set to be used to copy data!
|
|
844
848
|
** Pipe URL: {host}/v0/pipes/{pipe}
|
|
@@ -17,6 +17,36 @@ from tinybird.context import ff_preprocess_parameters_circuit_breaker, ff_split_
|
|
|
17
17
|
from .datatypes import testers
|
|
18
18
|
from .tornado_template import VALID_CUSTOM_FUNCTION_NAMES, SecurityException, Template
|
|
19
19
|
|
|
20
|
+
TB_SECRET_IN_TEST_MODE = "tb_secret_dont_raise"
|
|
21
|
+
TB_SECRET_PREFIX = "tb_secret_"
|
|
22
|
+
CH_PARAM_PREFIX = "param_"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def secret_template_key(secret_name: str) -> str:
|
|
26
|
+
return f"{TB_SECRET_PREFIX}{secret_name}"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def is_secret_template_key(key: str) -> bool:
|
|
30
|
+
return key.startswith(TB_SECRET_PREFIX)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class TemplateExecutionResults(dict):
|
|
34
|
+
def __init__(self, *args, **kwargs):
|
|
35
|
+
super(TemplateExecutionResults, self).__init__(*args, **kwargs)
|
|
36
|
+
self.template_params = set()
|
|
37
|
+
self.ch_params = set()
|
|
38
|
+
|
|
39
|
+
def add_template_param(self, param: str):
|
|
40
|
+
self.template_params.add(param)
|
|
41
|
+
|
|
42
|
+
def add_ch_param(self, param: str):
|
|
43
|
+
self.ch_params.add(param)
|
|
44
|
+
|
|
45
|
+
def update_all(self, other: "TemplateExecutionResults"):
|
|
46
|
+
self.update(other)
|
|
47
|
+
self.ch_params.update(other.ch_params)
|
|
48
|
+
self.template_params.update(other.template_params)
|
|
49
|
+
|
|
20
50
|
|
|
21
51
|
class SQLTemplateCustomError(Exception):
|
|
22
52
|
def __init__(self, err, code=400):
|
|
@@ -1333,10 +1363,30 @@ for p in DEFAULT_PARAM_NAMES: # we handle these in an specific manner
|
|
|
1333
1363
|
error_vars = ["error", "custom_error"]
|
|
1334
1364
|
|
|
1335
1365
|
|
|
1336
|
-
def generate(self, **kwargs) -> Tuple[str,
|
|
1366
|
+
def generate(self, **kwargs) -> Tuple[str, TemplateExecutionResults]:
|
|
1337
1367
|
"""Generate this template with the given arguments."""
|
|
1338
1368
|
namespace = {}
|
|
1339
|
-
template_execution_results =
|
|
1369
|
+
template_execution_results = TemplateExecutionResults()
|
|
1370
|
+
for key in kwargs.get("tb_secrets", []):
|
|
1371
|
+
if is_secret_template_key(key):
|
|
1372
|
+
template_execution_results.add_template_param(key)
|
|
1373
|
+
if TB_SECRET_IN_TEST_MODE in kwargs:
|
|
1374
|
+
template_execution_results[TB_SECRET_IN_TEST_MODE] = None
|
|
1375
|
+
|
|
1376
|
+
def set_tb_secret(x):
|
|
1377
|
+
try:
|
|
1378
|
+
key = secret_template_key(x)
|
|
1379
|
+
if key in template_execution_results.template_params:
|
|
1380
|
+
template_execution_results.add_ch_param(x)
|
|
1381
|
+
return Symbol("{" + sqlescape(x) + ": String}")
|
|
1382
|
+
else:
|
|
1383
|
+
is_test_mode = TB_SECRET_IN_TEST_MODE in template_execution_results
|
|
1384
|
+
if is_test_mode:
|
|
1385
|
+
return Symbol("{" + sqlescape(x) + ": String}")
|
|
1386
|
+
else:
|
|
1387
|
+
raise SQLTemplateException(f"Secret '{x}' does not exist in Workspace")
|
|
1388
|
+
except Exception:
|
|
1389
|
+
raise SQLTemplateException(f"Secret '{x}' does not exist in Workspace")
|
|
1340
1390
|
|
|
1341
1391
|
def set_max_threads(x):
|
|
1342
1392
|
try:
|
|
@@ -1374,6 +1424,7 @@ def generate(self, **kwargs) -> Tuple[str, dict]:
|
|
|
1374
1424
|
"__name__": self.name.replace(".", "_"),
|
|
1375
1425
|
"__loader__": ObjectDict(get_source=lambda name: self.code),
|
|
1376
1426
|
"max_threads": set_max_threads,
|
|
1427
|
+
"tb_secret": set_tb_secret,
|
|
1377
1428
|
"backend_hint": set_backend_hint,
|
|
1378
1429
|
"cache_ttl": set_cache_ttl,
|
|
1379
1430
|
"activate": set_activate,
|
|
@@ -1856,9 +1907,10 @@ def preprocess_variables(variables: dict, t: Template):
|
|
|
1856
1907
|
def render_sql_template(
|
|
1857
1908
|
sql: str,
|
|
1858
1909
|
variables: Optional[dict] = None,
|
|
1910
|
+
secrets: Optional[List[str]] = None,
|
|
1859
1911
|
test_mode: bool = False,
|
|
1860
1912
|
name: Optional[str] = None,
|
|
1861
|
-
) -> Tuple[str,
|
|
1913
|
+
) -> Tuple[str, TemplateExecutionResults, list]:
|
|
1862
1914
|
"""
|
|
1863
1915
|
>>> render_sql_template("select * from table where f = {{Float32(foo)}}", { 'foo': -1 })
|
|
1864
1916
|
("select * from table where f = toFloat32('-1.0')", {}, [])
|
|
@@ -2058,6 +2110,20 @@ def render_sql_template(
|
|
|
2058
2110
|
tinybird.tornado_template.UnClosedIfError: Missing {% end %} block for if at line 1
|
|
2059
2111
|
>>> render_sql_template("select * from table where str = {{pipeline}}", { 'pipeline': 'test' })
|
|
2060
2112
|
("select * from table where str = 'test'", {}, ['pipeline'])
|
|
2113
|
+
>>> render_sql_template("select * from table where str = {{tb_secret('test')}}", secrets = [ 'tb_secret_test' ])
|
|
2114
|
+
('select * from table where str = {test: String}', {}, [])
|
|
2115
|
+
>>> render_sql_template("select * from table where str = {{tb_secret('test')}}", variables = { 'test': '1234' })
|
|
2116
|
+
Traceback (most recent call last):
|
|
2117
|
+
...
|
|
2118
|
+
tinybird.sql_template.SQLTemplateException: Template Syntax Error: Secret 'test' does not exist in Workspace
|
|
2119
|
+
>>> render_sql_template("select * from table where str = {{tb_secret('test')}}", test_mode=True)
|
|
2120
|
+
('select * from table where str = {test: String}', {}, [])
|
|
2121
|
+
>>> render_sql_template("select * from table where str = {{tb_secret('test')}}", secrets = [ 'tb_secret_test' ], test_mode=True)
|
|
2122
|
+
('select * from table where str = {test: String}', {}, [])
|
|
2123
|
+
>>> render_sql_template("select * from table where str = {{tb_secret('test')}}", secrets = [ 'tb_secret_test2' ])
|
|
2124
|
+
Traceback (most recent call last):
|
|
2125
|
+
...
|
|
2126
|
+
tinybird.sql_template.SQLTemplateException: Template Syntax Error: Secret 'test' does not exist in Workspace
|
|
2061
2127
|
"""
|
|
2062
2128
|
escape_split_to_array = ff_split_to_array_escape.get(False)
|
|
2063
2129
|
bypass_preprocess_variables = ff_preprocess_parameters_circuit_breaker.get(False)
|
|
@@ -2076,10 +2142,17 @@ def render_sql_template(
|
|
|
2076
2142
|
return Comment("error launched")
|
|
2077
2143
|
|
|
2078
2144
|
v: dict = {x["name"]: Placeholder(x["name"], x["line"]) for x in template_variables}
|
|
2145
|
+
is_tb_secret = any([s for s in template_variables if s["name"] == "tb_secret"])
|
|
2079
2146
|
|
|
2080
2147
|
if variables:
|
|
2081
2148
|
v.update(variables)
|
|
2082
2149
|
|
|
2150
|
+
if secrets:
|
|
2151
|
+
v.update({"tb_secrets": secrets})
|
|
2152
|
+
|
|
2153
|
+
if is_tb_secret:
|
|
2154
|
+
v.update({TB_SECRET_IN_TEST_MODE: None})
|
|
2155
|
+
|
|
2083
2156
|
v.update(type_fns_check)
|
|
2084
2157
|
v.update(
|
|
2085
2158
|
{
|
|
@@ -2093,10 +2166,19 @@ def render_sql_template(
|
|
|
2093
2166
|
v = {x["name"]: None for x in template_variables}
|
|
2094
2167
|
if variables:
|
|
2095
2168
|
v.update(variables)
|
|
2169
|
+
|
|
2170
|
+
if secrets:
|
|
2171
|
+
v.update({"tb_secrets": secrets})
|
|
2096
2172
|
v.update(type_fns)
|
|
2097
2173
|
|
|
2098
2174
|
try:
|
|
2099
|
-
|
|
2175
|
+
sql, template_execution_results = generate(t, **v)
|
|
2176
|
+
try:
|
|
2177
|
+
if TB_SECRET_IN_TEST_MODE in template_execution_results:
|
|
2178
|
+
del template_execution_results[TB_SECRET_IN_TEST_MODE]
|
|
2179
|
+
except Exception:
|
|
2180
|
+
pass
|
|
2181
|
+
return sql, template_execution_results, variable_warnings
|
|
2100
2182
|
except NameError as e:
|
|
2101
2183
|
raise SQLTemplateException(e, documentation="/cli/advanced-templates.html#defined")
|
|
2102
2184
|
except SQLTemplateException:
|
|
@@ -14,15 +14,15 @@ VALID_REMOTE = "VALID_REMOTE"
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class InvalidFunction(ValueError):
|
|
17
|
-
def __init__(self, msg: str = "",
|
|
17
|
+
def __init__(self, msg: str = "", table_function_name: str = ""):
|
|
18
18
|
if any([fn for fn in COPY_ENABLED_TABLE_FUNCTIONS if fn in msg]):
|
|
19
19
|
msg = msg.replace("is restricted", "is restricted to Copy Pipes")
|
|
20
20
|
|
|
21
|
-
if
|
|
22
|
-
if
|
|
23
|
-
self.msg = "The
|
|
21
|
+
if table_function_name:
|
|
22
|
+
if table_function_name in COPY_ENABLED_TABLE_FUNCTIONS:
|
|
23
|
+
self.msg = f"The {table_function_name} table function is only allowed in Copy Pipes"
|
|
24
24
|
else:
|
|
25
|
-
self.msg = f"The query uses disabled table functions: '{
|
|
25
|
+
self.msg = f"The query uses disabled table functions: '{table_function_name}'"
|
|
26
26
|
else:
|
|
27
27
|
self.msg = msg
|
|
28
28
|
super().__init__(self.msg)
|
|
@@ -102,6 +102,8 @@ def sql_get_used_tables_cached(
|
|
|
102
102
|
msg = str(e)
|
|
103
103
|
if "is restricted. Contact support@tinybird.co" in msg:
|
|
104
104
|
raise InvalidFunction(msg=msg) from e
|
|
105
|
+
elif "Unknown function tb_secret" in msg:
|
|
106
|
+
raise InvalidFunction(msg="Unknown function tb_secret. Usage: {{tb_secret('secret_name')}}") from e
|
|
105
107
|
raise
|
|
106
108
|
return [(default_database, sql, "")]
|
|
107
109
|
|
|
@@ -234,7 +236,7 @@ def replace_tables(
|
|
|
234
236
|
if len(table) == 3:
|
|
235
237
|
first_table, second_table, last_table = table
|
|
236
238
|
if last_table and last_table not in _enabled_table_functions:
|
|
237
|
-
raise InvalidFunction(
|
|
239
|
+
raise InvalidFunction(table_function_name=last_table)
|
|
238
240
|
if first_table or second_table:
|
|
239
241
|
table = (first_table, second_table)
|
|
240
242
|
else:
|
|
@@ -251,7 +253,7 @@ def replace_tables(
|
|
|
251
253
|
and dependent_table[2] not in _enabled_table_functions
|
|
252
254
|
and not (dependent_table[2] in ["cluster"] and replacement[0] == VALID_REMOTE)
|
|
253
255
|
):
|
|
254
|
-
raise InvalidFunction(
|
|
256
|
+
raise InvalidFunction(table_function_name=dependent_table[2])
|
|
255
257
|
if dependent_table[0] or dependent_table[1]:
|
|
256
258
|
dependent_table = (dependent_table[0], dependent_table[1])
|
|
257
259
|
else:
|
|
@@ -16,7 +16,7 @@ from click import Context
|
|
|
16
16
|
import tinybird.context as context
|
|
17
17
|
from tinybird.client import DoesNotExistException, TinyB
|
|
18
18
|
from tinybird.config import DEFAULT_API_HOST, FeatureFlags
|
|
19
|
-
from tinybird.datafile import folder_push, get_name_version, process_file, wait_job
|
|
19
|
+
from tinybird.datafile import 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
|
|
@@ -267,6 +267,74 @@ async def pipe_populate(
|
|
|
267
267
|
await wait_job(cl, job_id, job_url, "Populating")
|
|
268
268
|
|
|
269
269
|
|
|
270
|
+
@pipe.command(name="unlink")
|
|
271
|
+
@click.argument("pipe_name_or_id")
|
|
272
|
+
@click.argument("node_uid", default=None, required=False)
|
|
273
|
+
@click.pass_context
|
|
274
|
+
@coro
|
|
275
|
+
async def pipe_unlink_output_node(
|
|
276
|
+
ctx: click.Context,
|
|
277
|
+
pipe_name_or_id: str,
|
|
278
|
+
node_uid: Optional[str] = None,
|
|
279
|
+
):
|
|
280
|
+
"""Unlink the output of a pipe. Works for Materialized Views, Copy Pipes, and Sinks."""
|
|
281
|
+
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
282
|
+
|
|
283
|
+
try:
|
|
284
|
+
pipe = await client.pipe(pipe_name_or_id)
|
|
285
|
+
|
|
286
|
+
if pipe["type"] not in [PipeTypes.MATERIALIZED, PipeTypes.COPY, PipeTypes.DATA_SINK]:
|
|
287
|
+
raise CLIPipeException(FeedbackManager.error_unlinking_pipe_not_linked(pipe=pipe_name_or_id))
|
|
288
|
+
|
|
289
|
+
if pipe["type"] == PipeTypes.MATERIALIZED:
|
|
290
|
+
click.echo(FeedbackManager.info_unlinking_materialized_pipe(pipe=pipe["name"]))
|
|
291
|
+
|
|
292
|
+
if not node_uid:
|
|
293
|
+
for node in pipe["nodes"]:
|
|
294
|
+
if "materialized" in node and node["materialized"] is not None:
|
|
295
|
+
node_uid = node["id"]
|
|
296
|
+
break
|
|
297
|
+
|
|
298
|
+
if not node_uid:
|
|
299
|
+
raise CLIPipeException(FeedbackManager.error_unlinking_pipe_not_linked(pipe=pipe_name_or_id))
|
|
300
|
+
else:
|
|
301
|
+
await client.pipe_unlink_materialized(pipe["name"], node_uid)
|
|
302
|
+
click.echo(FeedbackManager.success_pipe_unlinked(pipe=pipe["name"]))
|
|
303
|
+
|
|
304
|
+
if pipe["type"] == PipeTypes.COPY:
|
|
305
|
+
click.echo(FeedbackManager.info_unlinking_copy_pipe(pipe=pipe["name"]))
|
|
306
|
+
|
|
307
|
+
if not node_uid:
|
|
308
|
+
for node in pipe["nodes"]:
|
|
309
|
+
if node["node_type"] == "copy":
|
|
310
|
+
node_uid = node["id"]
|
|
311
|
+
break
|
|
312
|
+
|
|
313
|
+
if not node_uid:
|
|
314
|
+
raise CLIPipeException(FeedbackManager.error_unlinking_pipe_not_linked(pipe=pipe_name_or_id))
|
|
315
|
+
else:
|
|
316
|
+
await client.pipe_remove_copy(pipe["name"], node_uid)
|
|
317
|
+
click.echo(FeedbackManager.success_pipe_unlinked(pipe=pipe["name"]))
|
|
318
|
+
|
|
319
|
+
if pipe["type"] == PipeTypes.DATA_SINK:
|
|
320
|
+
click.echo(FeedbackManager.info_unlinking_sink_pipe(pipe=pipe["name"]))
|
|
321
|
+
|
|
322
|
+
if not node_uid:
|
|
323
|
+
for node in pipe["nodes"]:
|
|
324
|
+
if node["node_type"] == "sink":
|
|
325
|
+
node_uid = node["id"]
|
|
326
|
+
break
|
|
327
|
+
|
|
328
|
+
if not node_uid:
|
|
329
|
+
raise CLIPipeException(FeedbackManager.error_unlinking_pipe_not_linked(pipe=pipe_name_or_id))
|
|
330
|
+
else:
|
|
331
|
+
await client.pipe_remove_sink(pipe["name"], node_uid)
|
|
332
|
+
click.echo(FeedbackManager.success_pipe_unlinked(pipe=pipe["name"]))
|
|
333
|
+
|
|
334
|
+
except Exception as e:
|
|
335
|
+
raise CLIPipeException(FeedbackManager.error_exception(error=e))
|
|
336
|
+
|
|
337
|
+
|
|
270
338
|
@pipe.command(name="append")
|
|
271
339
|
@click.argument("pipe_name_or_uid")
|
|
272
340
|
@click.argument("sql")
|
|
@@ -151,7 +151,7 @@ async def clear_workspace(ctx: Context, yes: bool, dry_run: bool) -> None:
|
|
|
151
151
|
break
|
|
152
152
|
|
|
153
153
|
if node_id:
|
|
154
|
-
click.echo(FeedbackManager.
|
|
154
|
+
click.echo(FeedbackManager.info_unlinking_materialized_pipe(pipe=pipe["name"]))
|
|
155
155
|
try:
|
|
156
156
|
await client.pipe_unlink_materialized(pipe["name"], node_id)
|
|
157
157
|
except DoesNotExistException:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tinybird-cli
|
|
3
|
-
Version: 5.1.1.
|
|
3
|
+
Version: 5.1.1.dev2
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/cli/introduction.html
|
|
6
6
|
Author: Tinybird
|
|
@@ -18,6 +18,16 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
18
18
|
Changelog
|
|
19
19
|
----------
|
|
20
20
|
|
|
21
|
+
5.1.1.dev2
|
|
22
|
+
************
|
|
23
|
+
|
|
24
|
+
- `Added` `tb pipe unlink` command
|
|
25
|
+
|
|
26
|
+
5.1.1.dev1
|
|
27
|
+
***********
|
|
28
|
+
|
|
29
|
+
- `Added` internal release
|
|
30
|
+
|
|
21
31
|
5.1.0
|
|
22
32
|
******
|
|
23
33
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/tinyunit/tinyunit.py
RENAMED
|
File without changes
|
{tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py
RENAMED
|
File without changes
|
|
File without changes
|
{tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird/tb_cli_modules/workspace_members.py
RENAMED
|
File without changes
|
|
File without changes
|
{tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev2}/tinybird_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|