tinybird-cli 5.13.3.dev1__tar.gz → 5.14.0.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.13.3.dev1 → tinybird_cli-5.14.0.dev0}/PKG-INFO +13 -2
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/__cli__.py +2 -2
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/client.py +1 -1
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/connectors.py +3 -3
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/datafile.py +13 -11
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/feedback_manager.py +1 -1
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/sql.py +4 -4
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/sql_template_fmt.py +1 -1
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/sql_toolset.py +9 -2
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/cli.py +2 -2
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/common.py +20 -18
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/pipe.py +1 -1
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +1 -1
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tornado_template.py +2 -2
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird_cli.egg-info/PKG-INFO +13 -2
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/setup.cfg +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/ch_utils/constants.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/ch_utils/engine.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/check_pypi.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/config.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/context.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/datatypes.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/git_settings.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/sql_template.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/syncasync.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/token.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird_cli.egg-info/SOURCES.txt +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird_cli.egg-info/dependency_links.txt +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird_cli.egg-info/entry_points.txt +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird_cli.egg-info/requires.txt +0 -0
- {tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.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.
|
|
3
|
+
Version: 5.14.0.dev0
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/cli
|
|
6
6
|
Author: Tinybird
|
|
@@ -18,14 +18,25 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
18
18
|
Changelog
|
|
19
19
|
----------
|
|
20
20
|
|
|
21
|
-
5.
|
|
21
|
+
5.14.0.dev0
|
|
22
|
+
***********
|
|
23
|
+
|
|
24
|
+
- `Added` support for `KAFKA_KEY_FORMAT` and `KAFKA_VALUE_FORMAT` parameters for kafka datasources.
|
|
25
|
+
|
|
26
|
+
5.13.3
|
|
22
27
|
***********
|
|
23
28
|
|
|
24
29
|
- `Fixed` updating the cron schedule of a BigQuery data source when having a query but no external_data_source setting.
|
|
30
|
+
- `Fixed` handle Kafka connector with multiple brokers properly.
|
|
25
31
|
|
|
26
32
|
5.13.2
|
|
27
33
|
***********
|
|
28
34
|
|
|
35
|
+
- `Fixed` Correctly handle Kafka connector with multiple brokers
|
|
36
|
+
|
|
37
|
+
5.13.1.dev2
|
|
38
|
+
***********
|
|
39
|
+
|
|
29
40
|
- `Added` comply with [PEP 625](https://peps.python.org/pep-0625/)
|
|
30
41
|
- `Added` `eu-west-1` region to the list of available regions.
|
|
31
42
|
|
|
@@ -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.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '5.14.0.dev0'
|
|
8
|
+
__revision__ = '643b049'
|
|
@@ -72,7 +72,7 @@ def parse_error_response(response: Response) -> str:
|
|
|
72
72
|
if content.get("error", None):
|
|
73
73
|
error = content["error"]
|
|
74
74
|
if content.get("errors", None):
|
|
75
|
-
error += f
|
|
75
|
+
error += f" -> errors: {content.get('errors')}"
|
|
76
76
|
else:
|
|
77
77
|
error = json.dumps(response, indent=4)
|
|
78
78
|
return error
|
|
@@ -246,7 +246,7 @@ class BigQuery(Connector):
|
|
|
246
246
|
uri='{self.gcs.gs_url()}{destination}*.csv',
|
|
247
247
|
format='CSV',
|
|
248
248
|
overwrite=true,
|
|
249
|
-
header={
|
|
249
|
+
header={"true" if with_headers else "false"},
|
|
250
250
|
field_delimiter=',') AS
|
|
251
251
|
{sql}
|
|
252
252
|
"""
|
|
@@ -319,7 +319,7 @@ class Snowflake(Connector):
|
|
|
319
319
|
|
|
320
320
|
def create_stage(self):
|
|
321
321
|
sql = f"""
|
|
322
|
-
create stage "{self.options[
|
|
322
|
+
create stage "{self.options["schema"]}".{self.stage()}
|
|
323
323
|
url='{self.gcs.gcs_url()}'
|
|
324
324
|
storage_integration = {self.storage_integration()};
|
|
325
325
|
"""
|
|
@@ -337,7 +337,7 @@ class Snowflake(Connector):
|
|
|
337
337
|
from ({sql})
|
|
338
338
|
overwrite = true
|
|
339
339
|
file_format = (TYPE=CSV COMPRESSION=NONE ESCAPE_UNENCLOSED_FIELD=NONE FIELD_DELIMITER='|' FIELD_OPTIONALLY_ENCLOSED_BY='"' null_if=())
|
|
340
|
-
header = {"true" if with_headers else "false"
|
|
340
|
+
header = {"true" if with_headers else "false"}
|
|
341
341
|
max_file_size = 2500000000;
|
|
342
342
|
"""
|
|
343
343
|
self.execute(sql)
|
|
@@ -1218,6 +1218,8 @@ def parse(
|
|
|
1218
1218
|
"kafka_store_raw_value": assign_var("kafka_store_raw_value"),
|
|
1219
1219
|
"kafka_store_headers": assign_var("kafka_store_headers"),
|
|
1220
1220
|
"kafka_store_binary_headers": assign_var("kafka_store_binary_headers"),
|
|
1221
|
+
"kafka_key_format": assign_var("kafka_key_format"),
|
|
1222
|
+
"kafka_value_format": assign_var("kafka_value_format"),
|
|
1221
1223
|
"kafka_key_avro_deserialization": assign_var("kafka_key_avro_deserialization"),
|
|
1222
1224
|
"kafka_ssl_ca_pem": assign_var("kafka_ssl_ca_pem"),
|
|
1223
1225
|
"kafka_sasl_mechanism": assign_var("kafka_sasl_mechanism"),
|
|
@@ -2175,8 +2177,8 @@ class PipeCheckerRunner:
|
|
|
2175
2177
|
AND extractURLParameter(assumeNotNull(url), 'debug') <> 'query'
|
|
2176
2178
|
AND error = 0
|
|
2177
2179
|
AND not mapContains(parameters, '__tb__semver')
|
|
2178
|
-
{" AND " + " AND ".join([f"mapContains(pipe_request_params, '{match}')" for match in matches]) if matches and len(matches) > 0 else
|
|
2179
|
-
{
|
|
2180
|
+
{" AND " + " AND ".join([f"mapContains(pipe_request_params, '{match}')" for match in matches]) if matches and len(matches) > 0 else ""}
|
|
2181
|
+
{extra_where_clause}
|
|
2180
2182
|
Limit 5000000 -- Enough to bring data while not processing all requests from highly used pipes
|
|
2181
2183
|
)
|
|
2182
2184
|
group by request_param_names, http_method
|
|
@@ -2202,7 +2204,7 @@ class PipeCheckerRunner:
|
|
|
2202
2204
|
AND extractURLParameter(assumeNotNull(url), 'debug') <> 'query'
|
|
2203
2205
|
AND error = 0
|
|
2204
2206
|
AND not mapContains(parameters, '__tb__semver')
|
|
2205
|
-
{" AND " + " AND ".join([f"mapContains(pipe_request_params, '{match}')" for match in matches]) if matches and len(matches) > 0 else
|
|
2207
|
+
{" AND " + " AND ".join([f"mapContains(pipe_request_params, '{match}')" for match in matches]) if matches and len(matches) > 0 else ""}
|
|
2206
2208
|
{extra_where_clause}
|
|
2207
2209
|
LIMIT {limit}
|
|
2208
2210
|
)
|
|
@@ -4425,7 +4427,7 @@ async def folder_push(
|
|
|
4425
4427
|
name=(
|
|
4426
4428
|
name
|
|
4427
4429
|
if to_run[name]["version"] is None
|
|
4428
|
-
else f
|
|
4430
|
+
else f"{name}__v{to_run[name]['version']}"
|
|
4429
4431
|
)
|
|
4430
4432
|
)
|
|
4431
4433
|
)
|
|
@@ -4442,7 +4444,7 @@ async def folder_push(
|
|
|
4442
4444
|
if raise_on_exists:
|
|
4443
4445
|
raise AlreadyExistsException(
|
|
4444
4446
|
FeedbackManager.warning_name_already_exists(
|
|
4445
|
-
name=name if to_run[name]["version"] is None else f
|
|
4447
|
+
name=name if to_run[name]["version"] is None else f"{name}__v{to_run[name]['version']}"
|
|
4446
4448
|
)
|
|
4447
4449
|
)
|
|
4448
4450
|
else:
|
|
@@ -4457,7 +4459,7 @@ async def folder_push(
|
|
|
4457
4459
|
name=(
|
|
4458
4460
|
name
|
|
4459
4461
|
if to_run[name]["version"] is None
|
|
4460
|
-
else f
|
|
4462
|
+
else f"{name}__v{to_run[name]['version']}"
|
|
4461
4463
|
)
|
|
4462
4464
|
)
|
|
4463
4465
|
)
|
|
@@ -5013,7 +5015,7 @@ async def format_engine(
|
|
|
5013
5015
|
else:
|
|
5014
5016
|
if node.get("engine", None):
|
|
5015
5017
|
empty = '""'
|
|
5016
|
-
file_parts.append(f
|
|
5018
|
+
file_parts.append(f"ENGINE {node['engine']['type']}" if node.get("engine", {}).get("type") else empty)
|
|
5017
5019
|
file_parts.append(DATAFILE_NEW_LINE)
|
|
5018
5020
|
for arg in sorted(node["engine"].get("args", [])):
|
|
5019
5021
|
elem = ", ".join([x.strip() for x in arg[1].split(",")])
|
|
@@ -5030,7 +5032,7 @@ async def format_node_type(file_parts: List[str], node: Dict[str, Any]) -> List[
|
|
|
5030
5032
|
if node_type == PipeNodeTypes.MATERIALIZED:
|
|
5031
5033
|
file_parts.append(node_type_upper)
|
|
5032
5034
|
file_parts.append(DATAFILE_NEW_LINE)
|
|
5033
|
-
file_parts.append(f
|
|
5035
|
+
file_parts.append(f"DATASOURCE {node['datasource']}")
|
|
5034
5036
|
file_parts.append(DATAFILE_NEW_LINE)
|
|
5035
5037
|
await format_engine(file_parts, node)
|
|
5036
5038
|
|
|
@@ -5038,10 +5040,10 @@ async def format_node_type(file_parts: List[str], node: Dict[str, Any]) -> List[
|
|
|
5038
5040
|
if node_type == PipeNodeTypes.COPY:
|
|
5039
5041
|
file_parts.append(node_type_upper)
|
|
5040
5042
|
file_parts.append(DATAFILE_NEW_LINE)
|
|
5041
|
-
file_parts.append(f
|
|
5043
|
+
file_parts.append(f"TARGET_DATASOURCE {node['target_datasource']}")
|
|
5042
5044
|
if node.get("mode"):
|
|
5043
5045
|
file_parts.append(DATAFILE_NEW_LINE)
|
|
5044
|
-
file_parts.append(f
|
|
5046
|
+
file_parts.append(f"COPY_MODE {node.get('mode')}")
|
|
5045
5047
|
|
|
5046
5048
|
if node.get(CopyParameters.COPY_SCHEDULE):
|
|
5047
5049
|
is_ondemand = node[CopyParameters.COPY_SCHEDULE].lower() == ON_DEMAND
|
|
@@ -5095,7 +5097,7 @@ async def format_node(
|
|
|
5095
5097
|
if item and not unroll_includes:
|
|
5096
5098
|
return
|
|
5097
5099
|
|
|
5098
|
-
file_parts.append(f
|
|
5100
|
+
file_parts.append(f"NODE {node['name'].strip()}")
|
|
5099
5101
|
file_parts.append(DATAFILE_NEW_LINE)
|
|
5100
5102
|
|
|
5101
5103
|
from collections import namedtuple
|
|
@@ -951,7 +951,7 @@ Ready? """
|
|
|
951
951
|
)
|
|
952
952
|
success_datasource_alter = success_message("** The Data Source has been correctly updated.")
|
|
953
953
|
success_datasource_kafka_connected = success_message(
|
|
954
|
-
"** Data Source '{id}' created\n
|
|
954
|
+
"** Data Source '{id}' created\n** Kafka streaming connection configured successfully!"
|
|
955
955
|
)
|
|
956
956
|
success_datasource_shared = success_message(
|
|
957
957
|
"** The Data Source {datasource} has been correctly shared with {workspace}"
|
|
@@ -86,7 +86,7 @@ def get_format(sql: str) -> Optional[str]:
|
|
|
86
86
|
"""
|
|
87
87
|
FORMAT_RE = r"\s+format\s+(\w+)\s*$"
|
|
88
88
|
sql = sql.strip()
|
|
89
|
-
format = re.findall(FORMAT_RE, sql, re.
|
|
89
|
+
format = re.findall(FORMAT_RE, sql, re.IGNORECASE)
|
|
90
90
|
return format[0] if format else None
|
|
91
91
|
|
|
92
92
|
|
|
@@ -100,7 +100,7 @@ def get_format_group(sql: str) -> str:
|
|
|
100
100
|
"""
|
|
101
101
|
FORMAT_RE = r"\s+format\s+(\w+)\s*$"
|
|
102
102
|
sql = sql.strip()
|
|
103
|
-
format = re.search(FORMAT_RE, sql, re.
|
|
103
|
+
format = re.search(FORMAT_RE, sql, re.IGNORECASE)
|
|
104
104
|
return format.group() if format else ""
|
|
105
105
|
|
|
106
106
|
|
|
@@ -135,7 +135,7 @@ def remove_format(sql: str) -> str:
|
|
|
135
135
|
"""
|
|
136
136
|
FORMAT_RE = r"\s+(format)\s+(\w+)\s*$"
|
|
137
137
|
sql = sql.strip()
|
|
138
|
-
return re.sub(FORMAT_RE, "", sql, flags=re.
|
|
138
|
+
return re.sub(FORMAT_RE, "", sql, flags=re.IGNORECASE)
|
|
139
139
|
|
|
140
140
|
|
|
141
141
|
def col_name(name: str, backquotes: bool = True) -> str:
|
|
@@ -241,7 +241,7 @@ def format_parse_error(
|
|
|
241
241
|
message += f" found at position {adjusted_position - len(keyword)}"
|
|
242
242
|
else:
|
|
243
243
|
message += (
|
|
244
|
-
f" found {repr(table_structure[i]) if len(table_structure)>i else 'EOF'} at position {adjusted_position}"
|
|
244
|
+
f" found {repr(table_structure[i]) if len(table_structure) > i else 'EOF'} at position {adjusted_position}"
|
|
245
245
|
)
|
|
246
246
|
return message
|
|
247
247
|
|
|
@@ -100,7 +100,7 @@ def _format_jinja_node(self, node: Node, max_length: int) -> bool:
|
|
|
100
100
|
parts = tag.code.split("\n")
|
|
101
101
|
prefix = INDENT * (node.depth[0] + node.depth[1])
|
|
102
102
|
if len(parts) > 1:
|
|
103
|
-
tag.code = "\n".join([f
|
|
103
|
+
tag.code = "\n".join([f"{prefix if i != 0 else ''}{part}" for i, part in enumerate(parts)])
|
|
104
104
|
|
|
105
105
|
node.value = str(tag)
|
|
106
106
|
|
|
@@ -3,7 +3,7 @@ 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
|
|
6
|
+
from typing import FrozenSet, List, Optional, Set, Tuple
|
|
7
7
|
|
|
8
8
|
from chtoolset import query as chquery
|
|
9
9
|
from toposort import toposort
|
|
@@ -172,7 +172,7 @@ def tables_or_sql(replacement: dict, table_functions=False) -> set:
|
|
|
172
172
|
return {replacement}
|
|
173
173
|
|
|
174
174
|
|
|
175
|
-
def _separate_as_tuple_if_contains_database_and_table(definition: str) ->
|
|
175
|
+
def _separate_as_tuple_if_contains_database_and_table(definition: str) -> str | Tuple[str, str]:
|
|
176
176
|
if "." in definition:
|
|
177
177
|
database_and_table_separated = definition.split(".")
|
|
178
178
|
return database_and_table_separated[0], database_and_table_separated[1]
|
|
@@ -219,6 +219,7 @@ def replace_tables(
|
|
|
219
219
|
output_one_line: bool = False,
|
|
220
220
|
timestamp: Optional[datetime] = None,
|
|
221
221
|
function_allow_list: Optional[FrozenSet[str]] = None,
|
|
222
|
+
original_replacements: Optional[dict] = None,
|
|
222
223
|
) -> str:
|
|
223
224
|
"""
|
|
224
225
|
Given a query and a list of table replacements, returns the query after applying the table replacements.
|
|
@@ -239,6 +240,12 @@ def replace_tables(
|
|
|
239
240
|
_replacements[rk] = r if isinstance(r, tuple) else (default_database, r)
|
|
240
241
|
_replaced_with.add(r)
|
|
241
242
|
|
|
243
|
+
if original_replacements:
|
|
244
|
+
# Some replacements have been expanded by filters and turned to a query str, but we need to send the original
|
|
245
|
+
# ones to is_invalid_resource()
|
|
246
|
+
for r in original_replacements.values():
|
|
247
|
+
_replaced_with.add(r)
|
|
248
|
+
|
|
242
249
|
deps: defaultdict = defaultdict(set)
|
|
243
250
|
_tables = sql_get_used_tables(
|
|
244
251
|
sql,
|
|
@@ -1053,7 +1053,7 @@ async def materialize(
|
|
|
1053
1053
|
return node, node_name
|
|
1054
1054
|
|
|
1055
1055
|
def _choose_target_datasource_name(pipe, node, node_name):
|
|
1056
|
-
return target_datasource or node.get("datasource", None) or f
|
|
1056
|
+
return target_datasource or node.get("datasource", None) or f"mv_{pipe['resource_name']}_{node_name}"
|
|
1057
1057
|
|
|
1058
1058
|
def _save_local_backup_pipe(pipe):
|
|
1059
1059
|
pipe_bak = f"{filename}_bak"
|
|
@@ -1231,7 +1231,7 @@ def __patch_click_output():
|
|
|
1231
1231
|
if isinstance(substitution, str):
|
|
1232
1232
|
msg = re.sub(pattern, substitution, str(msg))
|
|
1233
1233
|
else:
|
|
1234
|
-
msg = re.sub(pattern, lambda m: substitution(m.group(0)), str(msg)) # noqa
|
|
1234
|
+
msg = re.sub(pattern, lambda m: substitution(m.group(0)), str(msg)) # noqa: B023
|
|
1235
1235
|
return msg
|
|
1236
1236
|
|
|
1237
1237
|
def _obfuscate_echo(msg: Any, *args: Any, **kwargs: Any) -> None:
|
|
@@ -1252,26 +1252,28 @@ def is_url_valid(url):
|
|
|
1252
1252
|
return False
|
|
1253
1253
|
|
|
1254
1254
|
|
|
1255
|
-
def validate_kafka_bootstrap_servers(
|
|
1256
|
-
if not isinstance(
|
|
1255
|
+
def validate_kafka_bootstrap_servers(bootstrap_servers):
|
|
1256
|
+
if not isinstance(bootstrap_servers, str):
|
|
1257
1257
|
raise CLIException(FeedbackManager.error_kafka_bootstrap_server())
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
except Exception:
|
|
1266
|
-
raise CLIException(FeedbackManager.error_kafka_bootstrap_server())
|
|
1267
|
-
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
|
|
1258
|
+
|
|
1259
|
+
for host_and_port in bootstrap_servers.split(","):
|
|
1260
|
+
parts = host_and_port.split(":")
|
|
1261
|
+
if len(parts) > 2:
|
|
1262
|
+
raise CLIException(FeedbackManager.error_kafka_bootstrap_server())
|
|
1263
|
+
host = parts[0]
|
|
1264
|
+
port_str = parts[1] if len(parts) == 2 else "9092"
|
|
1268
1265
|
try:
|
|
1269
|
-
|
|
1270
|
-
sock.connect((host, port))
|
|
1271
|
-
except socket.timeout:
|
|
1272
|
-
raise CLIException(FeedbackManager.error_kafka_bootstrap_server_conn_timeout())
|
|
1266
|
+
port = int(port_str)
|
|
1273
1267
|
except Exception:
|
|
1274
|
-
raise CLIException(FeedbackManager.
|
|
1268
|
+
raise CLIException(FeedbackManager.error_kafka_bootstrap_server())
|
|
1269
|
+
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
|
|
1270
|
+
try:
|
|
1271
|
+
sock.settimeout(3)
|
|
1272
|
+
sock.connect((host, port))
|
|
1273
|
+
except socket.timeout:
|
|
1274
|
+
raise CLIException(FeedbackManager.error_kafka_bootstrap_server_conn_timeout())
|
|
1275
|
+
except Exception:
|
|
1276
|
+
raise CLIException(FeedbackManager.error_kafka_bootstrap_server_conn())
|
|
1275
1277
|
|
|
1276
1278
|
|
|
1277
1279
|
def validate_kafka_key(s):
|
|
@@ -1588,7 +1590,7 @@ async def try_update_config_with_remote(
|
|
|
1588
1590
|
def ask_for_admin_token_interactively(ui_host: str, default_token: Optional[str]) -> str:
|
|
1589
1591
|
return (
|
|
1590
1592
|
click.prompt(
|
|
1591
|
-
f
|
|
1593
|
+
f'\nCopy the "admin your@email" token from {ui_host}/tokens and paste it here {"OR press enter to use the token from .tinyb file" if default_token else ""}',
|
|
1592
1594
|
hide_input=True,
|
|
1593
1595
|
show_default=False,
|
|
1594
1596
|
default=default_token,
|
|
@@ -117,7 +117,7 @@ async def pipe_stats(ctx: click.Context, pipes: Tuple[str, ...], format_: str):
|
|
|
117
117
|
sumIf(error_count, date > now() - interval 7 day) errors,
|
|
118
118
|
avgMergeIf(avg_duration_state, date > now() - interval 7 day) latency
|
|
119
119
|
FROM tinybird.pipe_stats
|
|
120
|
-
WHERE pipe_id in ({
|
|
120
|
+
WHERE pipe_id in ({",".join(pipes_to_get_stats)})
|
|
121
121
|
GROUP BY pipe_id
|
|
122
122
|
ORDER BY requests DESC
|
|
123
123
|
FORMAT JSON
|
{tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit.py
RENAMED
|
@@ -155,7 +155,7 @@ def parse_file(file: str) -> Iterable[TestCase]:
|
|
|
155
155
|
)
|
|
156
156
|
except Exception as e:
|
|
157
157
|
raise CLIException(
|
|
158
|
-
f"""Error: {FeedbackManager.error_exception(error=e)} reading file, check "{file}"->"{definition.get(
|
|
158
|
+
f"""Error: {FeedbackManager.error_exception(error=e)} reading file, check "{file}"->"{definition.get("name")}" """
|
|
159
159
|
)
|
|
160
160
|
|
|
161
161
|
|
|
@@ -370,7 +370,7 @@ class Template:
|
|
|
370
370
|
for chunk in self.file.body.chunks:
|
|
371
371
|
if isinstance(chunk, _ExtendsBlock):
|
|
372
372
|
if not loader:
|
|
373
|
-
raise ParseError("{% extends %} block found, but no
|
|
373
|
+
raise ParseError("{% extends %} block found, but no template loader")
|
|
374
374
|
template = loader.load(chunk.name, self.name)
|
|
375
375
|
ancestors.extend(template._get_ancestors(loader))
|
|
376
376
|
return ancestors
|
|
@@ -633,7 +633,7 @@ class _Expression(_Node):
|
|
|
633
633
|
|
|
634
634
|
def generate(self, writer):
|
|
635
635
|
writer.write_line("_tt_tmp = %s" % self.expression, self.line)
|
|
636
|
-
writer.write_line("if isinstance(_tt_tmp, _tt_string_types):
|
|
636
|
+
writer.write_line("if isinstance(_tt_tmp, _tt_string_types): _tt_tmp = _tt_utf8(_tt_tmp)", self.line)
|
|
637
637
|
writer.write_line("else: _tt_tmp = _tt_utf8(str(_tt_tmp))", self.line)
|
|
638
638
|
if not self.raw and writer.current_template.autoescape is not None:
|
|
639
639
|
# In python3 functions like xhtml_escape return unicode,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tinybird-cli
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.14.0.dev0
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/cli
|
|
6
6
|
Author: Tinybird
|
|
@@ -18,14 +18,25 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
18
18
|
Changelog
|
|
19
19
|
----------
|
|
20
20
|
|
|
21
|
-
5.
|
|
21
|
+
5.14.0.dev0
|
|
22
|
+
***********
|
|
23
|
+
|
|
24
|
+
- `Added` support for `KAFKA_KEY_FORMAT` and `KAFKA_VALUE_FORMAT` parameters for kafka datasources.
|
|
25
|
+
|
|
26
|
+
5.13.3
|
|
22
27
|
***********
|
|
23
28
|
|
|
24
29
|
- `Fixed` updating the cron schedule of a BigQuery data source when having a query but no external_data_source setting.
|
|
30
|
+
- `Fixed` handle Kafka connector with multiple brokers properly.
|
|
25
31
|
|
|
26
32
|
5.13.2
|
|
27
33
|
***********
|
|
28
34
|
|
|
35
|
+
- `Fixed` Correctly handle Kafka connector with multiple brokers
|
|
36
|
+
|
|
37
|
+
5.13.1.dev2
|
|
38
|
+
***********
|
|
39
|
+
|
|
29
40
|
- `Added` comply with [PEP 625](https://peps.python.org/pep-0625/)
|
|
30
41
|
- `Added` `eu-west-1` region to the list of available regions.
|
|
31
42
|
|
|
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.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird/tb_cli_modules/workspace_members.py
RENAMED
|
File without changes
|
|
File without changes
|
{tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{tinybird_cli-5.13.3.dev1 → tinybird_cli-5.14.0.dev0}/tinybird_cli.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|