tinybird 0.0.1.dev69__tar.gz → 0.0.1.dev71__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.
Potentially problematic release.
This version of tinybird might be problematic. Click here for more details.
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/PKG-INFO +1 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/client.py +5 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/sql_template.py +38 -5
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/__cli__.py +2 -2
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/build.py +12 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/cli.py +16 -5
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/common.py +3 -3
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/config.py +2 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/fixture.py +7 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datasource.py +63 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/deployment.py +18 -4
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/local_common.py +2 -2
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/mock.py +26 -18
- {tinybird-0.0.1.dev69/tinybird/tb_cli_modules → tinybird-0.0.1.dev71/tinybird/tb/modules}/telemetry.py +1 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/test.py +2 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -2
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/watch.py +1 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/cli.py +0 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/common.py +1 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/pipe.py +0 -1
- {tinybird-0.0.1.dev69/tinybird/tb/modules → tinybird-0.0.1.dev71/tinybird/tb_cli_modules}/telemetry.py +1 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -2
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tornado_template.py +1 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird.egg-info/PKG-INFO +1 -1
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/setup.cfg +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/__cli__.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/ch_utils/engine.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/check_pypi.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/config.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/connectors.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/context.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/datafile.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/datatypes.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/feedback_manager.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/git_settings.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/prompts.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/sql.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/sql_toolset.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/syncasync.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/cli.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/auth.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/cicd.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/copy.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/create.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/build.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/build_common.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/common.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/diff.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/exceptions.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/format_common.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/parse_datasource.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/parse_pipe.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/pull.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/endpoint.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/exceptions.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/feedback_manager.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/fmt.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/job.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/llm.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/llm_utils.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/local.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/login.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/materialization.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/pipe.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/project.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/regions.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/shell.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/table.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/tag.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/token.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/workspace.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/workspace_members.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird.egg-info/SOURCES.txt +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird.egg-info/dependency_links.txt +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird.egg-info/entry_points.txt +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird.egg-info/requires.txt +0 -0
- {tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird.egg-info/top_level.txt +0 -0
|
@@ -93,6 +93,7 @@ class TinyB:
|
|
|
93
93
|
send_telemetry: bool = False,
|
|
94
94
|
semver: Optional[str] = None,
|
|
95
95
|
env: Optional[str] = "production",
|
|
96
|
+
preview: bool = False,
|
|
96
97
|
):
|
|
97
98
|
ctx = ssl.create_default_context()
|
|
98
99
|
ctx.check_hostname = False
|
|
@@ -105,6 +106,7 @@ class TinyB:
|
|
|
105
106
|
self.send_telemetry = send_telemetry
|
|
106
107
|
self.semver = semver
|
|
107
108
|
self.env = env
|
|
109
|
+
self.preview = preview
|
|
108
110
|
|
|
109
111
|
async def _req_raw(
|
|
110
112
|
self,
|
|
@@ -125,6 +127,8 @@ class TinyB:
|
|
|
125
127
|
url += ("&" if "?" in url else "?") + "cli_version=" + quote(self.version)
|
|
126
128
|
if self.semver:
|
|
127
129
|
url += ("&" if "?" in url else "?") + "__tb__semver=" + self.semver
|
|
130
|
+
if self.preview:
|
|
131
|
+
url += ("&" if "?" in url else "?") + "__tb__deployment=preview"
|
|
128
132
|
|
|
129
133
|
verify_ssl = not self.disable_ssl_checks
|
|
130
134
|
try:
|
|
@@ -197,7 +201,7 @@ class TinyB:
|
|
|
197
201
|
if not token_to_use:
|
|
198
202
|
raise AuthNoTokenException(f"Forbidden: {error}")
|
|
199
203
|
raise AuthException(f"Forbidden: {error}")
|
|
200
|
-
if response.status_code
|
|
204
|
+
if response.status_code in (204, 205):
|
|
201
205
|
return None
|
|
202
206
|
if response.status_code == 404:
|
|
203
207
|
error = parse_error_response(response)
|
|
@@ -385,9 +385,12 @@ def array_type(types):
|
|
|
385
385
|
x = default
|
|
386
386
|
else:
|
|
387
387
|
if _type and _type in types:
|
|
388
|
-
|
|
388
|
+
if _type == "String":
|
|
389
|
+
x = ""
|
|
390
|
+
else:
|
|
391
|
+
x = ",".join(map(str, [types[_type](x) for _ in range(2)]))
|
|
389
392
|
else:
|
|
390
|
-
x = "
|
|
393
|
+
x = ""
|
|
391
394
|
elif x is None:
|
|
392
395
|
x = default
|
|
393
396
|
if x is None:
|
|
@@ -405,7 +408,7 @@ def array_type(types):
|
|
|
405
408
|
values.append(expression_wrapper(types[_type](t), str(t)))
|
|
406
409
|
else:
|
|
407
410
|
raise SQLTemplateException(
|
|
408
|
-
f"Error validating {x}[{i}]({t}) to type {_type}",
|
|
411
|
+
f"Error validating [{x}][{i}] ({'empty string' if t == '' else t}) to type {_type}",
|
|
409
412
|
documentation="/cli/advanced-templates.html",
|
|
410
413
|
)
|
|
411
414
|
else:
|
|
@@ -2056,7 +2059,11 @@ def render_sql_template(
|
|
|
2056
2059
|
>>> render_sql_template("SELECT {{ Array(embedding, 'Float32') }}", {'token':'testing', 'embedding': '1,2,3,4, null'})
|
|
2057
2060
|
Traceback (most recent call last):
|
|
2058
2061
|
...
|
|
2059
|
-
tinybird.sql_template.SQLTemplateException: Template Syntax Error: Error validating 1,2,3,4, null[4]( null) to type Float32
|
|
2062
|
+
tinybird.sql_template.SQLTemplateException: Template Syntax Error: Error validating [1,2,3,4, null][4] ( null) to type Float32
|
|
2063
|
+
>>> render_sql_template("SELECT {{ Array(embedding, 'Int32', '') }}", {'token':'testing', 'embedding': ''})
|
|
2064
|
+
Traceback (most recent call last):
|
|
2065
|
+
...
|
|
2066
|
+
tinybird.sql_template.SQLTemplateException: Template Syntax Error: Error validating [][0] (empty string) to type Int32
|
|
2060
2067
|
>>> render_sql_template('{% if test %}SELECT 1{% else %} select 2 {% end %}')
|
|
2061
2068
|
(' select 2 ', {}, [])
|
|
2062
2069
|
>>> render_sql_template('{% if Int32(test, 1) %}SELECT 1{% else %} select 2 {% end %}')
|
|
@@ -2096,7 +2103,7 @@ def render_sql_template(
|
|
|
2096
2103
|
>>> render_sql_template("SELECT {{Array(foo, 'Int32')}}", test_mode=True)
|
|
2097
2104
|
('SELECT [0,0]', {}, [])
|
|
2098
2105
|
>>> render_sql_template("SELECT {{Array(foo)}}", test_mode=True)
|
|
2099
|
-
("SELECT ['
|
|
2106
|
+
("SELECT ['']", {}, [])
|
|
2100
2107
|
>>> render_sql_template("{{max_threads(2)}} SELECT 1")
|
|
2101
2108
|
('-- max_threads 2\\n SELECT 1', {'max_threads': 2}, [])
|
|
2102
2109
|
>>> render_sql_template("SELECT {{String(foo)}}", test_mode=True)
|
|
@@ -2183,6 +2190,14 @@ def render_sql_template(
|
|
|
2183
2190
|
("% SELECT ['pre','pro']", {}, [])
|
|
2184
2191
|
>>> render_sql_template("% SELECT {{Array(click_selector, 'String', 'pre,pro')}}", {'click_selector': 'hi,hello'})
|
|
2185
2192
|
("% SELECT ['hi','hello']", {}, [])
|
|
2193
|
+
>>> render_sql_template("% SELECT {{Array(click_selector, 'String', '')}}")
|
|
2194
|
+
("% SELECT ['']", {}, [])
|
|
2195
|
+
>>> render_sql_template("SELECT {{ Array(embedding, 'Int32', '') }}")
|
|
2196
|
+
Traceback (most recent call last):
|
|
2197
|
+
...
|
|
2198
|
+
tinybird.sql_template.SQLTemplateException: Template Syntax Error: Error validating [][0] (empty string) to type Int32
|
|
2199
|
+
>>> render_sql_template("% SELECT {{Array(click_selector, 'String', '')}}", test_mode=True)
|
|
2200
|
+
("% SELECT ['']", {}, [])
|
|
2186
2201
|
>>> render_sql_template("% SELECT now() > {{DateTime64(variable, '2020-09-09 10:10:10.000')}}", {})
|
|
2187
2202
|
("% SELECT now() > '2020-09-09 10:10:10.000'", {}, [])
|
|
2188
2203
|
>>> render_sql_template("% SELECT {% if defined(x) %} x, 1", {})
|
|
@@ -2241,6 +2256,16 @@ def render_sql_template(
|
|
|
2241
2256
|
Traceback (most recent call last):
|
|
2242
2257
|
...
|
|
2243
2258
|
tinybird.sql_template.SQLTemplateException: Template Syntax Error: Required parameter is not defined. Check the parameters test. Please provide a value or set a default value in the pipe code.
|
|
2259
|
+
>>> render_sql_template("SELECT * FROM test WHERE {% for item in JSON(filters, '[{}]') %} {{item.get('operand')}} {% end %}")
|
|
2260
|
+
Traceback (most recent call last):
|
|
2261
|
+
...
|
|
2262
|
+
tinybird.sql_template.SQLTemplateException: Template Syntax Error: expression "item.get('operand')" evaluated to null
|
|
2263
|
+
>>> render_sql_template("SELECT * FROM test WHERE {% for item in JSON(filters, '[{\\\"operand\\\":\\\"test\\\"}]') %} {{item.get('operand')}} {% end %}")
|
|
2264
|
+
("SELECT * FROM test WHERE 'test' ", {}, [])
|
|
2265
|
+
>>> render_sql_template("SELECT * FROM test WHERE {% for item in JSON(filters, '[\\\"test\\\"]') %} {{item.get('operator')}} {% end %}")
|
|
2266
|
+
Traceback (most recent call last):
|
|
2267
|
+
...
|
|
2268
|
+
tinybird.sql_template.SQLTemplateException: Template Syntax Error: 'str' object has no attribute 'get'. Make sure you're using an object/dictionary where trying to use .get()
|
|
2244
2269
|
"""
|
|
2245
2270
|
escape_split_to_array = ff_split_to_array_escape.get(False)
|
|
2246
2271
|
|
|
@@ -2308,6 +2333,14 @@ def render_sql_template(
|
|
|
2308
2333
|
except SQLTemplateException as e:
|
|
2309
2334
|
format_SQLTemplateException_message(e, vars_and_types=template_variables_with_types)
|
|
2310
2335
|
raise
|
|
2336
|
+
except AttributeError as e:
|
|
2337
|
+
# This happens when trying to use `get` on a string or when the object is None
|
|
2338
|
+
if "'str' object has no attribute 'get'" in str(e):
|
|
2339
|
+
raise SQLTemplateException(
|
|
2340
|
+
"'str' object has no attribute 'get'. Make sure you're using an object/dictionary where trying to use .get()",
|
|
2341
|
+
documentation="/cli/advanced-templates.html",
|
|
2342
|
+
)
|
|
2343
|
+
raise SQLTemplateException(str(e), documentation="/cli/advanced-templates.html")
|
|
2311
2344
|
except Exception as e:
|
|
2312
2345
|
# errors might vary here, we need to support as much as possible
|
|
2313
2346
|
# https://gitlab.com/tinybird/analytics/-/issues/943
|
|
@@ -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__ = '0.0.1.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '0.0.1.dev71'
|
|
8
|
+
__revision__ = '4feda71'
|
|
@@ -15,7 +15,7 @@ from tinybird.client import TinyB
|
|
|
15
15
|
from tinybird.tb.modules.cli import cli
|
|
16
16
|
from tinybird.tb.modules.common import push_data
|
|
17
17
|
from tinybird.tb.modules.datafile.build import folder_build
|
|
18
|
-
from tinybird.tb.modules.datafile.fixture import get_fixture_dir
|
|
18
|
+
from tinybird.tb.modules.datafile.fixture import get_fixture_dir, persist_fixture
|
|
19
19
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
20
20
|
from tinybird.tb.modules.project import Project
|
|
21
21
|
from tinybird.tb.modules.shell import Shell, print_table_formatted
|
|
@@ -210,6 +210,8 @@ def process(
|
|
|
210
210
|
build_failed = False
|
|
211
211
|
if file_changed and file_changed.endswith(".ndjson"):
|
|
212
212
|
rebuild_fixture(project, tb_client, file_changed)
|
|
213
|
+
elif file_changed and file_changed.endswith(".sql"):
|
|
214
|
+
rebuild_fixture_sql(project, tb_client, file_changed)
|
|
213
215
|
else:
|
|
214
216
|
try:
|
|
215
217
|
build_project(project, tb_client, file_changed)
|
|
@@ -247,3 +249,12 @@ def run_watch(
|
|
|
247
249
|
)
|
|
248
250
|
watcher_thread.start()
|
|
249
251
|
shell.run()
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def rebuild_fixture_sql(project: Project, tb_client: TinyB, sql_file: str) -> None:
|
|
255
|
+
sql_path = Path(sql_file)
|
|
256
|
+
datasource_name = sql_path.stem
|
|
257
|
+
sql = sql_path.read_text()
|
|
258
|
+
result = asyncio.run(tb_client.query(f"{sql} FORMAT JSON"))
|
|
259
|
+
data = result.get("data", [])
|
|
260
|
+
persist_fixture(datasource_name, data, project.folder)
|
|
@@ -57,6 +57,7 @@ VERSION = f"{__cli__.__version__} (rev {__cli__.__revision__})"
|
|
|
57
57
|
@click.option("--show-tokens", is_flag=True, default=False, help="Enable the output of tokens")
|
|
58
58
|
@click.option("--cloud/--local", is_flag=True, default=False, help="Run against cloud or local")
|
|
59
59
|
@click.option("--build", is_flag=True, default=False, help="Run against build mode")
|
|
60
|
+
@click.option("--preview", is_flag=True, default=False, help="Run against new deployment")
|
|
60
61
|
@click.version_option(version=VERSION)
|
|
61
62
|
@click.pass_context
|
|
62
63
|
@coro
|
|
@@ -68,6 +69,7 @@ async def cli(
|
|
|
68
69
|
show_tokens: bool,
|
|
69
70
|
cloud: bool,
|
|
70
71
|
build: bool,
|
|
72
|
+
preview: bool,
|
|
71
73
|
) -> None:
|
|
72
74
|
"""
|
|
73
75
|
Use `OBFUSCATE_REGEX_PATTERN` and `OBFUSCATE_PATTERN_SEPARATOR` environment variables to define a regex pattern and a separator (in case of a single string with multiple regex) to obfuscate secrets in the CLI output.
|
|
@@ -121,12 +123,13 @@ async def cli(
|
|
|
121
123
|
|
|
122
124
|
logging.debug("debug enabled")
|
|
123
125
|
|
|
124
|
-
client = await create_ctx_client(ctx, config, cloud, build)
|
|
126
|
+
client = await create_ctx_client(ctx, config, cloud, build, preview)
|
|
125
127
|
|
|
126
128
|
if client:
|
|
127
129
|
ctx.ensure_object(dict)["client"] = client
|
|
128
130
|
|
|
129
131
|
ctx.ensure_object(dict)["project"] = project
|
|
132
|
+
ctx.ensure_object(dict)["env"] = get_target_env(cloud, build)
|
|
130
133
|
|
|
131
134
|
|
|
132
135
|
@cli.command(hidden=True)
|
|
@@ -385,7 +388,7 @@ def __unpatch_click_output():
|
|
|
385
388
|
click.secho = __old_click_secho
|
|
386
389
|
|
|
387
390
|
|
|
388
|
-
async def create_ctx_client(ctx: Context, config: Dict[str, Any], cloud: bool, build: bool):
|
|
391
|
+
async def create_ctx_client(ctx: Context, config: Dict[str, Any], cloud: bool, build: bool, preview: bool):
|
|
389
392
|
commands_without_ctx_client = ["auth", "check", "login", "local", "upgrade"]
|
|
390
393
|
command = ctx.invoked_subcommand
|
|
391
394
|
if command in commands_without_ctx_client:
|
|
@@ -393,7 +396,7 @@ async def create_ctx_client(ctx: Context, config: Dict[str, Any], cloud: bool, b
|
|
|
393
396
|
|
|
394
397
|
commands_always_cloud = ["pull"]
|
|
395
398
|
commands_always_build = ["build", "test", "dev"]
|
|
396
|
-
commands_always_local = ["create"
|
|
399
|
+
commands_always_local = ["create"]
|
|
397
400
|
if (
|
|
398
401
|
(cloud or command in commands_always_cloud)
|
|
399
402
|
and command not in commands_always_build
|
|
@@ -402,8 +405,16 @@ async def create_ctx_client(ctx: Context, config: Dict[str, Any], cloud: bool, b
|
|
|
402
405
|
click.echo(
|
|
403
406
|
FeedbackManager.gray(message=f"Running against Tinybird Cloud: Workspace {config.get('name', 'default')}")
|
|
404
407
|
)
|
|
405
|
-
return _get_tb_client(config.get("token", None), config["host"])
|
|
408
|
+
return _get_tb_client(config.get("token", None), config["host"], preview=preview)
|
|
406
409
|
build = command in commands_always_build or build
|
|
407
410
|
if not build and command not in commands_always_local and command not in commands_always_build:
|
|
408
411
|
click.echo(FeedbackManager.gray(message="Running against Tinybird Local\n"))
|
|
409
|
-
return await get_tinybird_local_client(config, build=build)
|
|
412
|
+
return await get_tinybird_local_client(config, build=build, preview=preview)
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
def get_target_env(cloud: bool, build: bool) -> str:
|
|
416
|
+
if cloud:
|
|
417
|
+
return "cloud"
|
|
418
|
+
if build:
|
|
419
|
+
return "build"
|
|
420
|
+
return "local"
|
|
@@ -375,9 +375,9 @@ def getenv_bool(key: str, default: bool) -> bool:
|
|
|
375
375
|
return v.lower() == "true" or v == "1"
|
|
376
376
|
|
|
377
377
|
|
|
378
|
-
def _get_tb_client(token: str, host: str) -> TinyB:
|
|
378
|
+
def _get_tb_client(token: str, host: str, preview: bool = False) -> TinyB:
|
|
379
379
|
disable_ssl: bool = getenv_bool("TB_DISABLE_SSL_CHECKS", False)
|
|
380
|
-
return TinyB(token, host, version=VERSION, disable_ssl_checks=disable_ssl, send_telemetry=True)
|
|
380
|
+
return TinyB(token, host, version=VERSION, disable_ssl_checks=disable_ssl, send_telemetry=True, preview=preview)
|
|
381
381
|
|
|
382
382
|
|
|
383
383
|
def create_tb_client(ctx: Context) -> TinyB:
|
|
@@ -554,7 +554,7 @@ def format_host(host: str, subdomain: Optional[str] = None) -> str:
|
|
|
554
554
|
if subdomain and not is_localhost:
|
|
555
555
|
url_info = urlparse(host)
|
|
556
556
|
current_subdomain = url_info.netloc.split(".")[0]
|
|
557
|
-
if current_subdomain
|
|
557
|
+
if current_subdomain in ("api", "ui"):
|
|
558
558
|
host = host.replace(current_subdomain, subdomain)
|
|
559
559
|
if "localhost" in host or is_localhost:
|
|
560
560
|
host = f"http://{host}" if "http" not in host else host
|
|
@@ -219,7 +219,7 @@ class CLIConfig:
|
|
|
219
219
|
return CLIConfig.DEFAULTS["host"]
|
|
220
220
|
return None
|
|
221
221
|
|
|
222
|
-
def get_client(self, token: Optional[str] = None, host: Optional[str] = None) -> tbc.TinyB:
|
|
222
|
+
def get_client(self, token: Optional[str] = None, host: Optional[str] = None, preview: bool = False) -> tbc.TinyB:
|
|
223
223
|
"""Returns a new TinyB client configured with:
|
|
224
224
|
|
|
225
225
|
- token:
|
|
@@ -242,6 +242,7 @@ class CLIConfig:
|
|
|
242
242
|
version=CURRENT_VERSION,
|
|
243
243
|
disable_ssl_checks=FeatureFlags.ignore_ssl_errors(),
|
|
244
244
|
send_telemetry=FeatureFlags.send_telemetry(),
|
|
245
|
+
preview=preview,
|
|
245
246
|
)
|
|
246
247
|
|
|
247
248
|
def get_user_client(self, host: Optional[str] = None) -> tbc.TinyB:
|
|
@@ -8,6 +8,13 @@ def get_fixture_dir(folder: str) -> Path:
|
|
|
8
8
|
return Path(folder) / "fixtures"
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
def persist_fixture_sql(fixture_name: str, sql: str, folder: str) -> Path:
|
|
12
|
+
fixture_dir = get_fixture_dir(folder)
|
|
13
|
+
fixture_file = fixture_dir / f"{fixture_name}.sql"
|
|
14
|
+
fixture_file.write_text(sql)
|
|
15
|
+
return fixture_file
|
|
16
|
+
|
|
17
|
+
|
|
11
18
|
def persist_fixture(fixture_name: str, data: Union[List[Dict[str, Any]], str], folder: str, format="ndjson") -> Path:
|
|
12
19
|
fixture_dir = get_fixture_dir(folder)
|
|
13
20
|
fixture_file = fixture_dir / f"{fixture_name}.{format}"
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import asyncio
|
|
7
7
|
import json
|
|
8
|
+
import os
|
|
8
9
|
import re
|
|
9
10
|
from typing import Optional
|
|
10
11
|
|
|
@@ -23,8 +24,10 @@ from tinybird.tb.modules.common import (
|
|
|
23
24
|
push_data,
|
|
24
25
|
)
|
|
25
26
|
from tinybird.tb.modules.datafile.common import get_name_version
|
|
27
|
+
from tinybird.tb.modules.datafile.fixture import persist_fixture
|
|
26
28
|
from tinybird.tb.modules.exceptions import CLIDatasourceException
|
|
27
29
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
30
|
+
from tinybird.tb.modules.project import Project
|
|
28
31
|
|
|
29
32
|
|
|
30
33
|
@cli.group()
|
|
@@ -391,3 +394,63 @@ async def datasource_data(ctx: Context, datasource: str, limit: int):
|
|
|
391
394
|
echo_safe_humanfriendly_tables_format_smart_table(
|
|
392
395
|
data=[d.values() for d in res["data"]], column_names=res["data"][0].keys()
|
|
393
396
|
)
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
@datasource.command(name="export")
|
|
400
|
+
@click.argument("datasource")
|
|
401
|
+
@click.option(
|
|
402
|
+
"--format",
|
|
403
|
+
"format_",
|
|
404
|
+
type=click.Choice(["csv", "ndjson"], case_sensitive=False),
|
|
405
|
+
default="ndjson",
|
|
406
|
+
help="Output format (csv or ndjson)",
|
|
407
|
+
)
|
|
408
|
+
@click.option("--rows", type=int, default=100, help="Number of rows to export (default: 100)")
|
|
409
|
+
@click.option("--where", type=str, default=None, help="Condition to filter data")
|
|
410
|
+
@click.option("--target", type=str, help="Target file path (default: datasource_name.{format})")
|
|
411
|
+
@click.pass_context
|
|
412
|
+
@coro
|
|
413
|
+
async def datasource_export(
|
|
414
|
+
ctx: Context,
|
|
415
|
+
datasource: str,
|
|
416
|
+
format_: str,
|
|
417
|
+
rows: int,
|
|
418
|
+
where: Optional[str],
|
|
419
|
+
target: Optional[str],
|
|
420
|
+
):
|
|
421
|
+
"""Export data from a datasource to a file in CSV or NDJSON format
|
|
422
|
+
|
|
423
|
+
Example usage:
|
|
424
|
+
- Export all rows as CSV: tb datasource export my_datasource
|
|
425
|
+
- Export 1000 rows as NDJSON: tb datasource export my_datasource --format ndjson --rows 1000
|
|
426
|
+
- Export to specific file: tb datasource export my_datasource --output ./data/export.csv
|
|
427
|
+
"""
|
|
428
|
+
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
429
|
+
project: Project = ctx.ensure_object(dict)["project"]
|
|
430
|
+
|
|
431
|
+
# Determine output filename if not provided
|
|
432
|
+
if not target:
|
|
433
|
+
target = f"{datasource}.{format_}"
|
|
434
|
+
|
|
435
|
+
# Build query with optional row limit
|
|
436
|
+
query = f"SELECT * FROM {datasource} WHERE {where or 1} LIMIT {rows}"
|
|
437
|
+
|
|
438
|
+
click.echo(FeedbackManager.highlight(message=f"\n» Exporting {datasource} to {target}"))
|
|
439
|
+
|
|
440
|
+
try:
|
|
441
|
+
if format_ == "csv":
|
|
442
|
+
query += " FORMAT CSVWithNames"
|
|
443
|
+
else:
|
|
444
|
+
query += " FORMAT JSONEachRow"
|
|
445
|
+
|
|
446
|
+
res = await client.query(query)
|
|
447
|
+
|
|
448
|
+
fixture_path = persist_fixture(datasource, res, project.folder)
|
|
449
|
+
file_size = os.path.getsize(fixture_path)
|
|
450
|
+
|
|
451
|
+
click.echo(
|
|
452
|
+
FeedbackManager.success(message=f"✓ Exported data to {target} ({humanfriendly.format_size(file_size)})")
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
except Exception as e:
|
|
456
|
+
raise CLIDatasourceException(FeedbackManager.error(message=str(e)))
|
|
@@ -266,13 +266,13 @@ def deployment_rollback(ctx: click.Context, wait: bool) -> None:
|
|
|
266
266
|
@click.option(
|
|
267
267
|
"--wait/--no-wait",
|
|
268
268
|
is_flag=True,
|
|
269
|
-
default=
|
|
269
|
+
default=True,
|
|
270
270
|
help="Wait for deploy to finish. Disabled by default.",
|
|
271
271
|
)
|
|
272
272
|
@click.option(
|
|
273
273
|
"--auto/--no-auto",
|
|
274
274
|
is_flag=True,
|
|
275
|
-
default=
|
|
275
|
+
default=True,
|
|
276
276
|
help="Auto-promote the deployment. Only works if --wait is enabled. Disabled by default.",
|
|
277
277
|
)
|
|
278
278
|
@click.option(
|
|
@@ -311,6 +311,7 @@ def create_deployment(
|
|
|
311
311
|
}
|
|
312
312
|
project: Project = ctx.ensure_object(dict)["project"]
|
|
313
313
|
client = ctx.ensure_object(dict)["client"]
|
|
314
|
+
config = ctx.ensure_object(dict)["config"]
|
|
314
315
|
TINYBIRD_API_URL = f"{client.host}/v1/deploy"
|
|
315
316
|
TINYBIRD_API_KEY = client.token
|
|
316
317
|
|
|
@@ -357,8 +358,21 @@ def create_deployment(
|
|
|
357
358
|
deploy_result = result.get("result")
|
|
358
359
|
if deploy_result == "success":
|
|
359
360
|
print_changes(result, project)
|
|
360
|
-
|
|
361
|
-
|
|
361
|
+
deployment = result.get("deployment", {})
|
|
362
|
+
# We show the url in the case of region is public
|
|
363
|
+
if client.host == "https://api.europe-west2.gcp.tinybird.co":
|
|
364
|
+
click.echo(
|
|
365
|
+
FeedbackManager.gray(message="Deployment URL: ")
|
|
366
|
+
+ FeedbackManager.info(
|
|
367
|
+
message=f"https://cloud.tinybird.co/gcp/europe-west2/{config.get('name')}/deployments/{deployment.get('id')}"
|
|
368
|
+
)
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
if wait:
|
|
372
|
+
click.echo(FeedbackManager.info(message="\n✓ Deployment submitted successfully"))
|
|
373
|
+
else:
|
|
374
|
+
click.echo(FeedbackManager.success(message="\n✓ Deployment submitted successfully"))
|
|
375
|
+
|
|
362
376
|
feedback = deployment.get("feedback", [])
|
|
363
377
|
for f in feedback:
|
|
364
378
|
click.echo(
|
|
@@ -15,10 +15,10 @@ TB_LOCAL_PORT = int(os.getenv("TB_LOCAL_PORT", 80))
|
|
|
15
15
|
TB_LOCAL_HOST = f"http://localhost:{TB_LOCAL_PORT}"
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
async def get_tinybird_local_client(config_obj: Dict[str, Any], build: bool = False) -> TinyB:
|
|
18
|
+
async def get_tinybird_local_client(config_obj: Dict[str, Any], build: bool = False, preview: bool = False) -> TinyB:
|
|
19
19
|
"""Get a Tinybird client connected to the local environment."""
|
|
20
20
|
config = await get_tinybird_local_config(config_obj, build=build)
|
|
21
|
-
return config.get_client(host=TB_LOCAL_HOST)
|
|
21
|
+
return config.get_client(host=TB_LOCAL_HOST, preview=preview)
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
async def get_tinybird_local_config(config_obj: Dict[str, Any], build: bool = False) -> CLIConfig:
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import glob
|
|
2
|
-
import logging
|
|
3
|
-
import os
|
|
4
2
|
from pathlib import Path
|
|
5
3
|
|
|
6
4
|
import click
|
|
@@ -8,9 +6,9 @@ import click
|
|
|
8
6
|
from tinybird.client import TinyB
|
|
9
7
|
from tinybird.prompts import mock_prompt
|
|
10
8
|
from tinybird.tb.modules.cli import cli
|
|
11
|
-
from tinybird.tb.modules.common import CLIException, check_user_token_with_client, coro
|
|
9
|
+
from tinybird.tb.modules.common import CLIException, check_user_token_with_client, coro, push_data
|
|
12
10
|
from tinybird.tb.modules.config import CLIConfig
|
|
13
|
-
from tinybird.tb.modules.datafile.fixture import persist_fixture
|
|
11
|
+
from tinybird.tb.modules.datafile.fixture import persist_fixture, persist_fixture_sql
|
|
14
12
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
15
13
|
from tinybird.tb.modules.llm import LLM
|
|
16
14
|
from tinybird.tb.modules.llm_utils import extract_xml
|
|
@@ -41,11 +39,11 @@ async def mock(ctx: click.Context, datasource: str, rows: int, prompt: str) -> N
|
|
|
41
39
|
try:
|
|
42
40
|
tb_client: TinyB = ctx.ensure_object(dict)["client"]
|
|
43
41
|
project: Project = ctx.ensure_object(dict)["project"]
|
|
42
|
+
env = ctx.ensure_object(dict)["env"]
|
|
44
43
|
datasource_path = Path(datasource)
|
|
45
44
|
datasource_name = datasource
|
|
46
45
|
folder = project.folder
|
|
47
46
|
click.echo(FeedbackManager.highlight(message=f"\n» Creating fixture for {datasource_name}..."))
|
|
48
|
-
|
|
49
47
|
if datasource_path.suffix == ".datasource":
|
|
50
48
|
datasource_name = datasource_path.stem
|
|
51
49
|
else:
|
|
@@ -56,14 +54,6 @@ async def mock(ctx: click.Context, datasource: str, rows: int, prompt: str) -> N
|
|
|
56
54
|
if not datasource_path.exists():
|
|
57
55
|
raise CLIException(f"Datasource '{datasource_path.stem}' not found")
|
|
58
56
|
|
|
59
|
-
prompt_path = Path(folder) / "fixtures" / f"{datasource_name}.prompt"
|
|
60
|
-
if not prompt or prompt == "Use the datasource schema to generate sample data":
|
|
61
|
-
# load the prompt from the fixture.prompt file if it exists
|
|
62
|
-
if prompt_path.exists():
|
|
63
|
-
prompt = prompt_path.read_text()
|
|
64
|
-
else:
|
|
65
|
-
prompt_path.write_text(prompt)
|
|
66
|
-
|
|
67
57
|
datasource_content = datasource_path.read_text()
|
|
68
58
|
config = CLIConfig.get_project_config()
|
|
69
59
|
user_client = config.get_client()
|
|
@@ -76,21 +66,39 @@ async def mock(ctx: click.Context, datasource: str, rows: int, prompt: str) -> N
|
|
|
76
66
|
except Exception:
|
|
77
67
|
click.echo(FeedbackManager.error(message="This action requires authentication. Run 'tb login' first."))
|
|
78
68
|
return
|
|
69
|
+
|
|
79
70
|
llm = LLM(user_token=user_token, host=user_client.host)
|
|
80
71
|
prompt = f"<datasource_schema>{datasource_content}</datasource_schema>\n<user_input>{prompt}</user_input>"
|
|
81
72
|
sql = ""
|
|
82
|
-
|
|
83
73
|
response = llm.ask(system_prompt=mock_prompt(rows), prompt=prompt)
|
|
84
74
|
sql = extract_xml(response, "sql")
|
|
85
75
|
result = await tb_client.query(f"{sql} FORMAT JSON")
|
|
86
76
|
data = result.get("data", [])[:rows]
|
|
87
|
-
|
|
88
|
-
|
|
77
|
+
if env == "build":
|
|
78
|
+
persist_fixture_sql(datasource_name, sql, folder)
|
|
79
|
+
|
|
80
|
+
fixture_path = persist_fixture(datasource_name, data, folder)
|
|
89
81
|
|
|
90
|
-
|
|
91
|
-
|
|
82
|
+
click.echo(FeedbackManager.info(message=f"✓ /fixtures/{datasource_name}.ndjson created"))
|
|
83
|
+
if env == "cloud":
|
|
84
|
+
await append_fixture(tb_client, datasource_name, str(fixture_path))
|
|
92
85
|
|
|
93
86
|
click.echo(FeedbackManager.success(message=f"✓ Sample data for {datasource_name} created with {rows} rows"))
|
|
94
87
|
|
|
95
88
|
except Exception as e:
|
|
96
89
|
click.echo(FeedbackManager.error_exception(error=f"Error: {e}"))
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
async def append_fixture(
|
|
93
|
+
tb_client: TinyB,
|
|
94
|
+
datasource_name: str,
|
|
95
|
+
url: str,
|
|
96
|
+
):
|
|
97
|
+
await push_data(
|
|
98
|
+
tb_client,
|
|
99
|
+
datasource_name,
|
|
100
|
+
url,
|
|
101
|
+
mode="append",
|
|
102
|
+
concurrency=1,
|
|
103
|
+
silent=True,
|
|
104
|
+
)
|
|
@@ -206,7 +206,7 @@ class TelemetryHelper:
|
|
|
206
206
|
|
|
207
207
|
self.log(f"Received status {r.status_code}: {r.text}")
|
|
208
208
|
|
|
209
|
-
if r.status_code
|
|
209
|
+
if r.status_code in (200, 202):
|
|
210
210
|
self.log(f"Successfully sent {len(events)} events to {self.tb_host}")
|
|
211
211
|
self.events.clear()
|
|
212
212
|
return
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import difflib
|
|
7
7
|
import glob
|
|
8
|
+
import sys
|
|
8
9
|
import urllib.parse
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
from typing import Any, Dict, List, Optional, Tuple
|
|
@@ -265,7 +266,7 @@ async def run_tests(ctx: click.Context, name: Tuple[str, ...]) -> None:
|
|
|
265
266
|
|
|
266
267
|
if failed_tests_count:
|
|
267
268
|
click.echo(FeedbackManager.error(message=f"\n✗ {test_count - failed_tests_count}/{test_count} passed"))
|
|
268
|
-
exit(1)
|
|
269
|
+
sys.exit(1)
|
|
269
270
|
else:
|
|
270
271
|
click.echo(FeedbackManager.success(message=f"\n✓ {test_count}/{test_count} passed"))
|
|
271
272
|
|
|
@@ -190,8 +190,6 @@ def generate_file(file: str, overwrite: bool = False) -> None:
|
|
|
190
190
|
else:
|
|
191
191
|
raise CLIException(FeedbackManager.error_file_already_exists(file=p))
|
|
192
192
|
|
|
193
|
-
return
|
|
194
|
-
|
|
195
193
|
|
|
196
194
|
async def run_test_file(tb_client: TinyB, file: str) -> List[TestResult]:
|
|
197
195
|
results: List[TestResult] = []
|
|
@@ -29,7 +29,7 @@ class WatchProjectHandler(FileSystemEventHandler):
|
|
|
29
29
|
if event.is_directory:
|
|
30
30
|
return None
|
|
31
31
|
|
|
32
|
-
valid_extensions = [".datasource", ".pipe", ".ndjson"]
|
|
32
|
+
valid_extensions = [".datasource", ".pipe", ".ndjson", ".sql"]
|
|
33
33
|
|
|
34
34
|
if not any(event.src_path.endswith(ext) for ext in valid_extensions):
|
|
35
35
|
return None
|
|
@@ -600,7 +600,7 @@ def format_host(host: str, subdomain: Optional[str] = None) -> str:
|
|
|
600
600
|
if subdomain and not is_localhost:
|
|
601
601
|
url_info = urlparse(host)
|
|
602
602
|
current_subdomain = url_info.netloc.split(".")[0]
|
|
603
|
-
if current_subdomain
|
|
603
|
+
if current_subdomain in ("api", "ui"):
|
|
604
604
|
host = host.replace(current_subdomain, subdomain)
|
|
605
605
|
if "localhost" in host or is_localhost:
|
|
606
606
|
host = f"http://{host}" if "http" not in host else host
|
|
@@ -206,7 +206,7 @@ class TelemetryHelper:
|
|
|
206
206
|
|
|
207
207
|
self.log(f"Received status {r.status_code}: {r.text}")
|
|
208
208
|
|
|
209
|
-
if r.status_code
|
|
209
|
+
if r.status_code in (200, 202):
|
|
210
210
|
self.log(f"Successfully sent {len(events)} events to {self.tb_host}")
|
|
211
211
|
self.events.clear()
|
|
212
212
|
return
|
|
@@ -190,8 +190,6 @@ def generate_file(file: str, overwrite: bool = False) -> None:
|
|
|
190
190
|
else:
|
|
191
191
|
raise CLIException(FeedbackManager.error_file_already_exists(file=p))
|
|
192
192
|
|
|
193
|
-
return
|
|
194
|
-
|
|
195
193
|
|
|
196
194
|
async def run_test_file(tb_client: TinyB, file: str) -> List[TestResult]:
|
|
197
195
|
results: List[TestResult] = []
|
|
@@ -1144,7 +1144,7 @@ def check_valid_expr(expr):
|
|
|
1144
1144
|
return
|
|
1145
1145
|
if isinstance(expr.value, str):
|
|
1146
1146
|
return
|
|
1147
|
-
if
|
|
1147
|
+
if expr.value is None:
|
|
1148
1148
|
return
|
|
1149
1149
|
raise SecurityException(f"Invalid Constant: {ast.dump(expr)}")
|
|
1150
1150
|
elif isinstance(expr, ast.Name):
|
|
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-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/build_datasource.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/format_datasource.py
RENAMED
|
File without changes
|
|
File without changes
|
{tinybird-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb/modules/datafile/parse_datasource.py
RENAMED
|
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
|
|
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-0.0.1.dev69 → tinybird-0.0.1.dev71}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|