tinybird 4.6.21__tar.gz → 4.6.21.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-4.6.21 → tinybird-4.6.21.dev0}/PKG-INFO +1 -11
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/pyproject.toml +1 -13
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/client.py +0 -4
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/datafile/common.py +1 -9
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/datatypes.py +12 -34
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/feedback_manager.py +0 -5
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/sql_template.py +6 -9
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/__cli__.py +2 -2
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/client.py +0 -4
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/copy.py +1 -33
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/build.py +0 -1
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/format_pipe.py +0 -4
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/playground.py +0 -1
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/deployment_common.py +6 -4
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/feedback_manager.py +0 -5
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/pipe.py +21 -40
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tornado_template.py +0 -204
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird.egg-info/PKG-INFO +1 -11
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird.egg-info/SOURCES.txt +1 -3
- tinybird-4.6.21/tinybird/utils/__init__.py +0 -0
- tinybird-4.6.21/tinybird/utils/bools.py +0 -19
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/setup.cfg +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/__cli__.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/ch_utils/engine.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/check_pypi.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/config.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/context.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/datafile/exceptions.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/datafile/parse_connection.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/datafile/parse_datasource.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/datafile/parse_pipe.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/git_settings.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/iterating/__init__.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/iterating/data_branch_modes.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/prompts.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/service_datasources.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/sql.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/sql_toolset.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/syncasync.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/check_pypi.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/cli.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/config.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/branch.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/build.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/build_common.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/cicd.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/cli.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/common.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/config.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/connection.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/connection_dynamodb.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/connection_kafka.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/connection_s3.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/create.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/build_common.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/diff.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/fixture.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/format_common.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/format_connection.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datafile/pull.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/datasource.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/deployment.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/deprecations.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/endpoint.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/exceptions.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/fmt.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/info.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/infra.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/job.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/job_common.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/llm.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/llm_utils.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/local.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/local_common.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/local_logs.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/login.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/login_common.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/logout.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/logs.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/materialization.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/open.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/pipe.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/preview.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/project.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/project_commands.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/py_project.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/query_output.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/regions.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/secret.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/secret_common.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/sink.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/table.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/telemetry.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/test.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/test_common.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/token.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/ts_project.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/watch.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/workspace.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb/modules/workspace_members.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/common.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird.egg-info/dependency_links.txt +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird.egg-info/entry_points.txt +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/tinybird.egg-info/requires.txt +0 -0
- {tinybird-4.6.21 → tinybird-4.6.21.dev0}/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.6.21
|
|
3
|
+
Version: 4.6.21.dev0
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/forward/commands
|
|
6
6
|
Author: Tinybird
|
|
@@ -52,16 +52,6 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
52
52
|
Changelog
|
|
53
53
|
----------
|
|
54
54
|
|
|
55
|
-
4.6.21
|
|
56
|
-
********
|
|
57
|
-
|
|
58
|
-
- `Fixed` ``tb deployment discard`` now discards the deployment that is not live, instead of assuming the live deployment is listed first. Previously, if removing the old deployment failed after a promotion, the command refused to discard it.
|
|
59
|
-
|
|
60
|
-
4.6.20
|
|
61
|
-
********
|
|
62
|
-
|
|
63
|
-
- `Added` Copy pipes accept ``ON_DEMAND_COMPUTE true`` so scheduled runs use on-demand compute. Manual ``tb copy run`` still requires ``--on-demand-compute``, and asks for confirmation when the local datafile does not enable it (skip it with ``--yes``).
|
|
64
|
-
|
|
65
55
|
4.6.19
|
|
66
56
|
********
|
|
67
57
|
|
|
@@ -22,7 +22,6 @@ dependencies = [
|
|
|
22
22
|
"aiofiles==24.1.0",
|
|
23
23
|
"aiohttp==3.11.2",
|
|
24
24
|
"anthropic==0.55.0",
|
|
25
|
-
"async-lru==2.3.0",
|
|
26
25
|
"aws-msk-iam-sasl-signer-python==1.0.2",
|
|
27
26
|
"cachetools==5.5.0",
|
|
28
27
|
"cffi==1.17.1",
|
|
@@ -151,8 +150,6 @@ doc = [
|
|
|
151
150
|
]
|
|
152
151
|
lint = [
|
|
153
152
|
"botocore-stubs==1.36.23",
|
|
154
|
-
"flake8~=7.3",
|
|
155
|
-
"flake8-async~=26.8",
|
|
156
153
|
"mypy==2.3.1",
|
|
157
154
|
"ruff==0.16.8",
|
|
158
155
|
"types-Markdown",
|
|
@@ -187,12 +184,6 @@ test = [
|
|
|
187
184
|
"rangehttpserver==1.4.0",
|
|
188
185
|
"yappi==1.7.6",
|
|
189
186
|
]
|
|
190
|
-
# Synced automatically by plain `uv run`/`uv sync`, no `--group` needed.
|
|
191
|
-
dev = [
|
|
192
|
-
{ include-group = "test" },
|
|
193
|
-
{ include-group = "deploy" },
|
|
194
|
-
{ include-group = "lint" },
|
|
195
|
-
]
|
|
196
187
|
|
|
197
188
|
[project.scripts]
|
|
198
189
|
tinybird_server = "tinybird.app:run"
|
|
@@ -202,10 +193,7 @@ tb = "tinybird.tb.cli:cli"
|
|
|
202
193
|
colibri = "tinybird.colibri.cli:cli"
|
|
203
194
|
|
|
204
195
|
[tool.uv.workspace]
|
|
205
|
-
members = [
|
|
206
|
-
"chbackups",
|
|
207
|
-
"data_connector",
|
|
208
|
-
]
|
|
196
|
+
members = ["data_connector"]
|
|
209
197
|
|
|
210
198
|
[tool.setuptools]
|
|
211
199
|
include-package-data = true
|
|
@@ -691,7 +691,6 @@ class TinyB:
|
|
|
691
691
|
target_datasource: Optional[str] = None,
|
|
692
692
|
schedule_cron: Optional[str] = None,
|
|
693
693
|
mode: Optional[str] = None,
|
|
694
|
-
on_demand_compute: Optional[bool] = None,
|
|
695
694
|
):
|
|
696
695
|
data = {"schedule_cron": schedule_cron}
|
|
697
696
|
|
|
@@ -701,9 +700,6 @@ class TinyB:
|
|
|
701
700
|
if mode:
|
|
702
701
|
data["mode"] = mode
|
|
703
702
|
|
|
704
|
-
if on_demand_compute is not None:
|
|
705
|
-
data["on_demand_compute"] = "true" if on_demand_compute else "false"
|
|
706
|
-
|
|
707
703
|
return await self._req(f"/v0/pipes/{pipe_name_or_id}/nodes/{node_id}/copy", method="PUT", data=data)
|
|
708
704
|
|
|
709
705
|
async def pipe_remove_copy(self, pipe_name_or_id: str, node_id: str):
|
|
@@ -28,7 +28,6 @@ from tinybird.ch_utils.engine import VALID_ENGINE_PARAMS, EngineParam
|
|
|
28
28
|
from tinybird.datafile.exceptions import IncludeFileNotFoundException, ParseException, ValidationException
|
|
29
29
|
from tinybird.tb.modules.exceptions import CLIPipeException
|
|
30
30
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
31
|
-
from tinybird.utils.bools import parse_optional_bool
|
|
32
31
|
|
|
33
32
|
# Code from sql.py has been duplicated so I can change it without breaking absolutely everything in the app
|
|
34
33
|
# I'll try not to make logic changes, just error reporting changes
|
|
@@ -180,10 +179,9 @@ class CopyParameters(Parameters):
|
|
|
180
179
|
COPY_SCHEDULE = "copy_schedule"
|
|
181
180
|
COPY_MODE = "copy_mode"
|
|
182
181
|
COPY_MODE_ALIAS = "mode" # we need this because bot MODE and COPY_MODE go to `mode` variable inside the node
|
|
183
|
-
ON_DEMAND_COMPUTE = "on_demand_compute"
|
|
184
182
|
MANDATORY_ATTRIBUTES = PipeParameters.MANDATORY_ATTRIBUTES.union({TARGET_DATASOURCE})
|
|
185
183
|
ACCEPTED_ATTRIBUTES = PipeParameters.ACCEPTED_ATTRIBUTES.union(MANDATORY_ATTRIBUTES).union(
|
|
186
|
-
{COPY_SCHEDULE, COPY_MODE_ALIAS
|
|
184
|
+
{COPY_SCHEDULE, COPY_MODE_ALIAS}
|
|
187
185
|
)
|
|
188
186
|
|
|
189
187
|
|
|
@@ -418,11 +416,6 @@ class Datafile:
|
|
|
418
416
|
)
|
|
419
417
|
if not croniter.is_valid(copy_schedule):
|
|
420
418
|
raise DatafileValidationError("COPY node schedule must be @on-demand or a valid cron expression.")
|
|
421
|
-
if CopyParameters.ON_DEMAND_COMPUTE in node:
|
|
422
|
-
try:
|
|
423
|
-
node[CopyParameters.ON_DEMAND_COMPUTE] = parse_optional_bool(node[CopyParameters.ON_DEMAND_COMPUTE])
|
|
424
|
-
except ValueError:
|
|
425
|
-
raise DatafileValidationError("ON_DEMAND_COMPUTE must be true or false")
|
|
426
419
|
for key in node.keys():
|
|
427
420
|
if key not in CopyParameters.valid_params():
|
|
428
421
|
raise DatafileValidationError(
|
|
@@ -2104,7 +2097,6 @@ def parse(
|
|
|
2104
2097
|
"copy_schedule": assign_node_var(CopyParameters.COPY_SCHEDULE),
|
|
2105
2098
|
"copy_mode": assign_node_var("mode"),
|
|
2106
2099
|
"mode": assign_node_var("mode"),
|
|
2107
|
-
"on_demand_compute": assign_node_var(CopyParameters.ON_DEMAND_COMPUTE),
|
|
2108
2100
|
"filter": assign_node_var("filter"),
|
|
2109
2101
|
"token": add_token,
|
|
2110
2102
|
"include": include,
|
|
@@ -120,74 +120,52 @@ def datetime_test(x: str) -> bool:
|
|
|
120
120
|
return any(p.match(x) for p in datetime_patterns)
|
|
121
121
|
|
|
122
122
|
|
|
123
|
-
def bounded_integer(x: str, pattern: re.Pattern[str]) -> Optional[int]:
|
|
124
|
-
if pattern.match(x) is None:
|
|
125
|
-
return None
|
|
126
|
-
digits = x.lstrip("+-").lstrip("0")
|
|
127
|
-
# 256-bit unsigned integers have at most 78 decimal digits.
|
|
128
|
-
if len(digits) > 78:
|
|
129
|
-
return None
|
|
130
|
-
return int(x) if len(x) <= 78 else int(digits or "0") * (-1 if x.startswith("-") else 1)
|
|
131
|
-
|
|
132
|
-
|
|
133
123
|
def int_8_test(x: str) -> bool:
|
|
134
|
-
|
|
135
|
-
return value is not None and -int_8_max <= value < int_8_max
|
|
124
|
+
return intx_re.match(x) is not None and -int_8_max <= int(x) < int_8_max
|
|
136
125
|
|
|
137
126
|
|
|
138
127
|
def int16_test(x: str) -> bool:
|
|
139
|
-
|
|
140
|
-
return value is not None and -int16_max <= value < int16_max
|
|
128
|
+
return intx_re.match(x) is not None and -int16_max <= int(x) < int16_max
|
|
141
129
|
|
|
142
130
|
|
|
143
131
|
def int32_test(x: str) -> bool:
|
|
144
|
-
|
|
145
|
-
return value is not None and -int32_max <= value < int32_max
|
|
132
|
+
return intx_re.match(x) is not None and -int32_max <= int(x) < int32_max
|
|
146
133
|
|
|
147
134
|
|
|
148
135
|
def int64_test(x: str) -> bool:
|
|
149
|
-
|
|
150
|
-
return value is not None and -int64_max <= value < int64_max
|
|
136
|
+
return intx_re.match(x) is not None and -int64_max <= int(x) < int64_max
|
|
151
137
|
|
|
152
138
|
|
|
153
139
|
def int128_test(x: str) -> bool:
|
|
154
|
-
|
|
155
|
-
return value is not None and -int128_max <= value < int128_max
|
|
140
|
+
return intx_re.match(x) is not None and -int128_max <= int(x) < int128_max
|
|
156
141
|
|
|
157
142
|
|
|
158
143
|
def int256_test(x: str) -> bool:
|
|
159
|
-
|
|
160
|
-
return value is not None and -int256_max <= value < int256_max
|
|
144
|
+
return intx_re.match(x) is not None and -int256_max <= int(x) < int256_max
|
|
161
145
|
|
|
162
146
|
|
|
163
147
|
def uint_8_test(x: str) -> bool:
|
|
164
|
-
|
|
165
|
-
return value is not None and 0 <= value < uint_8_max
|
|
148
|
+
return uintx_re.match(x) is not None and 0 <= int(x) < uint_8_max
|
|
166
149
|
|
|
167
150
|
|
|
168
151
|
def uint16_test(x: str) -> bool:
|
|
169
|
-
|
|
170
|
-
return value is not None and 0 <= value < uint16_max
|
|
152
|
+
return uintx_re.match(x) is not None and 0 <= int(x) < uint16_max
|
|
171
153
|
|
|
172
154
|
|
|
173
155
|
def uint32_test(x: str) -> bool:
|
|
174
|
-
|
|
175
|
-
return value is not None and 0 <= value < uint32_max
|
|
156
|
+
return uintx_re.match(x) is not None and 0 <= int(x) < uint32_max
|
|
176
157
|
|
|
177
158
|
|
|
178
159
|
def uint64_test(x: str) -> bool:
|
|
179
|
-
|
|
180
|
-
return value is not None and 0 <= value < uint64_max
|
|
160
|
+
return uintx_re.match(x) is not None and 0 <= int(x) < uint64_max
|
|
181
161
|
|
|
182
162
|
|
|
183
163
|
def uint128_test(x: str) -> bool:
|
|
184
|
-
|
|
185
|
-
return value is not None and 0 <= value < uint128_max
|
|
164
|
+
return intx_re.match(x) is not None and 0 <= int(x) < uint128_max
|
|
186
165
|
|
|
187
166
|
|
|
188
167
|
def uint256_test(x: str) -> bool:
|
|
189
|
-
|
|
190
|
-
return value is not None and 0 <= value < uint256_max
|
|
168
|
+
return intx_re.match(x) is not None and 0 <= int(x) < uint256_max
|
|
191
169
|
|
|
192
170
|
|
|
193
171
|
def float_test(x: str) -> bool:
|
|
@@ -572,11 +572,6 @@ class FeedbackManager:
|
|
|
572
572
|
"You can read more about the pricing at https://www.tinybird.co/docs/classic/work-with-data/process-and-copy/materialized-views#compute-compute-separation-for-populates\n\n"
|
|
573
573
|
"Do you want to proceed with on-demand compute?"
|
|
574
574
|
)
|
|
575
|
-
warning_confirm_on_demand_compute_differs_from_datafile = warning_message(
|
|
576
|
-
"The local datafile of pipe '{pipe}' does not set ON_DEMAND_COMPUTE true, but --on-demand-compute was passed.\n"
|
|
577
|
-
"On-demand compute uses dedicated resources that are billed separately from your regular usage.\n\n"
|
|
578
|
-
"Do you want to proceed?"
|
|
579
|
-
)
|
|
580
575
|
|
|
581
576
|
warning_confirm_delete_token = prompt_message("Do you want to delete Token {token}?")
|
|
582
577
|
warning_confirm_refresh_token = prompt_message("Do you want to refresh Token {token}?")
|
|
@@ -18,7 +18,7 @@ from tinybird.context import (
|
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
from .datatypes import testers
|
|
21
|
-
from .tornado_template import
|
|
21
|
+
from .tornado_template import VALID_CUSTOM_FUNCTION_NAMES, SecurityException, Template
|
|
22
22
|
|
|
23
23
|
VALID_ACTIVATE_FEATURES = frozenset(["analyzer", "parallel_replicas", "optimize_aggregation_in_order"])
|
|
24
24
|
|
|
@@ -1375,7 +1375,7 @@ _namespace = {
|
|
|
1375
1375
|
# they raise a pretty non understandable error but if someone
|
|
1376
1376
|
# is using them they know what they are trying to do
|
|
1377
1377
|
# read https://anee.me/escaping-python-jails-849c65cf306e on how to escape from python jails
|
|
1378
|
-
"
|
|
1378
|
+
"__buildins__": {},
|
|
1379
1379
|
"__import__": {},
|
|
1380
1380
|
"__debug__": {},
|
|
1381
1381
|
"__doc__": {},
|
|
@@ -1391,10 +1391,8 @@ _namespace = {
|
|
|
1391
1391
|
reserved_vars = {"_tt_tmp", "_tt_append", "isinstance", "str", "error", "custom_error", *list(vars(builtins))}
|
|
1392
1392
|
for p in DEFAULT_PARAM_NAMES: # we handle these in an specific manner
|
|
1393
1393
|
reserved_vars.discard(p) # `format` is part of builtins
|
|
1394
|
-
# Allow 'id'
|
|
1394
|
+
# Allow 'id' to be used as a template parameter - https://gitlab.com/tinybird/analytics/-/issues/19119
|
|
1395
1395
|
reserved_vars.discard("id")
|
|
1396
|
-
reserved_vars.discard("type")
|
|
1397
|
-
reserved_vars.discard("dir")
|
|
1398
1396
|
error_vars = ["error", "custom_error"]
|
|
1399
1397
|
|
|
1400
1398
|
|
|
@@ -1470,8 +1468,9 @@ def generate(self, **kwargs) -> Tuple[str, TemplateExecutionResults]:
|
|
|
1470
1468
|
return Expression(f"-- disable {feature}\n")
|
|
1471
1469
|
|
|
1472
1470
|
namespace.update(_namespace)
|
|
1473
|
-
#
|
|
1474
|
-
|
|
1471
|
+
# This is to fix the issue https://gitlab.com/tinybird/analytics/-/issues/19119
|
|
1472
|
+
# We need to do the override here because if we modify the _namespace, we would filter out parameters from the users
|
|
1473
|
+
namespace.update({"id": None})
|
|
1475
1474
|
namespace.update(kwargs)
|
|
1476
1475
|
namespace.update(
|
|
1477
1476
|
{
|
|
@@ -1479,8 +1478,6 @@ def generate(self, **kwargs) -> Tuple[str, TemplateExecutionResults]:
|
|
|
1479
1478
|
# the generated source code.
|
|
1480
1479
|
"__name__": self.name.replace(".", "_"),
|
|
1481
1480
|
"__loader__": ObjectDict(get_source=lambda name: self.code),
|
|
1482
|
-
# Set again after kwargs so request parameters can't override it
|
|
1483
|
-
"__builtins__": SAFE_BUILTINS,
|
|
1484
1481
|
"max_threads": set_max_threads,
|
|
1485
1482
|
"tb_secret": set_tb_secret,
|
|
1486
1483
|
"tb_var": set_tb_secret,
|
|
@@ -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.6.21'
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '4.6.21.dev0'
|
|
8
|
+
__revision__ = '965c47ce'
|
|
@@ -743,7 +743,6 @@ class TinyB:
|
|
|
743
743
|
target_datasource: Optional[str] = None,
|
|
744
744
|
schedule_cron: Optional[str] = None,
|
|
745
745
|
mode: Optional[str] = None,
|
|
746
|
-
on_demand_compute: Optional[bool] = None,
|
|
747
746
|
):
|
|
748
747
|
data = {"schedule_cron": schedule_cron}
|
|
749
748
|
|
|
@@ -753,9 +752,6 @@ class TinyB:
|
|
|
753
752
|
if mode:
|
|
754
753
|
data["mode"] = mode
|
|
755
754
|
|
|
756
|
-
if on_demand_compute is not None:
|
|
757
|
-
data["on_demand_compute"] = "true" if on_demand_compute else "false"
|
|
758
|
-
|
|
759
755
|
return self._req(f"/v0/pipes/{pipe_name_or_id}/nodes/{node_id}/copy", method="PUT", data=data)
|
|
760
756
|
|
|
761
757
|
def pipe_remove_copy(self, pipe_name_or_id: str, node_id: str):
|
|
@@ -10,29 +10,13 @@ from typing import Optional, Tuple
|
|
|
10
10
|
import click
|
|
11
11
|
from click import Context
|
|
12
12
|
|
|
13
|
-
from tinybird.datafile.common import
|
|
13
|
+
from tinybird.datafile.common import get_name_version
|
|
14
14
|
from tinybird.tb.client import AuthNoTokenException, TinyB
|
|
15
15
|
from tinybird.tb.modules.cli import cli
|
|
16
16
|
from tinybird.tb.modules.common import echo_safe_humanfriendly_tables_format_smart_table, wait_job
|
|
17
17
|
from tinybird.tb.modules.exceptions import CLIPipeException
|
|
18
18
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
19
19
|
from tinybird.tb.modules.job_common import echo_job_url
|
|
20
|
-
from tinybird.tb.modules.project import Project
|
|
21
|
-
from tinybird.utils.bools import parse_optional_bool
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def local_copy_node_uses_on_demand_compute(project: Project, pipe_name: str) -> Optional[bool]:
|
|
25
|
-
"""Reads ON_DEMAND_COMPUTE from the local datafile. Returns None when there is no parseable copy pipe to compare"""
|
|
26
|
-
pipe_path = project.get_resource_path(pipe_name, "pipe")
|
|
27
|
-
if not pipe_path:
|
|
28
|
-
return None
|
|
29
|
-
datafile = project.get_pipe_datafile(str(project.path / pipe_path))
|
|
30
|
-
if datafile is None:
|
|
31
|
-
return None
|
|
32
|
-
copy_node = next((node for node in datafile.nodes if node.get("type", "").lower() == PipeNodeTypes.COPY), None)
|
|
33
|
-
if copy_node is None:
|
|
34
|
-
return None
|
|
35
|
-
return parse_optional_bool(copy_node.get(CopyParameters.ON_DEMAND_COMPUTE))
|
|
36
20
|
|
|
37
21
|
|
|
38
22
|
@cli.group()
|
|
@@ -105,7 +89,6 @@ def copy_ls(ctx: Context, match: str, format_: str):
|
|
|
105
89
|
default=False,
|
|
106
90
|
help="Use on-demand compute instances for the copy job.",
|
|
107
91
|
)
|
|
108
|
-
@click.option("--yes", is_flag=True, default=False, help="Do not ask for confirmation")
|
|
109
92
|
@click.pass_context
|
|
110
93
|
def copy_run(
|
|
111
94
|
ctx: click.Context,
|
|
@@ -114,24 +97,9 @@ def copy_run(
|
|
|
114
97
|
mode: str,
|
|
115
98
|
param: Optional[Tuple[str]],
|
|
116
99
|
on_demand_compute: bool,
|
|
117
|
-
yes: bool,
|
|
118
100
|
):
|
|
119
101
|
"""Run an on-demand copy pipe"""
|
|
120
102
|
|
|
121
|
-
project: Optional[Project] = ctx.ensure_object(dict).get("project")
|
|
122
|
-
if (
|
|
123
|
-
on_demand_compute
|
|
124
|
-
and not yes
|
|
125
|
-
and project
|
|
126
|
-
and local_copy_node_uses_on_demand_compute(project, pipe_name_or_id) is False
|
|
127
|
-
and not click.confirm(
|
|
128
|
-
FeedbackManager.warning_confirm_on_demand_compute_differs_from_datafile(pipe=pipe_name_or_id),
|
|
129
|
-
default=False,
|
|
130
|
-
)
|
|
131
|
-
):
|
|
132
|
-
click.echo(FeedbackManager.info_cancelled_by_user())
|
|
133
|
-
return
|
|
134
|
-
|
|
135
103
|
params = dict(key_value.split("=") for key_value in param) if param else {}
|
|
136
104
|
click.echo(FeedbackManager.highlight(message=f"\n» Running on-demand copy '{pipe_name_or_id}'"))
|
|
137
105
|
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
@@ -881,7 +881,6 @@ def process_file(
|
|
|
881
881
|
"target_datasource": node.get("target_datasource", None),
|
|
882
882
|
"copy_schedule": node.get(CopyParameters.COPY_SCHEDULE, None),
|
|
883
883
|
"mode": node.get("mode", CopyModes.APPEND),
|
|
884
|
-
"on_demand_compute": node.get(CopyParameters.ON_DEMAND_COMPUTE, None),
|
|
885
884
|
}
|
|
886
885
|
|
|
887
886
|
is_export_node = ExportReplacements.is_export_node(node)
|
|
@@ -23,7 +23,6 @@ from tinybird.tb.modules.datafile.format_common import (
|
|
|
23
23
|
format_tags,
|
|
24
24
|
format_tokens,
|
|
25
25
|
)
|
|
26
|
-
from tinybird.utils.bools import parse_optional_bool
|
|
27
26
|
|
|
28
27
|
|
|
29
28
|
def format_node_sql(
|
|
@@ -82,9 +81,6 @@ def format_node_type(file_parts: List[str], node: Dict[str, Any]) -> List[str]:
|
|
|
82
81
|
file_parts.append(
|
|
83
82
|
f"{CopyParameters.COPY_SCHEDULE.upper()} {ON_DEMAND if is_ondemand else node[CopyParameters.COPY_SCHEDULE]}"
|
|
84
83
|
)
|
|
85
|
-
if parse_optional_bool(node.get(CopyParameters.ON_DEMAND_COMPUTE)):
|
|
86
|
-
file_parts.append(DATAFILE_NEW_LINE)
|
|
87
|
-
file_parts.append("ON_DEMAND_COMPUTE true")
|
|
88
84
|
file_parts.append(DATAFILE_NEW_LINE)
|
|
89
85
|
|
|
90
86
|
# Sink or Stream pipe
|
|
@@ -922,7 +922,6 @@ def process_file(
|
|
|
922
922
|
"target_datasource": node.get("target_datasource", None),
|
|
923
923
|
"copy_schedule": node.get(CopyParameters.COPY_SCHEDULE, None),
|
|
924
924
|
"mode": node.get("mode", CopyModes.APPEND),
|
|
925
|
-
"on_demand_compute": node.get(CopyParameters.ON_DEMAND_COMPUTE, None),
|
|
926
925
|
}
|
|
927
926
|
|
|
928
927
|
is_export_node = ExportReplacements.is_export_node(node)
|
|
@@ -335,12 +335,13 @@ def discard_deployment(host: Optional[str], headers: dict, wait: bool, request_f
|
|
|
335
335
|
click.echo(FeedbackManager.error(message="Only one deployment found. Cannot discard the only deployment."))
|
|
336
336
|
return
|
|
337
337
|
|
|
338
|
-
|
|
339
|
-
deployment_to_discard = next(deployment for deployment in deployments if deployment is not live_deployment)
|
|
338
|
+
current_deployment, deployment_to_discard = deployments[0], deployments[1]
|
|
340
339
|
|
|
341
|
-
|
|
340
|
+
# NOTE(eclbg): we never get here. We wrote this code when we though we'd enable promoting back and forth between
|
|
341
|
+
# staging and live, but the current CLI commands don't allow getting in that state
|
|
342
|
+
if current_deployment.get("status") != "data_ready":
|
|
342
343
|
click.echo(FeedbackManager.error(message="Previous deployment is not ready"))
|
|
343
|
-
deploy_errors =
|
|
344
|
+
deploy_errors = current_deployment.get("errors", [])
|
|
344
345
|
for deploy_error in deploy_errors:
|
|
345
346
|
click.echo(FeedbackManager.error(message=f"* {deploy_error}"))
|
|
346
347
|
return
|
|
@@ -358,6 +359,7 @@ def discard_deployment(host: Optional[str], headers: dict, wait: bool, request_f
|
|
|
358
359
|
click.echo(FeedbackManager.error(message=result.get("error")))
|
|
359
360
|
sys_exit("deployment_error", result.get("error", "Unknown error"))
|
|
360
361
|
|
|
362
|
+
deployment_to_discard = deployments[1]
|
|
361
363
|
click.echo(FeedbackManager.success(message="Discard process successfully started"))
|
|
362
364
|
|
|
363
365
|
if wait:
|
|
@@ -749,11 +749,6 @@ STEP 3: ADD KEY TO SERVICE ACCOUNT
|
|
|
749
749
|
)
|
|
750
750
|
warning_confirm_delete_pipe = prompt_message('Do you want to remove the pipe "{pipe}"?')
|
|
751
751
|
warning_confirm_copy_pipe = prompt_message('Do you want to run a copy job from the pipe "{pipe}"?')
|
|
752
|
-
warning_confirm_on_demand_compute_differs_from_datafile = warning_message(
|
|
753
|
-
"The local datafile of pipe '{pipe}' does not set ON_DEMAND_COMPUTE true, but --on-demand-compute was passed.\n"
|
|
754
|
-
"On-demand compute uses dedicated resources that are billed separately from your regular usage.\n\n"
|
|
755
|
-
"Do you want to proceed?"
|
|
756
|
-
)
|
|
757
752
|
warning_confirm_sink_job = prompt_message('Do you want to run a sink job from the pipe "{pipe}"?')
|
|
758
753
|
warning_confirm_clear_workspace = prompt_message(
|
|
759
754
|
"Do you want to remove all pipes and Data Sources from this workspace?"
|
|
@@ -16,15 +16,7 @@ from click import Context
|
|
|
16
16
|
from tinybird import context
|
|
17
17
|
from tinybird.client import AuthNoTokenException, DoesNotExistException, TinyB
|
|
18
18
|
from tinybird.config import DEFAULT_API_HOST, FeatureFlags
|
|
19
|
-
from tinybird.datafile_common import
|
|
20
|
-
PipeNodeTypes,
|
|
21
|
-
PipeTypes,
|
|
22
|
-
folder_push,
|
|
23
|
-
get_name_version,
|
|
24
|
-
local_copy_node_uses_on_demand_compute,
|
|
25
|
-
process_file,
|
|
26
|
-
wait_job,
|
|
27
|
-
)
|
|
19
|
+
from tinybird.datafile_common import PipeNodeTypes, PipeTypes, folder_push, get_name_version, process_file, wait_job
|
|
28
20
|
from tinybird.feedback_manager import FeedbackManager
|
|
29
21
|
from tinybird.tb_cli_modules.branch import warn_if_in_live
|
|
30
22
|
from tinybird.tb_cli_modules.cli import cli
|
|
@@ -757,41 +749,30 @@ async def pipe_copy_run(
|
|
|
757
749
|
|
|
758
750
|
params = dict(key_value.split("=") for key_value in param) if param else {}
|
|
759
751
|
|
|
760
|
-
if
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
if (
|
|
764
|
-
on_demand_compute
|
|
765
|
-
and not yes
|
|
766
|
-
and local_copy_node_uses_on_demand_compute(".", pipe_name_or_id) is False
|
|
767
|
-
and not click.confirm(
|
|
768
|
-
FeedbackManager.warning_confirm_on_demand_compute_differs_from_datafile(pipe=pipe_name_or_id),
|
|
769
|
-
default=False,
|
|
770
|
-
)
|
|
771
|
-
):
|
|
772
|
-
return
|
|
773
|
-
|
|
774
|
-
click.echo(FeedbackManager.info_copy_job_running(pipe=pipe_name_or_id))
|
|
775
|
-
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
752
|
+
if yes or click.confirm(FeedbackManager.warning_confirm_copy_pipe(pipe=pipe_name_or_id)):
|
|
753
|
+
click.echo(FeedbackManager.info_copy_job_running(pipe=pipe_name_or_id))
|
|
754
|
+
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
776
755
|
|
|
777
|
-
|
|
778
|
-
|
|
756
|
+
try:
|
|
757
|
+
response = await client.pipe_run_copy(pipe_name_or_id, params, mode, on_demand_compute=on_demand_compute)
|
|
779
758
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
759
|
+
job_id = response["job"]["job_id"]
|
|
760
|
+
job_url = response["job"]["job_url"]
|
|
761
|
+
target_datasource_id = response["tags"]["copy_target_datasource"]
|
|
762
|
+
target_datasource = await client.get_datasource(target_datasource_id)
|
|
763
|
+
target_datasource_name = target_datasource["name"]
|
|
764
|
+
click.echo(
|
|
765
|
+
FeedbackManager.success_copy_job_created(target_datasource=target_datasource_name, job_url=job_url)
|
|
766
|
+
)
|
|
786
767
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
768
|
+
if wait:
|
|
769
|
+
await wait_job(client, job_id, job_url, "** Copying data")
|
|
770
|
+
click.echo(FeedbackManager.success_data_copied_to_ds(target_datasource=target_datasource_name))
|
|
790
771
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
772
|
+
except AuthNoTokenException:
|
|
773
|
+
raise
|
|
774
|
+
except Exception as e:
|
|
775
|
+
raise CLIPipeException(FeedbackManager.error_creating_copy_job(error=e))
|
|
795
776
|
|
|
796
777
|
|
|
797
778
|
@pipe_copy.command(name="resume", short_help="Resume a paused copy pipe")
|