tinybird 4.6.22__tar.gz → 4.6.23.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.22 → tinybird-4.6.23.dev0}/PKG-INFO +1 -6
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/pyproject.toml +25 -28
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/client.py +8 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/sql_template.py +24 -55
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/sql_template_fmt.py +2 -2
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/syncasync.py +43 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/__cli__.py +2 -2
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/client.py +8 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/common.py +3 -3
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/create.py +4 -2
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/pull.py +3 -73
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datasource.py +1 -1
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/exceptions.py +21 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/common.py +3 -3
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/datasource.py +1 -1
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tornado_template.py +93 -38
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird.egg-info/PKG-INFO +1 -6
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/setup.cfg +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/__cli__.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/ch_utils/engine.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/check_pypi.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/config.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/context.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/datafile/common.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/datafile/exceptions.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/datafile/parse_connection.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/datafile/parse_datasource.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/datafile/parse_pipe.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/datatypes.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/feedback_manager.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/git_settings.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/iterating/__init__.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/iterating/data_branch_modes.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/prompts.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/service_datasources.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/sql.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/sql_toolset.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/check_pypi.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/cli.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/config.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/branch.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/build.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/build_common.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/cicd.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/cli.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/config.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/connection.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/connection_dynamodb.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/connection_kafka.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/connection_s3.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/copy.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/build.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/build_common.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/diff.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/fixture.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/format_common.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/format_connection.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/datafile/playground.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/deployment.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/deployment_common.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/deprecations.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/endpoint.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/feedback_manager.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/fmt.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/info.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/infra.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/job.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/job_common.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/llm.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/llm_utils.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/local.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/local_common.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/local_logs.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/login.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/login_common.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/logout.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/logs.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/materialization.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/open.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/pipe.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/preview.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/project.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/project_commands.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/py_project.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/query_output.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/regions.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/secret.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/secret_common.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/sink.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/table.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/telemetry.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/test.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/test_common.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/token.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/ts_project.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/watch.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/workspace.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb/modules/workspace_members.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/pipe.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/utils/__init__.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird/utils/bools.py +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird.egg-info/SOURCES.txt +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird.egg-info/dependency_links.txt +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird.egg-info/entry_points.txt +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.dev0}/tinybird.egg-info/requires.txt +0 -0
- {tinybird-4.6.22 → tinybird-4.6.23.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.
|
|
3
|
+
Version: 4.6.23.dev0
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/forward/commands
|
|
6
6
|
Author: Tinybird
|
|
@@ -52,11 +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.22
|
|
56
|
-
********
|
|
57
|
-
|
|
58
|
-
- `Added` ``tb pull`` demotes sink and copy pipes that exceed the workspace's sink/copy pipe plan limit to plain pipes instead of failing, stripping their ``TYPE``/``EXPORT_*``/``TARGET_DATASOURCE``/``COPY_SCHEDULE`` settings and warning that the plan must be upgraded to restore them.
|
|
59
|
-
|
|
60
55
|
4.6.21
|
|
61
56
|
********
|
|
62
57
|
|
|
@@ -18,35 +18,35 @@ authors = [
|
|
|
18
18
|
dependencies = [
|
|
19
19
|
"GitPython==3.1.44",
|
|
20
20
|
"Markdown==3.5.1",
|
|
21
|
-
"aioboto3
|
|
21
|
+
"aioboto3==14.0.0",
|
|
22
22
|
"aiofiles==24.1.0",
|
|
23
|
-
"aiohttp
|
|
24
|
-
"anthropic
|
|
23
|
+
"aiohttp==3.11.2",
|
|
24
|
+
"anthropic==0.55.0",
|
|
25
25
|
"async-lru==2.3.0",
|
|
26
26
|
"aws-msk-iam-sasl-signer-python==1.0.2",
|
|
27
27
|
"cachetools==5.5.0",
|
|
28
28
|
"cffi==1.17.1",
|
|
29
29
|
"chardet==4.0.0",
|
|
30
30
|
"ciso8601==2.2.0",
|
|
31
|
-
"click
|
|
31
|
+
"click==8.1.8",
|
|
32
32
|
"clickhouse-cityhash==1.0.2.5",
|
|
33
33
|
"clickhouse-driver==0.2.9",
|
|
34
34
|
"confluent-kafka[avro,json,schemaregistry]==2.12.2",
|
|
35
35
|
"contextvars==2.4",
|
|
36
36
|
"cramjam==2.11.0",
|
|
37
37
|
"croniter==6.2.2",
|
|
38
|
-
"cryptography
|
|
38
|
+
"cryptography==3.4.8",
|
|
39
39
|
"datasketch==1.6.5",
|
|
40
40
|
"dnspython==2.8.0",
|
|
41
41
|
"docker==7.1.0",
|
|
42
42
|
"fastavro==1.12.2",
|
|
43
43
|
"fastmcp==2.12.2",
|
|
44
|
-
"google-cloud-aiplatform
|
|
44
|
+
"google-cloud-aiplatform==1.148.1",
|
|
45
45
|
"google-cloud-compute==1.48.0",
|
|
46
46
|
"google-cloud-scheduler==2.20.0",
|
|
47
47
|
"google-cloud-secret-manager==2.29.0",
|
|
48
|
-
"google-cloud-storage
|
|
49
|
-
"google_api_core
|
|
48
|
+
"google-cloud-storage==3.4.1",
|
|
49
|
+
"google_api_core==2.25.2",
|
|
50
50
|
"googleapis_common_protos==1.66.0",
|
|
51
51
|
"grpcio_status==1.67.1",
|
|
52
52
|
"humanfriendly==10.0",
|
|
@@ -69,7 +69,7 @@ dependencies = [
|
|
|
69
69
|
"opentelemetry-sdk==1.38.0",
|
|
70
70
|
"orb-billing==2.17.0",
|
|
71
71
|
"orjson==3.11.5",
|
|
72
|
-
"packaging
|
|
72
|
+
"packaging==23.2",
|
|
73
73
|
"passlib==1.7.1",
|
|
74
74
|
"posthog==7.28.0",
|
|
75
75
|
"pre-commit==4.6.2",
|
|
@@ -83,10 +83,10 @@ dependencies = [
|
|
|
83
83
|
"py-spy==0.4.2",
|
|
84
84
|
"pyarrow==23.0.1",
|
|
85
85
|
"pycurl==7.45.7",
|
|
86
|
-
"pydantic-ai-slim[anthropic]
|
|
87
|
-
"pydantic-ai-slim[google]
|
|
88
|
-
"pydantic-ai-slim[retries]
|
|
89
|
-
"pydantic
|
|
86
|
+
"pydantic-ai-slim[anthropic]==0.5.0",
|
|
87
|
+
"pydantic-ai-slim[google]==0.5.0",
|
|
88
|
+
"pydantic-ai-slim[retries]==0.5.0",
|
|
89
|
+
"pydantic==2.12.5",
|
|
90
90
|
"pyjwt[crypto]==2.9.0",
|
|
91
91
|
"pympler==1.1",
|
|
92
92
|
"pynacl==1.5.0",
|
|
@@ -94,10 +94,10 @@ dependencies = [
|
|
|
94
94
|
"python-dateutil==2.9.0.post0",
|
|
95
95
|
"python-dotenv==1.1.0",
|
|
96
96
|
"python-ulid==2.7.0",
|
|
97
|
-
"pyyaml
|
|
97
|
+
"pyyaml==6.0.1",
|
|
98
98
|
"redis[hiredis]==5.3.1",
|
|
99
99
|
"requests==2.32.4",
|
|
100
|
-
"sentry-sdk==2.69.
|
|
100
|
+
"sentry-sdk==2.69.1",
|
|
101
101
|
"setproctitle==1.3.3",
|
|
102
102
|
"shandy-sqlfmt==0.11.1",
|
|
103
103
|
"shandy-sqlfmt[jinjafmt]==0.11.1",
|
|
@@ -108,7 +108,7 @@ dependencies = [
|
|
|
108
108
|
"tabulate==0.8.10",
|
|
109
109
|
"thefuzz==0.22.1",
|
|
110
110
|
"tinybird-python-sdk[ai]==0.3.7",
|
|
111
|
-
"tinybird-toolset==2.6.
|
|
111
|
+
"tinybird-toolset==2.6.2",
|
|
112
112
|
"toposort==1.10",
|
|
113
113
|
"tornado==6.5.5",
|
|
114
114
|
"urllib3==1.26.20",
|
|
@@ -125,9 +125,9 @@ deploy = [
|
|
|
125
125
|
"GitPython==3.1.44",
|
|
126
126
|
"ansible==8.5.0",
|
|
127
127
|
"ara==1.6.1",
|
|
128
|
-
"boto3
|
|
128
|
+
"boto3==1.36.21",
|
|
129
129
|
"fabric==3.2.2",
|
|
130
|
-
"google-auth
|
|
130
|
+
"google-auth==2.47.0",
|
|
131
131
|
"jsonnet",
|
|
132
132
|
"prettytable==3.8.0",
|
|
133
133
|
"requests==2.32.4",
|
|
@@ -142,7 +142,7 @@ devtools = [
|
|
|
142
142
|
]
|
|
143
143
|
doc = [
|
|
144
144
|
"Pallets-Sphinx-Themes==2.3.0",
|
|
145
|
-
"pyOpenSSL
|
|
145
|
+
"pyOpenSSL<24.0.0",
|
|
146
146
|
"sphinx-autobuild==2024.2.4",
|
|
147
147
|
"sphinx-sitemap",
|
|
148
148
|
"sphinx==7.3.7",
|
|
@@ -150,15 +150,15 @@ doc = [
|
|
|
150
150
|
"sphinxcontrib-jquery==4.1",
|
|
151
151
|
]
|
|
152
152
|
lint = [
|
|
153
|
-
"botocore-stubs
|
|
153
|
+
"botocore-stubs==1.36.23",
|
|
154
154
|
"flake8~=7.3",
|
|
155
155
|
"flake8-async~=26.8",
|
|
156
156
|
"mypy==2.3.1",
|
|
157
|
-
"ruff==0.16.
|
|
157
|
+
"ruff==0.16.8",
|
|
158
158
|
"types-Markdown",
|
|
159
159
|
"types-PyYAML",
|
|
160
160
|
"types-aiofiles==24.1.0.20241221",
|
|
161
|
-
"types-boto3-lite
|
|
161
|
+
"types-boto3-lite==1.36.21",
|
|
162
162
|
"types-cachetools",
|
|
163
163
|
"types-chardet",
|
|
164
164
|
"types-paramiko",
|
|
@@ -172,19 +172,18 @@ lint = [
|
|
|
172
172
|
test = [
|
|
173
173
|
"coverage==7.10.6",
|
|
174
174
|
"freezegun==1.5.5",
|
|
175
|
-
"google-auth
|
|
175
|
+
"google-auth==2.47.0",
|
|
176
176
|
"gsutil==4.58",
|
|
177
|
-
"httpx2~=2.13",
|
|
178
177
|
"hypothesis==6.156.1",
|
|
179
178
|
"oauth2client==3.0.0",
|
|
180
179
|
"py==1.11.0",
|
|
181
|
-
"pytest-asyncio
|
|
180
|
+
"pytest-asyncio==0.23.8",
|
|
182
181
|
"pytest-cov==4.1.0",
|
|
183
182
|
"pytest-env==1.1.3",
|
|
184
183
|
"pytest-flakefinder==1.1.0",
|
|
185
184
|
"pytest-timeout==2.3.1",
|
|
186
185
|
"pytest-xdist==3.6.1",
|
|
187
|
-
"pytest
|
|
186
|
+
"pytest==8.1.2",
|
|
188
187
|
"rangehttpserver==1.4.0",
|
|
189
188
|
"yappi==1.7.6",
|
|
190
189
|
]
|
|
@@ -206,8 +205,6 @@ colibri = "tinybird.colibri.cli:cli"
|
|
|
206
205
|
members = [
|
|
207
206
|
"chbackups",
|
|
208
207
|
"data_connector",
|
|
209
|
-
"gatherer",
|
|
210
|
-
"tinybird_orchestrator",
|
|
211
208
|
]
|
|
212
209
|
|
|
213
210
|
[tool.setuptools]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ast
|
|
2
|
+
import builtins
|
|
2
3
|
import linecache
|
|
3
4
|
import logging
|
|
4
5
|
import re
|
|
@@ -1335,10 +1336,8 @@ sqlescape_for_string_expression = sqlescape_generator(
|
|
|
1335
1336
|
)
|
|
1336
1337
|
|
|
1337
1338
|
|
|
1338
|
-
def escape_single_quote_str(s
|
|
1339
|
-
|
|
1340
|
-
# otherwise a trailing backslash escapes the closing quote and the following input becomes SQL
|
|
1341
|
-
return "'" + s.replace("\\", "\\\\").replace("'", "''") + "'"
|
|
1339
|
+
def escape_single_quote_str(s):
|
|
1340
|
+
return "'" + s.replace("'", "''") + "'"
|
|
1342
1341
|
|
|
1343
1342
|
|
|
1344
1343
|
def expression_wrapper(x, name, escape_arrays: bool = False):
|
|
@@ -1389,14 +1388,13 @@ _namespace = {
|
|
|
1389
1388
|
}
|
|
1390
1389
|
|
|
1391
1390
|
|
|
1392
|
-
|
|
1393
|
-
# `property`, `object`, ...) can only be template parameters, so they must be discovered as such to get a
|
|
1394
|
-
# value (None or a test-mode placeholder) instead of raising NameError.
|
|
1395
|
-
reserved_vars = {"_tt_tmp", "_tt_append", "isinstance", "str", "error", "custom_error", *SAFE_BUILTINS}
|
|
1391
|
+
reserved_vars = {"_tt_tmp", "_tt_append", "isinstance", "str", "error", "custom_error", *list(vars(builtins))}
|
|
1396
1392
|
for p in DEFAULT_PARAM_NAMES: # we handle these in an specific manner
|
|
1397
1393
|
reserved_vars.discard(p) # `format` is part of builtins
|
|
1398
|
-
# Allow 'id' as
|
|
1394
|
+
# Allow 'id', 'type' and 'dir' as template parameter names despite being builtins.
|
|
1399
1395
|
reserved_vars.discard("id")
|
|
1396
|
+
reserved_vars.discard("type")
|
|
1397
|
+
reserved_vars.discard("dir")
|
|
1400
1398
|
error_vars = ["error", "custom_error"]
|
|
1401
1399
|
|
|
1402
1400
|
|
|
@@ -1472,8 +1470,8 @@ def generate(self, **kwargs) -> Tuple[str, TemplateExecutionResults]:
|
|
|
1472
1470
|
return Expression(f"-- disable {feature}\n")
|
|
1473
1471
|
|
|
1474
1472
|
namespace.update(_namespace)
|
|
1475
|
-
# Default
|
|
1476
|
-
namespace.update({"id": None})
|
|
1473
|
+
# Default these here, not in _namespace, so they stay visible to variable extraction.
|
|
1474
|
+
namespace.update({"id": None, "type": None, "dir": None})
|
|
1477
1475
|
namespace.update(kwargs)
|
|
1478
1476
|
namespace.update(
|
|
1479
1477
|
{
|
|
@@ -1822,7 +1820,7 @@ def get_var_names(t: Template):
|
|
|
1822
1820
|
>>> [v['name'] for v in get_var_names(Template("{% for name in secret_names %}{{tb_secret(name)}}{% end %}"))]
|
|
1823
1821
|
['secret_names', 'name', 'tb_secret', 'name']
|
|
1824
1822
|
|
|
1825
|
-
Type casting with date function in elif chain:
|
|
1823
|
+
Type casting with date function in elif chain (type is in reserved_vars):
|
|
1826
1824
|
>>> t = Template("{% if kind == 'int' %}{{Int32(val, 0)}}{% elif kind == 'date' %}{{DateTime(val)}}{% elif kind == 'diff' %}{{date_diff_in_days(val, now)}}{% end %}")
|
|
1827
1825
|
>>> [v['name'] for v in get_var_names(t)]
|
|
1828
1826
|
['kind', 'Int32', 'val', 'kind', 'DateTime', 'val', 'kind', 'date_diff_in_days', 'val', 'now']
|
|
@@ -2374,24 +2372,7 @@ def wrap_vars(t, escape_arrays: bool = False):
|
|
|
2374
2372
|
return var
|
|
2375
2373
|
|
|
2376
2374
|
|
|
2377
|
-
def
|
|
2378
|
-
"""Value of a constant table() argument: a literal or a concatenation of string literals."""
|
|
2379
|
-
if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)):
|
|
2380
|
-
return str(node.value)
|
|
2381
|
-
return _string_literal(node)
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
def _string_literal(node: ast.expr) -> Optional[str]:
|
|
2385
|
-
if isinstance(node, ast.Constant) and isinstance(node.value, str):
|
|
2386
|
-
return node.value
|
|
2387
|
-
if isinstance(node, ast.BinOp) and isinstance(node.op, ast.Add):
|
|
2388
|
-
left, right = _string_literal(node.left), _string_literal(node.right)
|
|
2389
|
-
if left is not None and right is not None:
|
|
2390
|
-
return left + right
|
|
2391
|
-
return None
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
def get_used_tables_in_template(sql: str) -> List[str]:
|
|
2375
|
+
def get_used_tables_in_template(sql):
|
|
2395
2376
|
"""
|
|
2396
2377
|
>>> get_used_tables_in_template("select * from {{table('test')}}")
|
|
2397
2378
|
['test']
|
|
@@ -2405,42 +2386,30 @@ def get_used_tables_in_template(sql: str) -> List[str]:
|
|
|
2405
2386
|
[]
|
|
2406
2387
|
>>> get_used_tables_in_template("select * from {{table('my.test')}}, {{table('another.one')}}")
|
|
2407
2388
|
['my.test', 'another.one']
|
|
2408
|
-
|
|
2409
|
-
Only constant table names can be known without rendering, so anything else is skipped
|
|
2410
|
-
>>> get_used_tables_in_template("select * from {{table(tbl)}}, {{TABLE('b')}}, {{table('my.' + 'c')}}")
|
|
2411
|
-
['b', 'my.c']
|
|
2412
2389
|
"""
|
|
2413
|
-
return list(_get_used_tables_in_template_cached(sql))
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
# Building the Template dominates the cost and the result only depends on the SQL, which deployments and
|
|
2417
|
-
# /v0/sql pipelines scan repeatedly
|
|
2418
|
-
@lru_cache(maxsize=2**10)
|
|
2419
|
-
def _get_used_tables_in_template_cached(sql: str) -> Tuple[str, ...]:
|
|
2420
2390
|
try:
|
|
2421
2391
|
t = Template(sql)
|
|
2422
2392
|
|
|
2423
2393
|
def _n(chunks, tables):
|
|
2424
2394
|
for x in chunks:
|
|
2425
2395
|
if type(x).__name__ == "_Expression":
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
tables.append(name)
|
|
2396
|
+
c = compile(x.expression, "<string>", "exec", dont_inherit=True)
|
|
2397
|
+
v = [x.lower() for x in c.co_names if x not in _namespace and x not in reserved_vars]
|
|
2398
|
+
if "table" in v:
|
|
2399
|
+
|
|
2400
|
+
def _t(*args, **kwargs):
|
|
2401
|
+
return str(args[0])
|
|
2402
|
+
|
|
2403
|
+
n = {"table": _t, "TABLE": _t}
|
|
2404
|
+
e = "_tt_tmp = %s" % x.expression
|
|
2405
|
+
exec_in(e, n)
|
|
2406
|
+
tables += [n["_tt_tmp"]]
|
|
2438
2407
|
elif type(x).__name__ == "_ControlBlock":
|
|
2439
2408
|
_n(x.body.chunks, tables)
|
|
2440
2409
|
|
|
2441
|
-
tables
|
|
2410
|
+
tables = []
|
|
2442
2411
|
_n(t.file.body.chunks, tables)
|
|
2443
|
-
return
|
|
2412
|
+
return tables
|
|
2444
2413
|
except SecurityException as e:
|
|
2445
2414
|
raise SQLTemplateException(e)
|
|
2446
2415
|
|
|
@@ -214,8 +214,8 @@ class TinybirdDialect(ClickHouse):
|
|
|
214
214
|
],
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
for section
|
|
218
|
-
for rule in
|
|
217
|
+
for section in override_rules:
|
|
218
|
+
for rule in override_rules[section]:
|
|
219
219
|
for rr in self.RULES[section]:
|
|
220
220
|
if rr.name == rule.name:
|
|
221
221
|
self.RULES[section].remove(rr)
|
|
@@ -260,6 +260,49 @@ def _iscoroutinefunction_or_partial(func: Any) -> bool:
|
|
|
260
260
|
return asyncio.iscoroutinefunction(func)
|
|
261
261
|
|
|
262
262
|
|
|
263
|
+
class ThreadSensitiveContext:
|
|
264
|
+
"""Async context manager to manage context for thread sensitive mode
|
|
265
|
+
This context manager controls which thread pool executor is used when in
|
|
266
|
+
thread sensitive mode. By default, a single thread pool executor is shared
|
|
267
|
+
within a process.
|
|
268
|
+
In Python 3.7+, the ThreadSensitiveContext() context manager may be used to
|
|
269
|
+
specify a thread pool per context.
|
|
270
|
+
In Python 3.6, usage of this context manager has no effect.
|
|
271
|
+
This context manager is re-entrant, so only the outer-most call to
|
|
272
|
+
ThreadSensitiveContext will set the context.
|
|
273
|
+
"""
|
|
274
|
+
|
|
275
|
+
def __init__(self):
|
|
276
|
+
self.token = None
|
|
277
|
+
|
|
278
|
+
if contextvars:
|
|
279
|
+
|
|
280
|
+
async def __aenter__(self):
|
|
281
|
+
try:
|
|
282
|
+
SyncToAsync.thread_sensitive_context.get()
|
|
283
|
+
except LookupError:
|
|
284
|
+
self.token = SyncToAsync.thread_sensitive_context.set(self)
|
|
285
|
+
|
|
286
|
+
return self
|
|
287
|
+
|
|
288
|
+
async def __aexit__(self, exc, value, tb):
|
|
289
|
+
if not self.token:
|
|
290
|
+
return
|
|
291
|
+
|
|
292
|
+
executor = SyncToAsync.context_to_thread_executor.pop(self, None)
|
|
293
|
+
if executor:
|
|
294
|
+
executor.shutdown()
|
|
295
|
+
SyncToAsync.thread_sensitive_context.reset(self.token)
|
|
296
|
+
|
|
297
|
+
else:
|
|
298
|
+
|
|
299
|
+
async def __aenter__(self):
|
|
300
|
+
return self
|
|
301
|
+
|
|
302
|
+
async def __aexit__(self, exc, value, tb):
|
|
303
|
+
pass
|
|
304
|
+
|
|
305
|
+
|
|
263
306
|
class AsyncToSync:
|
|
264
307
|
"""
|
|
265
308
|
Utility class which turns an awaitable that only works on the thread with
|
|
@@ -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.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '4.6.23.dev0'
|
|
8
|
+
__revision__ = '2456d09e'
|
|
@@ -1277,11 +1277,11 @@ class ConnectionReplacements:
|
|
|
1277
1277
|
"""Maps prompt parameters to API parameters."""
|
|
1278
1278
|
|
|
1279
1279
|
api_params = {}
|
|
1280
|
-
for key
|
|
1280
|
+
for key in params.keys():
|
|
1281
1281
|
try:
|
|
1282
|
-
api_params[ConnectionReplacements._PARAMS_REPLACEMENTS[service][key]] =
|
|
1282
|
+
api_params[ConnectionReplacements._PARAMS_REPLACEMENTS[service][key]] = params[key]
|
|
1283
1283
|
except KeyError:
|
|
1284
|
-
api_params[key] =
|
|
1284
|
+
api_params[key] = params[key]
|
|
1285
1285
|
|
|
1286
1286
|
api_params["service"] = service
|
|
1287
1287
|
return api_params
|
|
@@ -215,12 +215,14 @@ def create_project_structure(folder: str):
|
|
|
215
215
|
"connections →": "Connect to and ingest data from popular sources: Kafka, S3 or GCS.",
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
for x
|
|
218
|
+
for x in PROJECT_PATHS_DESCRIPTIONS.keys():
|
|
219
219
|
try:
|
|
220
220
|
path = x.split("→")[0].strip()
|
|
221
221
|
f = folder_path / path
|
|
222
222
|
f.mkdir()
|
|
223
|
-
click.echo(
|
|
223
|
+
click.echo(
|
|
224
|
+
FeedbackManager.info(message=f"./{x} ") + FeedbackManager.gray(message=PROJECT_PATHS_DESCRIPTIONS[x])
|
|
225
|
+
)
|
|
224
226
|
except FileExistsError:
|
|
225
227
|
pass
|
|
226
228
|
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
1
|
from pathlib import Path
|
|
3
2
|
from typing import Any, Optional
|
|
4
3
|
|
|
5
4
|
import click
|
|
6
5
|
|
|
7
|
-
from tinybird.datafile.common import PipeNodeTypes
|
|
8
|
-
from tinybird.datafile.parse_pipe import parse_pipe
|
|
9
6
|
from tinybird.tb.client import AuthNoTokenException, TinyB
|
|
10
7
|
from tinybird.tb.modules.datafile.format_datasource import format_datasource
|
|
11
8
|
from tinybird.tb.modules.datafile.format_pipe import format_pipe
|
|
@@ -13,52 +10,6 @@ from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
|
13
10
|
|
|
14
11
|
PULL_EXISTING_FILE_MAX_DEPTH = 5
|
|
15
12
|
|
|
16
|
-
DEMOTABLE_NODE_TYPES = {
|
|
17
|
-
PipeNodeTypes.DATA_SINK: ("sink_pipes", "Sink"),
|
|
18
|
-
PipeNodeTypes.COPY: ("copy_pipes", "Copy"),
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def _parse_created_at(value: Any) -> datetime:
|
|
23
|
-
try:
|
|
24
|
-
return datetime.fromisoformat(str(value))
|
|
25
|
-
except ValueError:
|
|
26
|
-
return datetime.min
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def pipes_over_node_type_limit(pipes: list[dict[str, Any]], node_type: str, limit: Optional[int]) -> set[str]:
|
|
30
|
-
if limit is None:
|
|
31
|
-
return set()
|
|
32
|
-
|
|
33
|
-
matching_pipes = [p for p in pipes if p.get("type") == node_type]
|
|
34
|
-
if len(matching_pipes) <= limit:
|
|
35
|
-
return set()
|
|
36
|
-
|
|
37
|
-
matching_pipes.sort(key=lambda p: _parse_created_at(p.get("created_at")))
|
|
38
|
-
return {p["name"] for p in matching_pipes[limit:]}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def pipes_over_plan_limits(pipes: list[dict[str, Any]], limits: dict[str, Any]) -> dict[str, str]:
|
|
42
|
-
demoted: dict[str, str] = {}
|
|
43
|
-
for node_type, (limits_key, _label) in DEMOTABLE_NODE_TYPES.items():
|
|
44
|
-
limit = limits.get(limits_key, {}).get("max")
|
|
45
|
-
for name in pipes_over_node_type_limit(pipes, node_type, limit):
|
|
46
|
-
demoted[name] = node_type
|
|
47
|
-
return demoted
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def demote_pipe_content(name: str, content: str, node_type: str) -> str:
|
|
51
|
-
datafile = parse_pipe(name, content=content, replace_includes=False).datafile
|
|
52
|
-
demoted = False
|
|
53
|
-
for node in datafile.nodes:
|
|
54
|
-
if (node.get("type") or "").lower() == node_type:
|
|
55
|
-
node.pop("type", None)
|
|
56
|
-
demoted = True
|
|
57
|
-
|
|
58
|
-
if not demoted:
|
|
59
|
-
return content
|
|
60
|
-
return format_pipe(name, datafile=datafile)
|
|
61
|
-
|
|
62
13
|
|
|
63
14
|
def folder_pull(
|
|
64
15
|
client: TinyB,
|
|
@@ -110,7 +61,6 @@ def folder_pull(
|
|
|
110
61
|
get_resource_function: str,
|
|
111
62
|
progress_bar: bool = False,
|
|
112
63
|
fmt: bool = False,
|
|
113
|
-
demoted_pipe_types: Optional[dict[str, str]] = None,
|
|
114
64
|
) -> list[Path]:
|
|
115
65
|
def write_resource(k: dict[str, Any]) -> Optional[Path]:
|
|
116
66
|
name = f"{k['name']}.{extension}"
|
|
@@ -123,19 +73,8 @@ def folder_pull(
|
|
|
123
73
|
else:
|
|
124
74
|
resource = getattr(client, get_resource_function)(k["name"])
|
|
125
75
|
resource_to_write = resource
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
demoted_node_type = demoted_pipe_types.get(k["name"]) if demoted_pipe_types else None
|
|
129
|
-
if demoted_node_type:
|
|
130
|
-
resource_to_write = demote_pipe_content(name, resource, demoted_node_type)
|
|
131
|
-
resource_type = None
|
|
132
|
-
label = DEMOTABLE_NODE_TYPES[demoted_node_type][1]
|
|
133
|
-
warnings.append(
|
|
134
|
-
f"{label} pipe '{k['name']}' exceeds the {demoted_node_type} pipe limit of your current "
|
|
135
|
-
f"plan and was pulled as a plain pipe without its {demoted_node_type} configuration. "
|
|
136
|
-
"Upgrade your plan and reconfigure it to restore it."
|
|
137
|
-
)
|
|
138
|
-
elif fmt:
|
|
76
|
+
|
|
77
|
+
if fmt:
|
|
139
78
|
if extension == "datasource":
|
|
140
79
|
resource_to_write = format_datasource(name, content=resource)
|
|
141
80
|
elif extension == "pipe":
|
|
@@ -146,7 +85,7 @@ def folder_pull(
|
|
|
146
85
|
dest_folder = Path(folder) / "vendor" / k["name"].split(".", 1)[0]
|
|
147
86
|
name = f"{k['name'].split('.', 1)[1]}.{extension}"
|
|
148
87
|
|
|
149
|
-
file_folder = get_file_folder(extension,
|
|
88
|
+
file_folder = get_file_folder(extension, k.get("type"))
|
|
150
89
|
f = Path(dest_folder) / file_folder if file_folder is not None else Path(dest_folder)
|
|
151
90
|
|
|
152
91
|
existing_file = find_existing_resource_file(Path(dest_folder), name)
|
|
@@ -189,14 +128,6 @@ def folder_pull(
|
|
|
189
128
|
pipes = client.pipes()
|
|
190
129
|
connections = client.connections()
|
|
191
130
|
|
|
192
|
-
demoted_pipe_types: dict[str, str] = {}
|
|
193
|
-
if not only_vendored:
|
|
194
|
-
try:
|
|
195
|
-
limits = client.workspace_info().get("limits", {})
|
|
196
|
-
except Exception:
|
|
197
|
-
limits = {}
|
|
198
|
-
demoted_pipe_types = pipes_over_plan_limits(pipes, limits)
|
|
199
|
-
|
|
200
131
|
if only_vendored:
|
|
201
132
|
written_files = write_files(
|
|
202
133
|
resources=[ds for ds in datasources if "shared_from" in ds],
|
|
@@ -223,7 +154,6 @@ def folder_pull(
|
|
|
223
154
|
get_resource_function="pipe_file",
|
|
224
155
|
progress_bar=progress_bar,
|
|
225
156
|
fmt=fmt,
|
|
226
|
-
demoted_pipe_types=demoted_pipe_types,
|
|
227
157
|
)
|
|
228
158
|
)
|
|
229
159
|
written_files.extend(
|
|
@@ -677,7 +677,7 @@ def datasource_start(ctx: Context, datasource_name: str) -> None:
|
|
|
677
677
|
|
|
678
678
|
@datasource.command(name="delete")
|
|
679
679
|
@click.argument("datasource_name")
|
|
680
|
-
@click.option("--sql-condition", help="SQL WHERE condition to remove rows", hidden=True, required=True)
|
|
680
|
+
@click.option("--sql-condition", default=None, help="SQL WHERE condition to remove rows", hidden=True, required=True)
|
|
681
681
|
@click.option("--yes", is_flag=True, default=False, help="Do not ask for confirmation")
|
|
682
682
|
@click.option(
|
|
683
683
|
"--wait/--no-wait",
|
|
@@ -92,6 +92,20 @@ class CLITokenException(CLIException):
|
|
|
92
92
|
super().__init__(message, "token_error", **kw_telemetry_event_data)
|
|
93
93
|
|
|
94
94
|
|
|
95
|
+
class CLIBuildException(CLIException):
|
|
96
|
+
"""Exceptions generated by the build commands"""
|
|
97
|
+
|
|
98
|
+
def __init__(self, message: str, **kw_telemetry_event_data: Any) -> None:
|
|
99
|
+
super().__init__(message, "build_error", **kw_telemetry_event_data)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class CLIDeploymentException(CLIException):
|
|
103
|
+
"""Exceptions generated by the deployment commands"""
|
|
104
|
+
|
|
105
|
+
def __init__(self, message: str, **kw_telemetry_event_data: Any) -> None:
|
|
106
|
+
super().__init__(message, "deployment_error", **kw_telemetry_event_data)
|
|
107
|
+
|
|
108
|
+
|
|
95
109
|
class CLITestException(CLIException):
|
|
96
110
|
"""Exceptions generated by the test commands"""
|
|
97
111
|
|
|
@@ -113,6 +127,13 @@ class CLIMockException(CLIException):
|
|
|
113
127
|
super().__init__(message, "mock_error", **kw_telemetry_event_data)
|
|
114
128
|
|
|
115
129
|
|
|
130
|
+
class CLIAgentException(CLIException):
|
|
131
|
+
"""Exceptions generated by the agent commands"""
|
|
132
|
+
|
|
133
|
+
def __init__(self, message: str, **kw_telemetry_event_data: Any) -> None:
|
|
134
|
+
super().__init__(message, "agent_error", **kw_telemetry_event_data)
|
|
135
|
+
|
|
136
|
+
|
|
116
137
|
class CLILoginException(CLIException):
|
|
117
138
|
"""Exceptions generated by the login commands"""
|
|
118
139
|
|
|
@@ -1304,11 +1304,11 @@ class ConnectionReplacements:
|
|
|
1304
1304
|
"""Maps prompt parameters to API parameters."""
|
|
1305
1305
|
|
|
1306
1306
|
api_params = {}
|
|
1307
|
-
for key
|
|
1307
|
+
for key in params.keys():
|
|
1308
1308
|
try:
|
|
1309
|
-
api_params[ConnectionReplacements._PARAMS_REPLACEMENTS[service][key]] =
|
|
1309
|
+
api_params[ConnectionReplacements._PARAMS_REPLACEMENTS[service][key]] = params[key]
|
|
1310
1310
|
except KeyError:
|
|
1311
|
-
api_params[key] =
|
|
1311
|
+
api_params[key] = params[key]
|
|
1312
1312
|
|
|
1313
1313
|
api_params["service"] = service
|
|
1314
1314
|
return api_params
|
|
@@ -385,7 +385,7 @@ async def datasource_truncate(ctx, datasource_name, yes, cascade):
|
|
|
385
385
|
|
|
386
386
|
@datasource.command(name="delete")
|
|
387
387
|
@click.argument("datasource_name")
|
|
388
|
-
@click.option("--sql-condition", help="SQL WHERE condition to remove rows", hidden=True, required=True)
|
|
388
|
+
@click.option("--sql-condition", default=None, help="SQL WHERE condition to remove rows", hidden=True, required=True)
|
|
389
389
|
@click.option("--yes", is_flag=True, default=False, help="Do not ask for confirmation")
|
|
390
390
|
@click.option(
|
|
391
391
|
"--wait/--no-wait",
|