tinybird 4.3.2.dev0__tar.gz → 4.4.0__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-4.3.2.dev0 → tinybird-4.4.0}/PKG-INFO +11 -1
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/client.py +7 -1
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/datafile/common.py +55 -41
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/service_datasources.py +25 -18
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/syncasync.py +0 -26
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/__cli__.py +2 -2
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/client.py +18 -2
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/build_common.py +3 -2
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/cli.py +8 -5
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/common.py +10 -3
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/connection.py +1 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/connection_kafka.py +1 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/copy.py +15 -2
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datasource.py +6 -1
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/deployment.py +6 -5
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/deployment_common.py +38 -15
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/pipe.py +14 -2
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird.egg-info/PKG-INFO +11 -1
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/setup.cfg +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/__cli__.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/ch_utils/engine.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/check_pypi.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/config.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/context.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/datafile/exceptions.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/datafile/parse_connection.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/datafile/parse_datasource.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/datafile/parse_pipe.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/datatypes.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/feedback_manager.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/git_settings.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/prompts.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/sql.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/sql_template.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/sql_toolset.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/check_pypi.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/cli.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/config.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/branch.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/build.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/cicd.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/config.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/connection_s3.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/create.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/build.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/build_common.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/diff.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/fixture.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/format_common.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/format_connection.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/playground.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/datafile/pull.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/deprecations.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/endpoint.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/exceptions.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/feedback_manager.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/fmt.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/info.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/infra.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/job.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/job_common.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/llm.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/llm_utils.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/local.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/local_common.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/local_logs.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/login.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/login_common.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/logout.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/logs.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/materialization.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/open.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/pipe.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/preview.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/project.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/project_commands.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/py_project.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/query_output.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/regions.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/secret.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/secret_common.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/sink.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/table.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/telemetry.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/test.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/test_common.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/token.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/ts_project.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/watch.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/workspace.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb/modules/workspace_members.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/common.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird/tornado_template.py +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird.egg-info/SOURCES.txt +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird.egg-info/dependency_links.txt +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird.egg-info/entry_points.txt +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird.egg-info/requires.txt +0 -0
- {tinybird-4.3.2.dev0 → tinybird-4.4.0}/tinybird.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: tinybird
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.0
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/forward/commands
|
|
6
6
|
Author: Tinybird
|
|
@@ -52,6 +52,16 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
52
52
|
Changelog
|
|
53
53
|
----------
|
|
54
54
|
|
|
55
|
+
4.4.0
|
|
56
|
+
*******
|
|
57
|
+
|
|
58
|
+
- `Added` `tb copy run` has a new `--on-demand-compute` flag to use on-demand compute instances for copy jobs.
|
|
59
|
+
|
|
60
|
+
4.3.2
|
|
61
|
+
*******
|
|
62
|
+
|
|
63
|
+
- `Changed` CLI API requests now set the `from` parameter dynamically from the detected project type (`python-sdk`, `ts-sdk`, or `cli`) instead of using a hardcoded source.
|
|
64
|
+
|
|
55
65
|
4.3.1
|
|
56
66
|
*******
|
|
57
67
|
|
|
@@ -635,11 +635,17 @@ class TinyB:
|
|
|
635
635
|
return await self._req(f"/v0/pipes/{pipe_name_or_id}/nodes/{node_id}/copy", method="DELETE")
|
|
636
636
|
|
|
637
637
|
async def pipe_run_copy(
|
|
638
|
-
self,
|
|
638
|
+
self,
|
|
639
|
+
pipe_name_or_id: str,
|
|
640
|
+
params: Optional[Dict[str, str]] = None,
|
|
641
|
+
mode: Optional[str] = None,
|
|
642
|
+
on_demand_compute: bool = False,
|
|
639
643
|
):
|
|
640
644
|
params = {**params} if params else {}
|
|
641
645
|
if mode:
|
|
642
646
|
params["_mode"] = mode
|
|
647
|
+
if on_demand_compute:
|
|
648
|
+
params["on_demand_compute"] = "true"
|
|
643
649
|
return await self._req(f"/v0/pipes/{pipe_name_or_id}/copy?{urlencode(params)}", method="POST")
|
|
644
650
|
|
|
645
651
|
async def pipe_resume_copy(self, pipe_name_or_id: str):
|
|
@@ -282,12 +282,16 @@ def extract_column_names_from_sorting_key_part(part: str) -> List[str]:
|
|
|
282
282
|
"""
|
|
283
283
|
Extract actual column names from a sorting key part (which might be an expression).
|
|
284
284
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
285
|
+
>>> extract_column_names_from_sorting_key_part("shop")
|
|
286
|
+
['shop']
|
|
287
|
+
>>> extract_column_names_from_sorting_key_part("`column_name`")
|
|
288
|
+
['column_name']
|
|
289
|
+
>>> extract_column_names_from_sorting_key_part("ifNull(ad_id, '')")
|
|
290
|
+
['ad_id']
|
|
291
|
+
>>> extract_column_names_from_sorting_key_part("toDate(timestamp)")
|
|
292
|
+
['timestamp']
|
|
293
|
+
>>> extract_column_names_from_sorting_key_part("concat(first_name, last_name)")
|
|
294
|
+
['first_name', 'last_name']
|
|
291
295
|
"""
|
|
292
296
|
columns = []
|
|
293
297
|
|
|
@@ -312,10 +316,20 @@ def parse_sorting_key_column_names(sorting_key: str) -> List[str]:
|
|
|
312
316
|
"""
|
|
313
317
|
Extract all column names from a sorting key expression.
|
|
314
318
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
+
>>> parse_sorting_key_column_names("shop, event_date, channel")
|
|
320
|
+
['shop', 'event_date', 'channel']
|
|
321
|
+
>>> parse_sorting_key_column_names("shop, event_date, ifNull(ad_id, ''), event_id")
|
|
322
|
+
['shop', 'event_date', 'ad_id', 'event_id']
|
|
323
|
+
>>> parse_sorting_key_column_names("tuple(shop, toDate(timestamp))")
|
|
324
|
+
['shop', 'timestamp']
|
|
325
|
+
>>> parse_sorting_key_column_names("timestamp, substring(value, 2, 1)")
|
|
326
|
+
['timestamp', 'value']
|
|
327
|
+
>>> parse_sorting_key_column_names("cityHash64(id)")
|
|
328
|
+
['id']
|
|
329
|
+
>>> parse_sorting_key_column_names("toStartOfHour(timestamp)")
|
|
330
|
+
['timestamp']
|
|
331
|
+
>>> parse_sorting_key_column_names("toStartOfHour(timestamp), id, substring(a, 2, 1)")
|
|
332
|
+
['timestamp', 'id', 'a']
|
|
319
333
|
"""
|
|
320
334
|
# Remove tuple() wrapper if present
|
|
321
335
|
column_str = sorting_key
|
|
@@ -611,7 +625,6 @@ class Datafile:
|
|
|
611
625
|
|
|
612
626
|
def _parse_sorting_key_columns(self, sorting_key: str, engine_ver_column: Optional[str]) -> List[str]:
|
|
613
627
|
"""Parse sorting key to extract column names and validate constraints."""
|
|
614
|
-
# Validate ENGINE_VER column constraint early
|
|
615
628
|
if engine_ver_column and engine_ver_column in sorting_key:
|
|
616
629
|
raise DatafileValidationError(
|
|
617
630
|
f"ENGINE_VER column '{engine_ver_column}' cannot be included in the sorting key for ReplacingMergeTree. "
|
|
@@ -620,36 +633,33 @@ class Datafile:
|
|
|
620
633
|
f"define the record identity (what makes it unique), while ENGINE_VER tracks which version to keep."
|
|
621
634
|
)
|
|
622
635
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
636
|
+
self._validate_no_aggregate_functions_in_sorting_key(sorting_key)
|
|
637
|
+
|
|
638
|
+
return parse_sorting_key_column_names(sorting_key)
|
|
639
|
+
|
|
640
|
+
def _validate_no_aggregate_functions_in_sorting_key(self, sorting_key: str) -> None:
|
|
641
|
+
"""Validate that sorting key doesn't contain aggregate function expressions."""
|
|
642
|
+
for match in re.finditer(r"(\w+)\s*\(", sorting_key):
|
|
643
|
+
func_name = match.group(1)
|
|
644
|
+
if self._is_aggregate_function_expression(func_name):
|
|
645
|
+
start = match.start()
|
|
646
|
+
paren_start = match.end() - 1
|
|
647
|
+
depth = 1
|
|
648
|
+
pos = paren_start + 1
|
|
649
|
+
while pos < len(sorting_key) and depth > 0:
|
|
650
|
+
if sorting_key[pos] == "(":
|
|
651
|
+
depth += 1
|
|
652
|
+
elif sorting_key[pos] == ")":
|
|
653
|
+
depth -= 1
|
|
654
|
+
pos += 1
|
|
655
|
+
full_expr = sorting_key[start:pos]
|
|
634
656
|
raise DatafileValidationError(
|
|
635
|
-
f"Sorting key contains aggregate function expression '{
|
|
657
|
+
f"Sorting key contains aggregate function expression '{full_expr}'. "
|
|
658
|
+
f"Aggregate function expressions cannot be used in sorting keys."
|
|
636
659
|
)
|
|
637
660
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
sorting_key_columns.extend(extracted_columns)
|
|
641
|
-
|
|
642
|
-
return sorting_key_columns
|
|
643
|
-
|
|
644
|
-
def _is_aggregate_function_expression(self, part: str) -> bool:
|
|
645
|
-
"""Check if a sorting key part is an aggregate function expression."""
|
|
646
|
-
if not ("(" in part and part.endswith(")")):
|
|
647
|
-
return False
|
|
648
|
-
|
|
649
|
-
func_start = part.find("(")
|
|
650
|
-
func_name = part[:func_start].strip().lower()
|
|
651
|
-
|
|
652
|
-
aggregate_function_names = {
|
|
661
|
+
_AGGREGATE_FUNCTION_NAMES = frozenset(
|
|
662
|
+
{
|
|
653
663
|
"sum",
|
|
654
664
|
"count",
|
|
655
665
|
"avg",
|
|
@@ -669,8 +679,11 @@ class Datafile:
|
|
|
669
679
|
"groupuniqarraymerge",
|
|
670
680
|
"uniqmerge",
|
|
671
681
|
}
|
|
682
|
+
)
|
|
672
683
|
|
|
673
|
-
|
|
684
|
+
def _is_aggregate_function_expression(self, func_name: str) -> bool:
|
|
685
|
+
"""Check if a function name is an aggregate function."""
|
|
686
|
+
return func_name.lower() in self._AGGREGATE_FUNCTION_NAMES
|
|
674
687
|
|
|
675
688
|
def _validate_columns_against_schema(
|
|
676
689
|
self, sorting_key_columns: List[str], schema_columns: Dict[str, Dict[str, Any]]
|
|
@@ -680,10 +693,11 @@ class Datafile:
|
|
|
680
693
|
return # No schema information available, can't validate
|
|
681
694
|
|
|
682
695
|
for col_name in sorting_key_columns:
|
|
683
|
-
|
|
696
|
+
column_info = schema_columns.get(col_name)
|
|
697
|
+
if column_info is None:
|
|
684
698
|
continue
|
|
685
699
|
|
|
686
|
-
self._validate_single_column(col_name,
|
|
700
|
+
self._validate_single_column(col_name, column_info)
|
|
687
701
|
|
|
688
702
|
def _validate_single_column(self, col_name: str, column_info: Dict[str, Any]) -> None:
|
|
689
703
|
"""Validate a single column for use in sorting keys."""
|
|
@@ -36,6 +36,7 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
36
36
|
{"name": "read_bytes", "type": "UInt64"},
|
|
37
37
|
{"name": "read_rows", "type": "UInt64"},
|
|
38
38
|
{"name": "cpu_time", "type": "Float32"},
|
|
39
|
+
{"name": "result_rows", "type": "UInt64"},
|
|
39
40
|
{"name": "url", "type": "Nullable(String)"},
|
|
40
41
|
{"name": "error", "type": "UInt8"},
|
|
41
42
|
{"name": "status_code", "type": "Int32"},
|
|
@@ -90,11 +91,8 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
90
91
|
{"name": "import_id", "type": "String"},
|
|
91
92
|
{"name": "job_id", "type": "Nullable(String)"},
|
|
92
93
|
{"name": "source", "type": "String"},
|
|
93
|
-
{"name": "token_id", "type": "String"},
|
|
94
94
|
{"name": "block_id", "type": "String"},
|
|
95
95
|
{"name": "status", "type": "String"},
|
|
96
|
-
{"name": "user_id", "type": "String"},
|
|
97
|
-
{"name": "user_mail", "type": "String"},
|
|
98
96
|
{"name": "datasource_id", "type": "String"},
|
|
99
97
|
{"name": "datasource_name", "type": "String"},
|
|
100
98
|
{"name": "start_offset", "type": "Nullable(Int64)"},
|
|
@@ -125,6 +123,8 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
125
123
|
{"name": "result", "type": "String"},
|
|
126
124
|
{"name": "elapsed_time", "type": "Float32"},
|
|
127
125
|
{"name": "error", "type": "Nullable(String)"},
|
|
126
|
+
{"name": "Options.Names", "type": "Array(String)"},
|
|
127
|
+
{"name": "Options.Values", "type": "Array(String)"},
|
|
128
128
|
{"name": "request_id", "type": "String"},
|
|
129
129
|
{"name": "import_id", "type": "Nullable(String)"},
|
|
130
130
|
{"name": "job_id", "type": "Nullable(String)"},
|
|
@@ -133,9 +133,9 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
133
133
|
{"name": "blocks_ids", "type": "Array(String)"},
|
|
134
134
|
{"name": "operation_id", "type": "String"},
|
|
135
135
|
{"name": "read_rows", "type": "UInt64"},
|
|
136
|
+
{"name": "read_bytes", "type": "UInt64"},
|
|
136
137
|
{"name": "cpu_time", "type": "Float32"},
|
|
137
138
|
{"name": "memory_usage", "type": "UInt64"},
|
|
138
|
-
{"name": "read_bytes", "type": "UInt64"},
|
|
139
139
|
{"name": "written_rows", "type": "UInt64"},
|
|
140
140
|
{"name": "written_bytes", "type": "UInt64"},
|
|
141
141
|
{"name": "written_rows_quarantine", "type": "UInt64"},
|
|
@@ -143,6 +143,7 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
143
143
|
{"name": "pipe_id", "type": "String"},
|
|
144
144
|
{"name": "pipe_name", "type": "String"},
|
|
145
145
|
{"name": "release", "type": "String"},
|
|
146
|
+
{"name": "resource_tags", "type": "Array(String)"},
|
|
146
147
|
],
|
|
147
148
|
},
|
|
148
149
|
{
|
|
@@ -156,7 +157,8 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
156
157
|
},
|
|
157
158
|
"columns": [
|
|
158
159
|
{"name": "event_date", "type": "DateTime"},
|
|
159
|
-
{"name": "
|
|
160
|
+
{"name": "datasource_id", "type": "String"},
|
|
161
|
+
{"name": "datasource_name", "type": "String"},
|
|
160
162
|
{"name": "event_type", "type": "LowCardinality(String)"},
|
|
161
163
|
{"name": "pipe_id", "type": "String"},
|
|
162
164
|
{"name": "pipe_name", "type": "String"},
|
|
@@ -193,6 +195,7 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
193
195
|
{"name": "url", "type": "Nullable(String)"},
|
|
194
196
|
{"name": "status_code", "type": "Nullable(Int32)"},
|
|
195
197
|
{"name": "error", "type": "Nullable(String)"},
|
|
198
|
+
{"name": "resource_tags", "type": "Array(String)"},
|
|
196
199
|
],
|
|
197
200
|
},
|
|
198
201
|
{
|
|
@@ -252,7 +255,6 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
252
255
|
{"name": "query_normalized", "type": "String"},
|
|
253
256
|
{"name": "error_code", "type": "Int32"},
|
|
254
257
|
{"name": "error", "type": "Nullable(String)"},
|
|
255
|
-
{"name": "url", "type": "String"},
|
|
256
258
|
{"name": "duration", "type": "UInt64"},
|
|
257
259
|
{"name": "read_rows", "type": "UInt64"},
|
|
258
260
|
{"name": "read_bytes", "type": "UInt64"},
|
|
@@ -337,7 +339,7 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
337
339
|
"engine": {},
|
|
338
340
|
"columns": [
|
|
339
341
|
{"name": "timestamp", "type": "DateTime"},
|
|
340
|
-
{"name": "
|
|
342
|
+
{"name": "event", "type": "LowCardinality(String)"},
|
|
341
343
|
{"name": "origin_provider", "type": "LowCardinality(String)"},
|
|
342
344
|
{"name": "origin_region", "type": "LowCardinality(String)"},
|
|
343
345
|
{"name": "destination_provider", "type": "LowCardinality(String)"},
|
|
@@ -441,10 +443,7 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
441
443
|
"columns": [
|
|
442
444
|
{"name": "start_time", "type": "DateTime"},
|
|
443
445
|
{"name": "end_time", "type": "DateTime"},
|
|
444
|
-
{"name": "organization_id", "type": "String"},
|
|
445
|
-
{"name": "organization_name", "type": "String"},
|
|
446
446
|
{"name": "workspace_id", "type": "String"},
|
|
447
|
-
{"name": "workspace_name", "type": "String"},
|
|
448
447
|
{"name": "user_email", "type": "String"},
|
|
449
448
|
{"name": "request_id", "type": "String"},
|
|
450
449
|
{"name": "prompt_tokens", "type": "UInt32"},
|
|
@@ -466,7 +465,6 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
466
465
|
"partition_key": "toYYYYMM(run_validation)",
|
|
467
466
|
},
|
|
468
467
|
"columns": [
|
|
469
|
-
{"name": "cluster", "type": "LowCardinality(String)"},
|
|
470
468
|
{"name": "host", "type": "LowCardinality(String)"},
|
|
471
469
|
{"name": "version", "type": "LowCardinality(String)"},
|
|
472
470
|
{"name": "stable_version", "type": "LowCardinality(String)"},
|
|
@@ -553,6 +551,7 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
553
551
|
{"name": "plan", "type": "String"},
|
|
554
552
|
{"name": "created_at", "type": "DateTime"},
|
|
555
553
|
{"name": "deleted_at", "type": "Nullable(DateTime)"},
|
|
554
|
+
{"name": "origin", "type": "String"},
|
|
556
555
|
],
|
|
557
556
|
},
|
|
558
557
|
{
|
|
@@ -609,6 +608,8 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
609
608
|
{"name": "result", "type": "String"},
|
|
610
609
|
{"name": "elapsed_time", "type": "Float32"},
|
|
611
610
|
{"name": "error", "type": "Nullable(String)"},
|
|
611
|
+
{"name": "Options.Names", "type": "Array(String)"},
|
|
612
|
+
{"name": "Options.Values", "type": "Array(String)"},
|
|
612
613
|
{"name": "request_id", "type": "String"},
|
|
613
614
|
{"name": "import_id", "type": "Nullable(String)"},
|
|
614
615
|
{"name": "job_id", "type": "Nullable(String)"},
|
|
@@ -617,16 +618,16 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
617
618
|
{"name": "blocks_ids", "type": "Array(String)"},
|
|
618
619
|
{"name": "operation_id", "type": "String"},
|
|
619
620
|
{"name": "read_rows", "type": "UInt64"},
|
|
621
|
+
{"name": "read_bytes", "type": "UInt64"},
|
|
620
622
|
{"name": "cpu_time", "type": "Float32"},
|
|
621
623
|
{"name": "memory_usage", "type": "UInt64"},
|
|
622
|
-
{"name": "read_bytes", "type": "UInt64"},
|
|
623
624
|
{"name": "written_rows", "type": "UInt64"},
|
|
624
625
|
{"name": "written_bytes", "type": "UInt64"},
|
|
625
626
|
{"name": "written_rows_quarantine", "type": "UInt64"},
|
|
626
627
|
{"name": "written_bytes_quarantine", "type": "UInt64"},
|
|
627
628
|
{"name": "pipe_id", "type": "String"},
|
|
628
629
|
{"name": "pipe_name", "type": "String"},
|
|
629
|
-
{"name": "
|
|
630
|
+
{"name": "resource_tags", "type": "Array(String)"},
|
|
630
631
|
],
|
|
631
632
|
},
|
|
632
633
|
{
|
|
@@ -641,6 +642,8 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
641
642
|
"columns": [
|
|
642
643
|
{"name": "event_date", "type": "DateTime"},
|
|
643
644
|
{"name": "workspace_id", "type": "String"},
|
|
645
|
+
{"name": "datasource_id", "type": "String"},
|
|
646
|
+
{"name": "datasource_name", "type": "String"},
|
|
644
647
|
{"name": "event_type", "type": "LowCardinality(String)"},
|
|
645
648
|
{"name": "pipe_id", "type": "String"},
|
|
646
649
|
{"name": "pipe_name", "type": "String"},
|
|
@@ -648,12 +651,14 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
648
651
|
{"name": "executions", "type": "UInt64"},
|
|
649
652
|
{"name": "avg_elapsed_time_state", "type": "AggregateFunction(avg, Float32)"},
|
|
650
653
|
{"name": "quantiles_state", "type": "AggregateFunction(quantiles(0.9, 0.95, 0.99), Float64)"},
|
|
651
|
-
{"name": "read_rows", "type": "UInt64"},
|
|
652
654
|
{"name": "read_bytes", "type": "UInt64"},
|
|
653
|
-
{"name": "
|
|
655
|
+
{"name": "read_rows", "type": "UInt64"},
|
|
654
656
|
{"name": "written_bytes", "type": "UInt64"},
|
|
657
|
+
{"name": "written_rows", "type": "UInt64"},
|
|
655
658
|
{"name": "written_rows_quarantine", "type": "UInt64"},
|
|
656
659
|
{"name": "written_bytes_quarantine", "type": "UInt64"},
|
|
660
|
+
{"name": "cpu_time", "type": "Float32"},
|
|
661
|
+
{"name": "resource_tags", "type": "Array(String)"},
|
|
657
662
|
],
|
|
658
663
|
},
|
|
659
664
|
{
|
|
@@ -703,6 +708,7 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
703
708
|
{"name": "read_bytes", "type": "UInt64"},
|
|
704
709
|
{"name": "read_rows", "type": "UInt64"},
|
|
705
710
|
{"name": "cpu_time", "type": "Float32"},
|
|
711
|
+
{"name": "result_rows", "type": "UInt64"},
|
|
706
712
|
{"name": "url", "type": "Nullable(String)"},
|
|
707
713
|
{"name": "error", "type": "UInt8"},
|
|
708
714
|
{"name": "status_code", "type": "Int32"},
|
|
@@ -712,6 +718,7 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
712
718
|
{"name": "release", "type": "String"},
|
|
713
719
|
{"name": "user_agent", "type": "Nullable(String)"},
|
|
714
720
|
{"name": "resource_tags", "type": "Array(String)"},
|
|
721
|
+
{"name": "memory_usage", "type": "UInt64"},
|
|
715
722
|
],
|
|
716
723
|
},
|
|
717
724
|
{
|
|
@@ -722,7 +729,7 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
722
729
|
"columns": [
|
|
723
730
|
{"name": "workspace_id", "type": "String"},
|
|
724
731
|
{"name": "timestamp", "type": "DateTime"},
|
|
725
|
-
{"name": "
|
|
732
|
+
{"name": "event", "type": "LowCardinality(String)"},
|
|
726
733
|
{"name": "origin_provider", "type": "LowCardinality(String)"},
|
|
727
734
|
{"name": "origin_region", "type": "LowCardinality(String)"},
|
|
728
735
|
{"name": "destination_provider", "type": "LowCardinality(String)"},
|
|
@@ -801,7 +808,6 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
801
808
|
{"name": "query_normalized", "type": "String"},
|
|
802
809
|
{"name": "error_code", "type": "Int32"},
|
|
803
810
|
{"name": "error", "type": "Nullable(String)"},
|
|
804
|
-
{"name": "url", "type": "String"},
|
|
805
811
|
{"name": "duration", "type": "UInt64"},
|
|
806
812
|
{"name": "read_rows", "type": "UInt64"},
|
|
807
813
|
{"name": "read_bytes", "type": "UInt64"},
|
|
@@ -893,6 +899,7 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
893
899
|
{"name": "url", "type": "Nullable(String)"},
|
|
894
900
|
{"name": "status_code", "type": "Nullable(Int32)"},
|
|
895
901
|
{"name": "error", "type": "Nullable(String)"},
|
|
902
|
+
{"name": "resource_tags", "type": "Array(String)"},
|
|
896
903
|
],
|
|
897
904
|
},
|
|
898
905
|
{
|
|
@@ -934,7 +941,7 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
934
941
|
{"name": "organization_name", "type": "String"},
|
|
935
942
|
{"name": "plan_qps", "type": "SimpleAggregateFunction(max, Int64)"},
|
|
936
943
|
{"name": "total_qps", "type": "UInt64"},
|
|
937
|
-
{"name": "
|
|
944
|
+
{"name": "overages", "type": "Int64"},
|
|
938
945
|
],
|
|
939
946
|
},
|
|
940
947
|
{
|
|
@@ -681,29 +681,3 @@ def sync_to_async(
|
|
|
681
681
|
thread_sensitive=thread_sensitive,
|
|
682
682
|
executor=executor,
|
|
683
683
|
)
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
def run_function_in_event_loop(func_def: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
|
|
687
|
-
"""Run an async function, handling the case where an event loop may already be running."""
|
|
688
|
-
try:
|
|
689
|
-
asyncio.get_running_loop()
|
|
690
|
-
# If we're already in an event loop, we need to run the coroutine in a thread
|
|
691
|
-
# to avoid blocking the current event loop
|
|
692
|
-
import concurrent.futures
|
|
693
|
-
|
|
694
|
-
def run_in_new_loop() -> Any:
|
|
695
|
-
# Create a new event loop for this thread
|
|
696
|
-
new_loop = asyncio.new_event_loop()
|
|
697
|
-
asyncio.set_event_loop(new_loop)
|
|
698
|
-
try:
|
|
699
|
-
return new_loop.run_until_complete(func_def(*args, **kwargs))
|
|
700
|
-
finally:
|
|
701
|
-
new_loop.close()
|
|
702
|
-
|
|
703
|
-
# Run in a separate thread to avoid blocking the current event loop
|
|
704
|
-
with concurrent.futures.ThreadPoolExecutor() as executor:
|
|
705
|
-
future = executor.submit(run_in_new_loop)
|
|
706
|
-
return future.result()
|
|
707
|
-
except RuntimeError:
|
|
708
|
-
# No event loop running, use asyncio.run()
|
|
709
|
-
return asyncio.run(func_def(*args, **kwargs))
|
|
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
|
|
|
4
4
|
__url__ = 'https://www.tinybird.co/docs/forward/commands'
|
|
5
5
|
__author__ = 'Tinybird'
|
|
6
6
|
__author_email__ = 'support@tinybird.co'
|
|
7
|
-
__version__ = '4.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '4.4.0'
|
|
8
|
+
__revision__ = 'b610ec3'
|
|
@@ -5,7 +5,7 @@ import ssl
|
|
|
5
5
|
import time
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from typing import Any, Callable, Dict, List, Mapping, Optional, Set, Tuple, Union
|
|
8
|
-
from urllib.parse import quote, urlencode
|
|
8
|
+
from urllib.parse import parse_qsl, quote, urlencode, urlsplit
|
|
9
9
|
|
|
10
10
|
import requests
|
|
11
11
|
import requests.adapters
|
|
@@ -89,6 +89,7 @@ class TinyB:
|
|
|
89
89
|
semver: Optional[str] = None,
|
|
90
90
|
env: Optional[str] = "production",
|
|
91
91
|
staging: bool = False,
|
|
92
|
+
request_from: Optional[str] = None,
|
|
92
93
|
):
|
|
93
94
|
ctx = ssl.create_default_context()
|
|
94
95
|
ctx.check_hostname = False
|
|
@@ -102,6 +103,12 @@ class TinyB:
|
|
|
102
103
|
self.semver = semver
|
|
103
104
|
self.env = env
|
|
104
105
|
self.staging = staging
|
|
106
|
+
self.request_from = request_from
|
|
107
|
+
|
|
108
|
+
@staticmethod
|
|
109
|
+
def _has_query_param(url: str, param_name: str) -> bool:
|
|
110
|
+
query_params = parse_qsl(urlsplit(url).query, keep_blank_values=True)
|
|
111
|
+
return any(key == param_name for key, _ in query_params)
|
|
105
112
|
|
|
106
113
|
def _req_raw(
|
|
107
114
|
self,
|
|
@@ -124,6 +131,8 @@ class TinyB:
|
|
|
124
131
|
url += ("&" if "?" in url else "?") + "__tb__semver=" + self.semver
|
|
125
132
|
if self.staging:
|
|
126
133
|
url += ("&" if "?" in url else "?") + "__tb__deployment=staging"
|
|
134
|
+
if self.request_from and not self._has_query_param(url, "from"):
|
|
135
|
+
url += ("&" if "?" in url else "?") + "from=" + quote(self.request_from, safe="")
|
|
127
136
|
|
|
128
137
|
verify_ssl = not self.disable_ssl_checks
|
|
129
138
|
try:
|
|
@@ -636,11 +645,18 @@ class TinyB:
|
|
|
636
645
|
return self._req(f"/v0/pipes/{pipe_name_or_id}/nodes/{node_id}/copy", method="DELETE")
|
|
637
646
|
|
|
638
647
|
def pipe_run(
|
|
639
|
-
self,
|
|
648
|
+
self,
|
|
649
|
+
pipe_name_or_id: str,
|
|
650
|
+
pipe_type: str,
|
|
651
|
+
params: Optional[Dict[str, str]] = None,
|
|
652
|
+
mode: Optional[str] = None,
|
|
653
|
+
on_demand_compute: bool = False,
|
|
640
654
|
):
|
|
641
655
|
params = {**params} if params else {}
|
|
642
656
|
if mode:
|
|
643
657
|
params["_mode"] = mode
|
|
658
|
+
if on_demand_compute:
|
|
659
|
+
params["on_demand_compute"] = "true"
|
|
644
660
|
return self._req(f"/v0/pipes/{pipe_name_or_id}/{pipe_type}?{urlencode(params)}", method="POST")
|
|
645
661
|
|
|
646
662
|
def pipe_resume_copy(self, pipe_name_or_id: str):
|
|
@@ -209,6 +209,7 @@ def build_project(
|
|
|
209
209
|
TINYBIRD_API_URL = urljoin(tb_client.host, build_url)
|
|
210
210
|
logging.debug(TINYBIRD_API_URL)
|
|
211
211
|
TINYBIRD_API_KEY = tb_client.token
|
|
212
|
+
request_from = getattr(tb_client, "request_from", None)
|
|
212
213
|
error: Optional[str] = None
|
|
213
214
|
|
|
214
215
|
try:
|
|
@@ -235,8 +236,8 @@ def build_project(
|
|
|
235
236
|
|
|
236
237
|
files.append((MULTIPART_BOUNDARY_DATA_PROJECT, (relative_path, content, content_type)))
|
|
237
238
|
HEADERS = {"Authorization": f"Bearer {TINYBIRD_API_KEY}"}
|
|
238
|
-
|
|
239
|
-
r = requests.post(TINYBIRD_API_URL, files=files, headers=HEADERS)
|
|
239
|
+
params = {"from": request_from} if request_from else None
|
|
240
|
+
r = requests.post(TINYBIRD_API_URL, files=files, headers=HEADERS, params=params)
|
|
240
241
|
try:
|
|
241
242
|
result = r.json()
|
|
242
243
|
except Exception as e:
|
|
@@ -64,8 +64,8 @@ DEV_MODE_ROUTED_COMMANDS = {"build", "deploy"}
|
|
|
64
64
|
SDK_PROJECT_ROUTED_COMMANDS = {"build", "deploy", "preview"}
|
|
65
65
|
TS_PROJECT_ROUTED_COMMANDS = SDK_PROJECT_ROUTED_COMMANDS
|
|
66
66
|
COMMANDS_ALWAYS_CLOUD = {"infra", "branch", "environment", "workspace", "preview"}
|
|
67
|
-
PROJECT_TYPE_TYPESCRIPT = "
|
|
68
|
-
PROJECT_TYPE_PYTHON = "python"
|
|
67
|
+
PROJECT_TYPE_TYPESCRIPT = "ts-sdk"
|
|
68
|
+
PROJECT_TYPE_PYTHON = "python-sdk"
|
|
69
69
|
PROJECT_TYPE_CLI = "cli"
|
|
70
70
|
PROJECT_TYPES = {PROJECT_TYPE_TYPESCRIPT, PROJECT_TYPE_PYTHON, PROJECT_TYPE_CLI}
|
|
71
71
|
CLI_PROJECT_MARKERS = (
|
|
@@ -613,7 +613,9 @@ def cli(
|
|
|
613
613
|
user_token = os.environ.get("TB_USER_TOKEN", "")
|
|
614
614
|
|
|
615
615
|
config = get_config(host, token, user_token=user_token, config_file=config_temp._path)
|
|
616
|
-
|
|
616
|
+
project_type = get_project_type_from_tinybird_config(os.getcwd()) or PROJECT_TYPE_CLI
|
|
617
|
+
ctx.ensure_object(dict)["project_type"] = project_type
|
|
618
|
+
client = _get_tb_client(config.get("token", ""), config["host"], request_from=project_type)
|
|
617
619
|
|
|
618
620
|
tinybird_dev_mode = get_dev_mode_from_tinybird_config(os.getcwd())
|
|
619
621
|
if tinybird_dev_mode:
|
|
@@ -632,8 +634,6 @@ def cli(
|
|
|
632
634
|
|
|
633
635
|
project = Project(folder=folder, workspace_name=config.get("name", ""), max_depth=max_depth)
|
|
634
636
|
|
|
635
|
-
project_type = get_project_type_from_tinybird_config(os.getcwd())
|
|
636
|
-
|
|
637
637
|
sdk_virtual_project: Optional[Union[PythonVirtualProject, TypescriptVirtualProject]] = None
|
|
638
638
|
if ctx.invoked_subcommand in SDK_PROJECT_ROUTED_COMMANDS:
|
|
639
639
|
try:
|
|
@@ -724,6 +724,7 @@ def cli(
|
|
|
724
724
|
effective_cloud,
|
|
725
725
|
staging,
|
|
726
726
|
project=project,
|
|
727
|
+
project_type=project_type,
|
|
727
728
|
show_warnings=version_warning,
|
|
728
729
|
branch=effective_branch,
|
|
729
730
|
create_branch_if_missing=(
|
|
@@ -1013,6 +1014,7 @@ def create_ctx_client(
|
|
|
1013
1014
|
cloud: bool,
|
|
1014
1015
|
staging: bool,
|
|
1015
1016
|
project: Project,
|
|
1017
|
+
project_type: str = PROJECT_TYPE_CLI,
|
|
1016
1018
|
show_warnings: bool = True,
|
|
1017
1019
|
branch: Optional[str] = None,
|
|
1018
1020
|
create_branch_if_missing: bool = False,
|
|
@@ -1066,6 +1068,7 @@ def create_ctx_client(
|
|
|
1066
1068
|
staging=staging,
|
|
1067
1069
|
branch=branch,
|
|
1068
1070
|
create_branch_if_missing=create_branch_if_missing,
|
|
1071
|
+
request_from=project_type,
|
|
1069
1072
|
)
|
|
1070
1073
|
test = command in command_always_test
|
|
1071
1074
|
if show_warnings and command:
|
|
@@ -360,7 +360,9 @@ def _get_tb_client(
|
|
|
360
360
|
staging: bool = False,
|
|
361
361
|
branch: Optional[str] = None,
|
|
362
362
|
create_branch_if_missing: bool = False,
|
|
363
|
+
request_from: Optional[str] = None,
|
|
363
364
|
) -> TinyB:
|
|
365
|
+
resolved_request_from = request_from
|
|
364
366
|
disable_ssl: bool = getenv_bool("TB_DISABLE_SSL_CHECKS", False)
|
|
365
367
|
cloud_client = TinyB(
|
|
366
368
|
token,
|
|
@@ -369,6 +371,7 @@ def _get_tb_client(
|
|
|
369
371
|
disable_ssl_checks=disable_ssl,
|
|
370
372
|
send_telemetry=True,
|
|
371
373
|
staging=staging,
|
|
374
|
+
request_from=resolved_request_from,
|
|
372
375
|
)
|
|
373
376
|
|
|
374
377
|
if not branch:
|
|
@@ -402,13 +405,16 @@ def _get_tb_client(
|
|
|
402
405
|
disable_ssl_checks=disable_ssl,
|
|
403
406
|
send_telemetry=True,
|
|
404
407
|
staging=staging,
|
|
408
|
+
request_from=resolved_request_from,
|
|
405
409
|
)
|
|
406
410
|
|
|
407
411
|
|
|
408
412
|
def create_tb_client(ctx: Context) -> TinyB:
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
413
|
+
obj = ctx.ensure_object(dict)
|
|
414
|
+
token = obj["config"].get("token", "")
|
|
415
|
+
host = obj["config"].get("host", DEFAULT_API_HOST)
|
|
416
|
+
request_from = obj.get("project_type")
|
|
417
|
+
return _get_tb_client(token, host, request_from=request_from)
|
|
412
418
|
|
|
413
419
|
|
|
414
420
|
def _analyze(filename: str, client: TinyB, format: str):
|
|
@@ -1668,6 +1674,7 @@ def run_aws_iamrole_connection_flow(
|
|
|
1668
1674
|
token=config.get("token", ""),
|
|
1669
1675
|
host=config.get("host", ""),
|
|
1670
1676
|
staging=False,
|
|
1677
|
+
request_from=getattr(client, "request_from", None),
|
|
1671
1678
|
)
|
|
1672
1679
|
except Exception as e:
|
|
1673
1680
|
click.echo(FeedbackManager.warning(message=f"Failed to initialize cloud client: {e}"))
|
|
@@ -222,6 +222,7 @@ def connection_create_gcs(ctx: Context) -> None:
|
|
|
222
222
|
token=token,
|
|
223
223
|
host=host,
|
|
224
224
|
staging=False,
|
|
225
|
+
request_from=getattr(client, "request_from", None),
|
|
225
226
|
)
|
|
226
227
|
creds_json = get_gcs_svc_account_creds()
|
|
227
228
|
secret_name = f"gcs_svc_account_creds_{connection_name}_{unique_suffix}"
|
|
@@ -190,6 +190,7 @@ def connection_create_kafka(
|
|
|
190
190
|
token=token,
|
|
191
191
|
host=host,
|
|
192
192
|
staging=False,
|
|
193
|
+
request_from=getattr(obj.get("client"), "request_from", None),
|
|
193
194
|
)
|
|
194
195
|
if tb_secret_bootstrap_servers:
|
|
195
196
|
prod_client.create_secret(name=tb_secret_bootstrap_servers, value=bootstrap_servers)
|