tinybird-cli 5.0.0.dev4__tar.gz → 5.0.1.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.
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/PKG-INFO +9 -26
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/__cli__.py +2 -2
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/ch_utils/constants.py +1 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/client.py +21 -9
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/datafile.py +2 -1
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/sql_toolset.py +69 -16
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/workspace_members.py +8 -3
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird_cli.egg-info/PKG-INFO +9 -26
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/setup.cfg +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/ch_utils/engine.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/check_pypi.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/config.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/connectors.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/context.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/datatypes.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/feedback_manager.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/git_settings.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/sql.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/sql_template.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/syncasync.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/common.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/pipe.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/token.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tornado_template.py +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird_cli.egg-info/SOURCES.txt +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird_cli.egg-info/dependency_links.txt +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird_cli.egg-info/entry_points.txt +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird_cli.egg-info/requires.txt +0 -0
- {tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/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.0.
|
|
3
|
+
Version: 5.0.1.dev0
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/cli/introduction.html
|
|
6
6
|
Author: Tinybird
|
|
@@ -18,37 +18,20 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
18
18
|
Changelog
|
|
19
19
|
----------
|
|
20
20
|
|
|
21
|
-
5.0.0
|
|
22
|
-
|
|
21
|
+
5.0.0
|
|
22
|
+
******
|
|
23
23
|
|
|
24
|
-
- `
|
|
24
|
+
- `Breaking change` Make `insertion_date` column explicit. This column is no longer inferred, it must be present in the Data Source file.
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
************
|
|
26
|
+
Detailed info at https://www.tinybird.co/docs/changelog/2024-06-17-insertion_date-deprecation
|
|
28
27
|
|
|
28
|
+
- `Added` parameter to `tb pipe regression-test` --relative-change
|
|
29
|
+
- `Added` `tb push` displays warnings when using a reserved parameter in a pipe.
|
|
30
|
+
- `Added` --role parameter to `tb workspace members add`
|
|
29
31
|
- `Changed` Point region hosts to new `app.tinybird.co` domain
|
|
30
|
-
|
|
31
|
-
5.0.0.dev2
|
|
32
|
-
************
|
|
33
|
-
|
|
32
|
+
- `Improved` help message of `tb workspace members set-role` now displays the 3 valid roles: viewer|guest|admin.
|
|
34
33
|
- `Improved` syntax error messages when parsing endpoints.
|
|
35
34
|
|
|
36
|
-
5.0.0.dev1
|
|
37
|
-
************
|
|
38
|
-
|
|
39
|
-
- `Added` `tb push` displays warnings when using a reserved parameter in a pipe.
|
|
40
|
-
|
|
41
|
-
5.0.0.dev0
|
|
42
|
-
************
|
|
43
|
-
|
|
44
|
-
- `Changed` Make `insertion_date` column explicit. This column is no longer inferred, it must be present in the Data Source file.
|
|
45
|
-
|
|
46
|
-
4.1.2.dev0
|
|
47
|
-
************
|
|
48
|
-
|
|
49
|
-
- `Added` parameter to `tb pipe regression-test` --relative-change
|
|
50
|
-
|
|
51
|
-
|
|
52
35
|
4.1.1
|
|
53
36
|
************
|
|
54
37
|
|
|
@@ -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.0.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '5.0.1.dev0'
|
|
8
|
+
__revision__ = '2af0ad5'
|
|
@@ -4,6 +4,7 @@ LIVE_WS_NAME = "live"
|
|
|
4
4
|
SNAPSHOT_WS_NAME = "snapshot"
|
|
5
5
|
|
|
6
6
|
ENABLED_TABLE_FUNCTIONS = {"generateRandom", "null", "numbers", "numbers_mt", "values", "zeros", "zeros_mt"}
|
|
7
|
+
COPY_ENABLED_TABLE_FUNCTIONS = frozenset(["postgresql"])
|
|
7
8
|
|
|
8
9
|
ENABLED_SYSTEM_TABLES = {
|
|
9
10
|
"functions",
|
|
@@ -11,6 +11,7 @@ import requests.adapters
|
|
|
11
11
|
from requests import Response
|
|
12
12
|
from urllib3 import Retry
|
|
13
13
|
|
|
14
|
+
from tinybird.ch_utils.constants import COPY_ENABLED_TABLE_FUNCTIONS
|
|
14
15
|
from tinybird.syncasync import sync_to_async
|
|
15
16
|
from tinybird.tb_cli_modules.regions import fill_with_public_regions
|
|
16
17
|
from tinybird.tb_cli_modules.telemetry import add_telemetry_event
|
|
@@ -749,10 +750,12 @@ class TinyB(object):
|
|
|
749
750
|
async def delete_branch(self, id: str):
|
|
750
751
|
return await self._req(f"/v0/environments/{id}", method="DELETE")
|
|
751
752
|
|
|
752
|
-
async def add_users_to_workspace(self, workspace: Dict[str, Any], users_emails: List[str]):
|
|
753
|
+
async def add_users_to_workspace(self, workspace: Dict[str, Any], users_emails: List[str], role: Optional[str]):
|
|
753
754
|
users = ",".join(users_emails)
|
|
754
755
|
return await self._req(
|
|
755
|
-
f"/v0/workspaces/{workspace['id']}/users/",
|
|
756
|
+
f"/v0/workspaces/{workspace['id']}/users/",
|
|
757
|
+
method="PUT",
|
|
758
|
+
data={"operation": "add", "users": users, "role": role},
|
|
756
759
|
)
|
|
757
760
|
|
|
758
761
|
async def remove_users_from_workspace(self, workspace: Dict[str, Any], users_emails: List[str]):
|
|
@@ -1033,23 +1036,32 @@ class TinyB(object):
|
|
|
1033
1036
|
return result["q"]
|
|
1034
1037
|
|
|
1035
1038
|
@staticmethod
|
|
1036
|
-
def _sql_get_used_tables_local(sql: str, raising: bool = False) -> List[str]:
|
|
1039
|
+
def _sql_get_used_tables_local(sql: str, raising: bool = False, is_copy: Optional[bool] = False) -> List[str]:
|
|
1037
1040
|
from tinybird.sql_toolset import sql_get_used_tables
|
|
1038
1041
|
|
|
1039
|
-
tables = sql_get_used_tables(
|
|
1042
|
+
tables = sql_get_used_tables(
|
|
1043
|
+
sql, raising, table_functions=False, function_allow_list=COPY_ENABLED_TABLE_FUNCTIONS if is_copy else None
|
|
1044
|
+
)
|
|
1040
1045
|
return [t[1] if t[0] == "" else f"{t[0]}.{t[1]}" for t in tables]
|
|
1041
1046
|
|
|
1042
|
-
async def _sql_get_used_tables_remote(
|
|
1043
|
-
|
|
1047
|
+
async def _sql_get_used_tables_remote(
|
|
1048
|
+
self, sql: str, raising: bool = False, is_copy: Optional[bool] = False
|
|
1049
|
+
) -> List[str]:
|
|
1050
|
+
params = {
|
|
1051
|
+
"q": sql,
|
|
1052
|
+
"raising": "true" if raising else "false",
|
|
1053
|
+
"table_functions": "false",
|
|
1054
|
+
"is_copy": "true" if is_copy else "false",
|
|
1055
|
+
}
|
|
1044
1056
|
result = await self._req("/v0/sql_tables", data=params, method="POST")
|
|
1045
1057
|
return [t[1] if t[0] == "" else f"{t[0]}.{t[1]}" for t in result["tables"]]
|
|
1046
1058
|
|
|
1047
1059
|
# Get used tables from a query. Does not include table functions
|
|
1048
|
-
async def sql_get_used_tables(self, sql: str, raising: bool = False) -> List[str]:
|
|
1060
|
+
async def sql_get_used_tables(self, sql: str, raising: bool = False, is_copy: Optional[bool] = False) -> List[str]:
|
|
1049
1061
|
try:
|
|
1050
|
-
return self._sql_get_used_tables_local(sql, raising)
|
|
1062
|
+
return self._sql_get_used_tables_local(sql, raising, is_copy)
|
|
1051
1063
|
except ModuleNotFoundError:
|
|
1052
|
-
return await self._sql_get_used_tables_remote(sql, raising)
|
|
1064
|
+
return await self._sql_get_used_tables_remote(sql, raising, is_copy)
|
|
1053
1065
|
|
|
1054
1066
|
@staticmethod
|
|
1055
1067
|
def _replace_tables_local(q: str, replacements):
|
|
@@ -1476,6 +1476,7 @@ async def process_file(
|
|
|
1476
1476
|
deps = []
|
|
1477
1477
|
nodes: List[Dict[str, Any]] = []
|
|
1478
1478
|
|
|
1479
|
+
is_copy = any([node for node in doc.nodes if node.get("type", "standard").lower() == PipeNodeTypes.COPY])
|
|
1479
1480
|
for node in doc.nodes:
|
|
1480
1481
|
sql = node["sql"]
|
|
1481
1482
|
node_type = node.get("type", "standard").lower()
|
|
@@ -1504,7 +1505,7 @@ async def process_file(
|
|
|
1504
1505
|
sql_rendered = sql
|
|
1505
1506
|
|
|
1506
1507
|
try:
|
|
1507
|
-
dependencies = await tb_client.sql_get_used_tables(sql_rendered, raising=True)
|
|
1508
|
+
dependencies = await tb_client.sql_get_used_tables(sql_rendered, raising=True, is_copy=is_copy)
|
|
1508
1509
|
deps += [t for t in dependencies if t not in [n["name"] for n in doc.nodes]]
|
|
1509
1510
|
|
|
1510
1511
|
except Exception as e:
|
|
@@ -3,20 +3,26 @@ import logging
|
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from functools import lru_cache
|
|
6
|
-
from typing import Any, List, Optional, Set, Tuple
|
|
6
|
+
from typing import Any, FrozenSet, List, Optional, Set, Tuple
|
|
7
7
|
|
|
8
8
|
from chtoolset import query as chquery
|
|
9
9
|
from toposort import toposort
|
|
10
10
|
|
|
11
|
-
from tinybird.ch_utils.constants import ENABLED_TABLE_FUNCTIONS
|
|
11
|
+
from tinybird.ch_utils.constants import COPY_ENABLED_TABLE_FUNCTIONS, ENABLED_TABLE_FUNCTIONS
|
|
12
12
|
|
|
13
13
|
VALID_REMOTE = "VALID_REMOTE"
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class InvalidFunction(ValueError):
|
|
17
17
|
def __init__(self, msg: str = "", table_function_names: str = ""):
|
|
18
|
+
if any([fn for fn in COPY_ENABLED_TABLE_FUNCTIONS if fn in msg]):
|
|
19
|
+
msg = msg.replace("is restricted", "is restricted to Copy Pipes")
|
|
20
|
+
|
|
18
21
|
if table_function_names:
|
|
19
|
-
|
|
22
|
+
if "postgresql" in table_function_names:
|
|
23
|
+
self.msg = "The postgresql table function is only allowed in Copy Pipes"
|
|
24
|
+
else:
|
|
25
|
+
self.msg = f"The query uses disabled table functions: '{table_function_names}'"
|
|
20
26
|
else:
|
|
21
27
|
self.msg = msg
|
|
22
28
|
super().__init__(self.msg)
|
|
@@ -58,7 +64,11 @@ def format_where_for_mutation_command(where_clause: str) -> str:
|
|
|
58
64
|
|
|
59
65
|
@lru_cache(maxsize=2**13)
|
|
60
66
|
def sql_get_used_tables_cached(
|
|
61
|
-
sql: str,
|
|
67
|
+
sql: str,
|
|
68
|
+
raising: bool = False,
|
|
69
|
+
default_database: str = "",
|
|
70
|
+
table_functions: bool = True,
|
|
71
|
+
function_allow_list: Optional[FrozenSet[str]] = None,
|
|
62
72
|
) -> List[Tuple[str, str, str]]:
|
|
63
73
|
"""
|
|
64
74
|
>>> sql_get_used_tables("SELECT 1 FROM the_table")
|
|
@@ -79,7 +89,11 @@ def sql_get_used_tables_cached(
|
|
|
79
89
|
[('d_d3926a', 't_976af08ec4b547419e729c63e754b17b', '')]
|
|
80
90
|
"""
|
|
81
91
|
try:
|
|
82
|
-
|
|
92
|
+
_function_allow_list = list() if function_allow_list is None else list(function_allow_list)
|
|
93
|
+
|
|
94
|
+
tables: List[Tuple[str, str, str]] = chquery.tables(
|
|
95
|
+
sql, default_database=default_database, function_allow_list=_function_allow_list
|
|
96
|
+
)
|
|
83
97
|
if not table_functions:
|
|
84
98
|
return [(t[0], t[1], "") for t in tables if t[0] or t[1]]
|
|
85
99
|
return tables
|
|
@@ -93,10 +107,17 @@ def sql_get_used_tables_cached(
|
|
|
93
107
|
|
|
94
108
|
|
|
95
109
|
def sql_get_used_tables(
|
|
96
|
-
sql: str,
|
|
110
|
+
sql: str,
|
|
111
|
+
raising: bool = False,
|
|
112
|
+
default_database: str = "",
|
|
113
|
+
table_functions: bool = True,
|
|
114
|
+
function_allow_list: Optional[FrozenSet[str]] = None,
|
|
97
115
|
) -> List[Tuple[str, str, str]]:
|
|
98
|
-
|
|
99
|
-
|
|
116
|
+
hashable_list = frozenset() if function_allow_list is None else function_allow_list
|
|
117
|
+
|
|
118
|
+
return copy.copy(
|
|
119
|
+
sql_get_used_tables_cached(sql, raising, default_database, table_functions, function_allow_list=hashable_list)
|
|
120
|
+
)
|
|
100
121
|
|
|
101
122
|
|
|
102
123
|
class ReplacementsDict(dict):
|
|
@@ -150,9 +171,18 @@ def replace_tables_chquery_cached(
|
|
|
150
171
|
default_database: str = "",
|
|
151
172
|
output_one_line: bool = False,
|
|
152
173
|
timestamp: Optional[datetime] = None,
|
|
174
|
+
function_allow_list: Optional[FrozenSet[str]] = None,
|
|
153
175
|
) -> str:
|
|
154
176
|
replacements = dict(sorted_replacements) if sorted_replacements else {}
|
|
155
|
-
|
|
177
|
+
_function_allow_list = list() if function_allow_list is None else list(function_allow_list)
|
|
178
|
+
|
|
179
|
+
return chquery.replace_tables(
|
|
180
|
+
sql,
|
|
181
|
+
replacements,
|
|
182
|
+
default_database=default_database,
|
|
183
|
+
one_line=output_one_line,
|
|
184
|
+
function_allow_list=_function_allow_list,
|
|
185
|
+
)
|
|
156
186
|
|
|
157
187
|
|
|
158
188
|
def replace_tables(
|
|
@@ -164,15 +194,19 @@ def replace_tables(
|
|
|
164
194
|
valid_tables: Optional[Set[Tuple[str, str]]] = None,
|
|
165
195
|
output_one_line: bool = False,
|
|
166
196
|
timestamp: Optional[datetime] = None,
|
|
197
|
+
function_allow_list: Optional[FrozenSet[str]] = None,
|
|
167
198
|
) -> str:
|
|
168
199
|
"""
|
|
169
200
|
Given a query and a list of table replacements, returns the query after applying the table replacements.
|
|
170
201
|
It takes into account dependencies between replacement subqueries (if any)
|
|
171
202
|
It also validates the sql to verify it's valid and doesn't use unknown or prohibited functions
|
|
172
203
|
"""
|
|
204
|
+
hashable_list = frozenset() if function_allow_list is None else function_allow_list
|
|
173
205
|
if not replacements:
|
|
174
206
|
# Always call replace_tables to do validation and formatting
|
|
175
|
-
return replace_tables_chquery_cached(
|
|
207
|
+
return replace_tables_chquery_cached(
|
|
208
|
+
sql, None, output_one_line=output_one_line, timestamp=timestamp, function_allow_list=hashable_list
|
|
209
|
+
)
|
|
176
210
|
|
|
177
211
|
_replaced_with = set()
|
|
178
212
|
_replacements = ReplacementsDict()
|
|
@@ -182,14 +216,24 @@ def replace_tables(
|
|
|
182
216
|
_replaced_with.add(r)
|
|
183
217
|
|
|
184
218
|
deps: defaultdict = defaultdict(set)
|
|
185
|
-
_tables = sql_get_used_tables(
|
|
219
|
+
_tables = sql_get_used_tables(
|
|
220
|
+
sql,
|
|
221
|
+
default_database=default_database,
|
|
222
|
+
raising=True,
|
|
223
|
+
table_functions=check_functions,
|
|
224
|
+
function_allow_list=function_allow_list,
|
|
225
|
+
)
|
|
186
226
|
seen_tables = set()
|
|
187
227
|
table: Tuple[str, str] | Tuple[str, str, str]
|
|
228
|
+
if function_allow_list is None:
|
|
229
|
+
_enabled_table_functions = ENABLED_TABLE_FUNCTIONS
|
|
230
|
+
else:
|
|
231
|
+
_enabled_table_functions = ENABLED_TABLE_FUNCTIONS.union(set(function_allow_list))
|
|
188
232
|
while _tables:
|
|
189
233
|
table = _tables.pop()
|
|
190
234
|
if len(table) == 3:
|
|
191
235
|
first_table, second_table, last_table = table
|
|
192
|
-
if last_table and last_table not in
|
|
236
|
+
if last_table and last_table not in _enabled_table_functions:
|
|
193
237
|
raise InvalidFunction(table_function_names=last_table)
|
|
194
238
|
if first_table or second_table:
|
|
195
239
|
table = (first_table, second_table)
|
|
@@ -204,7 +248,7 @@ def replace_tables(
|
|
|
204
248
|
if len(dependent_table) == 3:
|
|
205
249
|
if (
|
|
206
250
|
dependent_table[2]
|
|
207
|
-
and dependent_table[2] not in
|
|
251
|
+
and dependent_table[2] not in _enabled_table_functions
|
|
208
252
|
and not (dependent_table[2] in ["cluster"] and replacement[0] == VALID_REMOTE)
|
|
209
253
|
):
|
|
210
254
|
raise InvalidFunction(table_function_names=dependent_table[2])
|
|
@@ -219,7 +263,9 @@ def replace_tables(
|
|
|
219
263
|
deps_sorted = list(reversed(list(toposort(deps))))
|
|
220
264
|
|
|
221
265
|
if not deps_sorted:
|
|
222
|
-
return replace_tables_chquery_cached(
|
|
266
|
+
return replace_tables_chquery_cached(
|
|
267
|
+
sql, None, output_one_line=output_one_line, timestamp=timestamp, function_allow_list=hashable_list
|
|
268
|
+
)
|
|
223
269
|
|
|
224
270
|
for current_deps in deps_sorted:
|
|
225
271
|
current_replacements = {}
|
|
@@ -251,10 +297,17 @@ def replace_tables(
|
|
|
251
297
|
# We need to transform the dictionary into something cacheable, so a sorted tuple of tuples it is
|
|
252
298
|
r = tuple(sorted([(k, v) for k, v in current_replacements.items()]))
|
|
253
299
|
sql = replace_tables_chquery_cached(
|
|
254
|
-
sql,
|
|
300
|
+
sql,
|
|
301
|
+
r,
|
|
302
|
+
default_database=default_database,
|
|
303
|
+
output_one_line=output_one_line,
|
|
304
|
+
timestamp=timestamp,
|
|
305
|
+
function_allow_list=hashable_list,
|
|
255
306
|
)
|
|
256
307
|
else:
|
|
257
|
-
sql = replace_tables_chquery_cached(
|
|
308
|
+
sql = replace_tables_chquery_cached(
|
|
309
|
+
sql, None, output_one_line=output_one_line, timestamp=timestamp, function_allow_list=hashable_list
|
|
310
|
+
)
|
|
258
311
|
|
|
259
312
|
return sql
|
|
260
313
|
|
{tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/workspace_members.py
RENAMED
|
@@ -22,6 +22,8 @@ from tinybird.tb_cli_modules.common import (
|
|
|
22
22
|
from tinybird.tb_cli_modules.exceptions import CLIWorkspaceMembersException
|
|
23
23
|
from tinybird.tb_cli_modules.workspace import workspace
|
|
24
24
|
|
|
25
|
+
ROLES = ["viewer", "guest", "admin"]
|
|
26
|
+
|
|
25
27
|
|
|
26
28
|
@dataclass
|
|
27
29
|
class WorkspaceMemberCommandContext:
|
|
@@ -55,10 +57,13 @@ def members(ctx: Context) -> None:
|
|
|
55
57
|
|
|
56
58
|
@members.command(name="add", short_help="Adds members to the current Workspace")
|
|
57
59
|
@click.argument("members_emails")
|
|
60
|
+
@click.option("--role", is_flag=False, default=None, help="Role for the members being added", type=click.Choice(ROLES))
|
|
58
61
|
@click.option("--user_token", is_flag=False, default=None, help="When passed, we won't prompt asking for it")
|
|
59
62
|
@click.pass_context
|
|
60
63
|
@coro
|
|
61
|
-
async def add_members_to_workspace(
|
|
64
|
+
async def add_members_to_workspace(
|
|
65
|
+
ctx: Context, members_emails: str, user_token: Optional[str], role: Optional[str]
|
|
66
|
+
) -> None:
|
|
62
67
|
"""Adds members to the current Workspace."""
|
|
63
68
|
|
|
64
69
|
cmd_ctx = await get_command_context(ctx)
|
|
@@ -79,7 +84,7 @@ async def add_members_to_workspace(ctx: Context, members_emails: str, user_token
|
|
|
79
84
|
|
|
80
85
|
user_client: TinyB = deepcopy(cmd_ctx.client)
|
|
81
86
|
user_client.token = user_token
|
|
82
|
-
await user_client.add_users_to_workspace(cmd_ctx.workspace, users_to_add)
|
|
87
|
+
await user_client.add_users_to_workspace(cmd_ctx.workspace, users_to_add, role)
|
|
83
88
|
msg = (
|
|
84
89
|
FeedbackManager.success_workspace_user_added(user=users_to_add[0], workspace_name=cmd_ctx.workspace["name"])
|
|
85
90
|
if len(users_to_add) == 1
|
|
@@ -149,7 +154,7 @@ async def remove_members_from_workspace(ctx: Context, members_emails: str, user_
|
|
|
149
154
|
|
|
150
155
|
|
|
151
156
|
@members.command(name="set-role", short_help="Sets the role for existing workspace members")
|
|
152
|
-
@click.argument("role", required=True, type=click.Choice(
|
|
157
|
+
@click.argument("role", required=True, type=click.Choice(ROLES))
|
|
153
158
|
@click.argument("members_emails", required=True, type=str)
|
|
154
159
|
@click.option("--user_token", is_flag=False, default=None, help="When passed, we won't prompt asking for it")
|
|
155
160
|
@click.pass_context
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tinybird-cli
|
|
3
|
-
Version: 5.0.
|
|
3
|
+
Version: 5.0.1.dev0
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/cli/introduction.html
|
|
6
6
|
Author: Tinybird
|
|
@@ -18,37 +18,20 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
18
18
|
Changelog
|
|
19
19
|
----------
|
|
20
20
|
|
|
21
|
-
5.0.0
|
|
22
|
-
|
|
21
|
+
5.0.0
|
|
22
|
+
******
|
|
23
23
|
|
|
24
|
-
- `
|
|
24
|
+
- `Breaking change` Make `insertion_date` column explicit. This column is no longer inferred, it must be present in the Data Source file.
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
************
|
|
26
|
+
Detailed info at https://www.tinybird.co/docs/changelog/2024-06-17-insertion_date-deprecation
|
|
28
27
|
|
|
28
|
+
- `Added` parameter to `tb pipe regression-test` --relative-change
|
|
29
|
+
- `Added` `tb push` displays warnings when using a reserved parameter in a pipe.
|
|
30
|
+
- `Added` --role parameter to `tb workspace members add`
|
|
29
31
|
- `Changed` Point region hosts to new `app.tinybird.co` domain
|
|
30
|
-
|
|
31
|
-
5.0.0.dev2
|
|
32
|
-
************
|
|
33
|
-
|
|
32
|
+
- `Improved` help message of `tb workspace members set-role` now displays the 3 valid roles: viewer|guest|admin.
|
|
34
33
|
- `Improved` syntax error messages when parsing endpoints.
|
|
35
34
|
|
|
36
|
-
5.0.0.dev1
|
|
37
|
-
************
|
|
38
|
-
|
|
39
|
-
- `Added` `tb push` displays warnings when using a reserved parameter in a pipe.
|
|
40
|
-
|
|
41
|
-
5.0.0.dev0
|
|
42
|
-
************
|
|
43
|
-
|
|
44
|
-
- `Changed` Make `insertion_date` column explicit. This column is no longer inferred, it must be present in the Data Source file.
|
|
45
|
-
|
|
46
|
-
4.1.2.dev0
|
|
47
|
-
************
|
|
48
|
-
|
|
49
|
-
- `Added` parameter to `tb pipe regression-test` --relative-change
|
|
50
|
-
|
|
51
|
-
|
|
52
35
|
4.1.1
|
|
53
36
|
************
|
|
54
37
|
|
|
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.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit.py
RENAMED
|
File without changes
|
{tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird-cli-5.0.0.dev4 → tinybird-cli-5.0.1.dev0}/tinybird_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|