tinybird-cli 5.1.1.dev0__tar.gz → 5.1.1.dev1__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 (46) hide show
  1. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/PKG-INFO +6 -1
  2. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/__cli__.py +2 -2
  3. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/sql_template.py +80 -5
  4. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/sql_toolset.py +9 -7
  5. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tornado_template.py +1 -0
  6. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird_cli.egg-info/PKG-INFO +6 -1
  7. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/setup.cfg +0 -0
  8. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/ch_utils/constants.py +0 -0
  9. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/ch_utils/engine.py +0 -0
  10. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/check_pypi.py +0 -0
  11. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/client.py +0 -0
  12. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/config.py +0 -0
  13. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/connectors.py +0 -0
  14. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/context.py +0 -0
  15. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/datafile.py +0 -0
  16. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/datatypes.py +0 -0
  17. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/feedback_manager.py +0 -0
  18. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/git_settings.py +0 -0
  19. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/sql.py +0 -0
  20. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/sql_template_fmt.py +0 -0
  21. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/syncasync.py +0 -0
  22. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli.py +0 -0
  23. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/auth.py +0 -0
  24. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/branch.py +0 -0
  25. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/cicd.py +0 -0
  26. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/cli.py +0 -0
  27. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/common.py +0 -0
  28. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/config.py +0 -0
  29. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/connection.py +0 -0
  30. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/datasource.py +0 -0
  31. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/exceptions.py +0 -0
  32. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/job.py +0 -0
  33. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/pipe.py +0 -0
  34. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/regions.py +0 -0
  35. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/telemetry.py +0 -0
  36. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/test.py +0 -0
  37. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  38. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  39. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/token.py +0 -0
  40. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/workspace.py +0 -0
  41. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  42. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird_cli.egg-info/SOURCES.txt +0 -0
  43. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird_cli.egg-info/dependency_links.txt +0 -0
  44. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird_cli.egg-info/entry_points.txt +0 -0
  45. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/tinybird_cli.egg-info/requires.txt +0 -0
  46. {tinybird-cli-5.1.1.dev0 → tinybird-cli-5.1.1.dev1}/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.dev0
3
+ Version: 5.1.1.dev1
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,11 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
18
18
  Changelog
19
19
  ----------
20
20
 
21
+ 5.1.1.dev1
22
+ ***********
23
+
24
+ - `Added` internal release
25
+
21
26
  5.1.0
22
27
  ******
23
28
 
@@ -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.dev0'
8
- __revision__ = '1b678aa'
7
+ __version__ = '5.1.1.dev1'
8
+ __revision__ = '2922d6f'
@@ -7,7 +7,7 @@ from datetime import datetime
7
7
  from functools import lru_cache
8
8
  from io import StringIO
9
9
  from json import loads
10
- from typing import Any, List, Optional, Tuple, Union
10
+ from typing import Any, Dict, List, Optional, Tuple, Union
11
11
 
12
12
  from tornado import escape
13
13
  from tornado.util import ObjectDict, exec_in, unicode_type
@@ -17,6 +17,32 @@ 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
+
37
+ def subdict(self, key: str) -> Dict[str, Any]:
38
+ return {k: v for k, v in self.items() if k.startswith(key)}
39
+
40
+ def get_params(self) -> Dict[str, Any]:
41
+ return self.subdict(CH_PARAM_PREFIX)
42
+
43
+ def get_params_keys(self) -> List[str]:
44
+ return [key.split(CH_PARAM_PREFIX)[-1] for key in list(self.get_params().keys())]
45
+
20
46
 
21
47
  class SQLTemplateCustomError(Exception):
22
48
  def __init__(self, err, code=400):
@@ -1333,10 +1359,29 @@ for p in DEFAULT_PARAM_NAMES: # we handle these in an specific manner
1333
1359
  error_vars = ["error", "custom_error"]
1334
1360
 
1335
1361
 
1336
- def generate(self, **kwargs) -> Tuple[str, dict]:
1362
+ def generate(self, **kwargs) -> Tuple[str, TemplateExecutionResults]:
1337
1363
  """Generate this template with the given arguments."""
1338
1364
  namespace = {}
1339
- template_execution_results = {}
1365
+ template_execution_results = TemplateExecutionResults()
1366
+ for key in kwargs:
1367
+ if is_secret_template_key(key):
1368
+ template_execution_results[key] = kwargs[key]
1369
+
1370
+ def set_tb_secret(x):
1371
+ try:
1372
+ key = secret_template_key(x)
1373
+ if key in template_execution_results:
1374
+ val = template_execution_results[key]
1375
+ template_execution_results[f"{CH_PARAM_PREFIX}{x}"] = val
1376
+ return Symbol("{" + sqlescape(x) + ": String}")
1377
+ else:
1378
+ is_test_mode = TB_SECRET_IN_TEST_MODE in template_execution_results
1379
+ if is_test_mode:
1380
+ return Symbol("{" + sqlescape(x) + ": String}")
1381
+ else:
1382
+ raise SQLTemplateException(f"Secret '{x}' does not exist in Workspace")
1383
+ except Exception:
1384
+ raise SQLTemplateException(f"Secret '{x}' does not exist in Workspace")
1340
1385
 
1341
1386
  def set_max_threads(x):
1342
1387
  try:
@@ -1374,6 +1419,7 @@ def generate(self, **kwargs) -> Tuple[str, dict]:
1374
1419
  "__name__": self.name.replace(".", "_"),
1375
1420
  "__loader__": ObjectDict(get_source=lambda name: self.code),
1376
1421
  "max_threads": set_max_threads,
1422
+ "tb_secret": set_tb_secret,
1377
1423
  "backend_hint": set_backend_hint,
1378
1424
  "cache_ttl": set_cache_ttl,
1379
1425
  "activate": set_activate,
@@ -1856,9 +1902,10 @@ def preprocess_variables(variables: dict, t: Template):
1856
1902
  def render_sql_template(
1857
1903
  sql: str,
1858
1904
  variables: Optional[dict] = None,
1905
+ secrets: Optional[dict] = None,
1859
1906
  test_mode: bool = False,
1860
1907
  name: Optional[str] = None,
1861
- ) -> Tuple[str, dict, list]:
1908
+ ) -> Tuple[str, TemplateExecutionResults, list]:
1862
1909
  """
1863
1910
  >>> render_sql_template("select * from table where f = {{Float32(foo)}}", { 'foo': -1 })
1864
1911
  ("select * from table where f = toFloat32('-1.0')", {}, [])
@@ -2058,6 +2105,20 @@ def render_sql_template(
2058
2105
  tinybird.tornado_template.UnClosedIfError: Missing {% end %} block for if at line 1
2059
2106
  >>> render_sql_template("select * from table where str = {{pipeline}}", { 'pipeline': 'test' })
2060
2107
  ("select * from table where str = 'test'", {}, ['pipeline'])
2108
+ >>> render_sql_template("select * from table where str = {{tb_secret('test')}}", secrets = { 'tb_secret_test': '1234' })
2109
+ ('select * from table where str = {test: String}', {'param_test': '1234'}, [])
2110
+ >>> render_sql_template("select * from table where str = {{tb_secret('test')}}", variables = { 'test': '1234' })
2111
+ Traceback (most recent call last):
2112
+ ...
2113
+ tinybird.sql_template.SQLTemplateException: Template Syntax Error: Secret 'test' does not exist in Workspace
2114
+ >>> render_sql_template("select * from table where str = {{tb_secret('test')}}", test_mode=True)
2115
+ ('select * from table where str = {test: String}', {}, [])
2116
+ >>> render_sql_template("select * from table where str = {{tb_secret('test')}}", secrets = { 'tb_secret_test': '1234' }, test_mode=True)
2117
+ ('select * from table where str = {test: String}', {'param_test': '1234'}, [])
2118
+ >>> render_sql_template("select * from table where str = {{tb_secret('test')}}", secrets = { 'tb_secret_test2': '1234' })
2119
+ Traceback (most recent call last):
2120
+ ...
2121
+ tinybird.sql_template.SQLTemplateException: Template Syntax Error: Secret 'test' does not exist in Workspace
2061
2122
  """
2062
2123
  escape_split_to_array = ff_split_to_array_escape.get(False)
2063
2124
  bypass_preprocess_variables = ff_preprocess_parameters_circuit_breaker.get(False)
@@ -2076,10 +2137,17 @@ def render_sql_template(
2076
2137
  return Comment("error launched")
2077
2138
 
2078
2139
  v: dict = {x["name"]: Placeholder(x["name"], x["line"]) for x in template_variables}
2140
+ is_tb_secret = any([s for s in template_variables if s["name"] == "tb_secret"])
2079
2141
 
2080
2142
  if variables:
2081
2143
  v.update(variables)
2082
2144
 
2145
+ if secrets:
2146
+ v.update(secrets)
2147
+
2148
+ if is_tb_secret:
2149
+ v.update({TB_SECRET_IN_TEST_MODE: None})
2150
+
2083
2151
  v.update(type_fns_check)
2084
2152
  v.update(
2085
2153
  {
@@ -2093,10 +2161,17 @@ def render_sql_template(
2093
2161
  v = {x["name"]: None for x in template_variables}
2094
2162
  if variables:
2095
2163
  v.update(variables)
2164
+
2165
+ if secrets:
2166
+ v.update(secrets)
2096
2167
  v.update(type_fns)
2097
2168
 
2098
2169
  try:
2099
- return *generate(t, **v), variable_warnings
2170
+ sql, template_execution_results = generate(t, **v)
2171
+ for key in list(template_execution_results.keys()):
2172
+ if is_secret_template_key(key) and key in template_execution_results:
2173
+ del template_execution_results[key]
2174
+ return sql, template_execution_results, variable_warnings
2100
2175
  except NameError as e:
2101
2176
  raise SQLTemplateException(e, documentation="/cli/advanced-templates.html#defined")
2102
2177
  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 = "", table_function_names: 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 table_function_names:
22
- if "postgresql" in table_function_names:
23
- self.msg = "The postgresql table function is only allowed in Copy Pipes"
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: '{table_function_names}'"
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(table_function_names=last_table)
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(table_function_names=dependent_table[2])
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:
@@ -1050,6 +1050,7 @@ VALID_FUNCTION_NAMES = {
1050
1050
  "activate",
1051
1051
  "sql_unescape",
1052
1052
  "max_threads",
1053
+ "tb_secret",
1053
1054
  "Int",
1054
1055
  "table",
1055
1056
  "TABLE",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tinybird-cli
3
- Version: 5.1.1.dev0
3
+ Version: 5.1.1.dev1
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,11 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
18
18
  Changelog
19
19
  ----------
20
20
 
21
+ 5.1.1.dev1
22
+ ***********
23
+
24
+ - `Added` internal release
25
+
21
26
  5.1.0
22
27
  ******
23
28