tinybird 0.0.1.dev213__py3-none-any.whl → 0.0.1.dev215__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tinybird might be problematic. Click here for more details.
- tinybird/{tb/modules/datafile → datafile}/common.py +26 -26
- tinybird/datafile/parse_connection.py +60 -0
- tinybird/{tb/modules/datafile → datafile}/parse_datasource.py +3 -3
- tinybird/{tb/modules/datafile → datafile}/parse_pipe.py +3 -3
- tinybird/tb/__cli__.py +2 -2
- tinybird/tb/cli.py +1 -0
- tinybird/tb/client.py +3 -3
- tinybird/tb/modules/build.py +4 -4
- tinybird/tb/modules/common.py +4 -2
- tinybird/tb/modules/connection.py +30 -5
- tinybird/tb/modules/copy.py +2 -43
- tinybird/tb/modules/datafile/build.py +15 -15
- tinybird/tb/modules/datafile/build_datasource.py +1 -1
- tinybird/tb/modules/datafile/build_pipe.py +1 -1
- tinybird/tb/modules/datafile/diff.py +1 -1
- tinybird/tb/modules/datafile/format_common.py +1 -1
- tinybird/tb/modules/datafile/format_datasource.py +2 -2
- tinybird/tb/modules/datafile/format_pipe.py +3 -3
- tinybird/tb/modules/datafile/pipe_checker.py +1 -1
- tinybird/tb/modules/datafile/playground.py +17 -17
- tinybird/tb/modules/datasource.py +1 -1
- tinybird/tb/modules/deployment.py +1 -1
- tinybird/tb/modules/endpoint.py +1 -1
- tinybird/tb/modules/feedback_manager.py +9 -1
- tinybird/tb/modules/materialization.py +1 -1
- tinybird/tb/modules/pipe.py +1 -1
- tinybird/tb/modules/project.py +5 -3
- tinybird/tb/modules/sink.py +105 -0
- tinybird/tb/modules/watch.py +1 -1
- {tinybird-0.0.1.dev213.dist-info → tinybird-0.0.1.dev215.dist-info}/METADATA +1 -1
- {tinybird-0.0.1.dev213.dist-info → tinybird-0.0.1.dev215.dist-info}/RECORD +35 -33
- /tinybird/{tb/modules/datafile → datafile}/exceptions.py +0 -0
- {tinybird-0.0.1.dev213.dist-info → tinybird-0.0.1.dev215.dist-info}/WHEEL +0 -0
- {tinybird-0.0.1.dev213.dist-info → tinybird-0.0.1.dev215.dist-info}/entry_points.txt +0 -0
- {tinybird-0.0.1.dev213.dist-info → tinybird-0.0.1.dev215.dist-info}/top_level.txt +0 -0
|
@@ -25,7 +25,7 @@ from croniter import croniter
|
|
|
25
25
|
from mypy_extensions import KwArg, VarArg
|
|
26
26
|
|
|
27
27
|
from tinybird.ch_utils.engine import ENABLED_ENGINES
|
|
28
|
-
from tinybird.
|
|
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
31
|
|
|
@@ -473,19 +473,19 @@ def parse_indexes_structure(indexes: Optional[List[str]]) -> List[TableIndex]:
|
|
|
473
473
|
>>> parse_indexes_structure(["index_name u64 * length(s)"])
|
|
474
474
|
Traceback (most recent call last):
|
|
475
475
|
...
|
|
476
|
-
tinybird.
|
|
476
|
+
tinybird.datafile.common.IndexesSyntaxError: Invalid INDEX syntax at 1:1.
|
|
477
477
|
Usage: `[INDEX] name expr TYPE type_full GRANULARITY granularity`.
|
|
478
478
|
|
|
479
479
|
>>> parse_indexes_structure(["index_name a TYPE set(100) GRANULARITY 100, index_name_bf mapValues(d) TYPE bloom_filter(0.001) GRANULARITY 16"])
|
|
480
480
|
Traceback (most recent call last):
|
|
481
481
|
...
|
|
482
|
-
tinybird.
|
|
482
|
+
tinybird.datafile.common.IndexesSyntaxError: Invalid INDEX syntax at 1:1.
|
|
483
483
|
Usage: `[INDEX] name expr TYPE type_full GRANULARITY granularity`.
|
|
484
484
|
|
|
485
485
|
>>> parse_indexes_structure(["", " ", " wrong_index_syntax,"])
|
|
486
486
|
Traceback (most recent call last):
|
|
487
487
|
...
|
|
488
|
-
tinybird.
|
|
488
|
+
tinybird.datafile.common.IndexesSyntaxError: Invalid INDEX syntax at 3:6.
|
|
489
489
|
Usage: `[INDEX] name expr TYPE type_full GRANULARITY granularity`.
|
|
490
490
|
|
|
491
491
|
>>> parse_indexes_structure(["my_index m['key'] TYPE ngrambf_v1(1, 1024, 1, 42) GRANULARITY 1"])
|
|
@@ -1164,49 +1164,49 @@ def parse_table_structure(schema: str) -> List[Dict[str, Any]]:
|
|
|
1164
1164
|
>>> parse_table_structure('col') # Missing type
|
|
1165
1165
|
Traceback (most recent call last):
|
|
1166
1166
|
...
|
|
1167
|
-
tinybird.
|
|
1167
|
+
tinybird.datafile.common.SchemaSyntaxError: Column name and either type or DEFAULT are required at 1:1.
|
|
1168
1168
|
|
|
1169
1169
|
>>> parse_table_structure('`col Int32') # Unclosed backtick
|
|
1170
1170
|
Traceback (most recent call last):
|
|
1171
1171
|
...
|
|
1172
|
-
tinybird.
|
|
1172
|
+
tinybird.datafile.common.SchemaSyntaxError: Expected closing backtick at 1:5.
|
|
1173
1173
|
|
|
1174
1174
|
>>> parse_table_structure('col Int32 DEFAULT') # Missing DEFAULT value
|
|
1175
1175
|
Traceback (most recent call last):
|
|
1176
1176
|
...
|
|
1177
|
-
tinybird.
|
|
1177
|
+
tinybird.datafile.common.SchemaSyntaxError: Missing mandatory value for DEFAULT at 1:18.
|
|
1178
1178
|
|
|
1179
1179
|
>>> parse_table_structure('col Int32 CODEC') # Missing CODEC parameters
|
|
1180
1180
|
Traceback (most recent call last):
|
|
1181
1181
|
...
|
|
1182
|
-
tinybird.
|
|
1182
|
+
tinybird.datafile.common.SchemaSyntaxError: Missing mandatory value for CODEC at 1:16.
|
|
1183
1183
|
|
|
1184
1184
|
>>> parse_table_structure('col#name Int32') # Invalid character in name
|
|
1185
1185
|
Traceback (most recent call last):
|
|
1186
1186
|
...
|
|
1187
|
-
tinybird.
|
|
1187
|
+
tinybird.datafile.common.SchemaSyntaxError: Column name contains invalid character '#' at 1:4.
|
|
1188
1188
|
Hint: use backticks.
|
|
1189
1189
|
|
|
1190
1190
|
>>> parse_table_structure('col Int32 MATERIALIZED expr') # Unsupported MATERIALIZED
|
|
1191
1191
|
Traceback (most recent call last):
|
|
1192
1192
|
...
|
|
1193
|
-
tinybird.
|
|
1193
|
+
tinybird.datafile.common.SchemaSyntaxError: MATERIALIZED columns are not supported at 1:11.
|
|
1194
1194
|
|
|
1195
1195
|
>>> parse_table_structure('col Int32 TTL timestamp + INTERVAL 1 DAY') # Unsupported TTL
|
|
1196
1196
|
Traceback (most recent call last):
|
|
1197
1197
|
...
|
|
1198
|
-
tinybird.
|
|
1198
|
+
tinybird.datafile.common.SchemaSyntaxError: column TTL is not supported at 1:11.
|
|
1199
1199
|
|
|
1200
1200
|
>>> parse_table_structure('col Int32 NULL') # Unsupported NULL
|
|
1201
1201
|
Traceback (most recent call last):
|
|
1202
1202
|
...
|
|
1203
|
-
tinybird.
|
|
1203
|
+
tinybird.datafile.common.SchemaSyntaxError: NULL column syntax not supported at 1:11.
|
|
1204
1204
|
Hint: use Nullable(...).
|
|
1205
1205
|
|
|
1206
1206
|
>>> parse_table_structure('col Int32 NOT NULL') # Unsupported NOT NULL
|
|
1207
1207
|
Traceback (most recent call last):
|
|
1208
1208
|
...
|
|
1209
|
-
tinybird.
|
|
1209
|
+
tinybird.datafile.common.SchemaSyntaxError: NOT NULL column syntax not supported at 1:11.
|
|
1210
1210
|
Hint: Columns are not nullable by default.
|
|
1211
1211
|
|
|
1212
1212
|
>>> parse_table_structure('''
|
|
@@ -1215,7 +1215,7 @@ def parse_table_structure(schema: str) -> List[Dict[str, Any]]:
|
|
|
1215
1215
|
... ZSTD''') # Unclosed CODEC parenthesis across lines
|
|
1216
1216
|
Traceback (most recent call last):
|
|
1217
1217
|
...
|
|
1218
|
-
tinybird.
|
|
1218
|
+
tinybird.datafile.common.SchemaSyntaxError: Expected closing ) at 4:17.
|
|
1219
1219
|
|
|
1220
1220
|
>>> parse_table_structure('''
|
|
1221
1221
|
... timestamp DateTime
|
|
@@ -1223,7 +1223,7 @@ def parse_table_structure(schema: str) -> List[Dict[str, Any]]:
|
|
|
1223
1223
|
... CODEC(ZSTD)''') # Missing DEFAULT value with following CODEC
|
|
1224
1224
|
Traceback (most recent call last):
|
|
1225
1225
|
...
|
|
1226
|
-
tinybird.
|
|
1226
|
+
tinybird.datafile.common.SchemaSyntaxError: Missing mandatory value for DEFAULT at 3:16.
|
|
1227
1227
|
|
|
1228
1228
|
>>> parse_table_structure('''
|
|
1229
1229
|
... col String
|
|
@@ -1232,7 +1232,7 @@ def parse_table_structure(schema: str) -> List[Dict[str, Any]]:
|
|
|
1232
1232
|
... now()''') # MATERIALIZED with heavy indentation
|
|
1233
1233
|
Traceback (most recent call last):
|
|
1234
1234
|
...
|
|
1235
|
-
tinybird.
|
|
1235
|
+
tinybird.datafile.common.SchemaSyntaxError: MATERIALIZED columns are not supported at 4:13.
|
|
1236
1236
|
|
|
1237
1237
|
>>> parse_table_structure('''
|
|
1238
1238
|
... `column.with.dots`
|
|
@@ -1241,7 +1241,7 @@ def parse_table_structure(schema: str) -> List[Dict[str, Any]]:
|
|
|
1241
1241
|
... timestamp + INTERVAL 1 DAY''') # TTL with increasing indentation
|
|
1242
1242
|
Traceback (most recent call last):
|
|
1243
1243
|
...
|
|
1244
|
-
tinybird.
|
|
1244
|
+
tinybird.datafile.common.SchemaSyntaxError: column TTL is not supported at 4:18.
|
|
1245
1245
|
"""
|
|
1246
1246
|
return _parse_table_structure(schema)
|
|
1247
1247
|
|
|
@@ -1666,15 +1666,6 @@ def parse(
|
|
|
1666
1666
|
"shared_with": shared_with, # Not supported yet
|
|
1667
1667
|
"export_service": export_service, # Deprecated
|
|
1668
1668
|
"forward_query": sql("forward_query"),
|
|
1669
|
-
"export_connection_name": assign_var("export_connection_name"),
|
|
1670
|
-
"export_schedule": assign_var("export_schedule"),
|
|
1671
|
-
"export_bucket_uri": assign_var("export_bucket_uri"),
|
|
1672
|
-
"export_file_template": assign_var("export_file_template"),
|
|
1673
|
-
"export_format": assign_var("export_format"),
|
|
1674
|
-
"export_strategy": assign_var("export_strategy"),
|
|
1675
|
-
"export_compression": assign_var("export_compression"),
|
|
1676
|
-
"export_write_strategy": assign_var("export_write_strategy"),
|
|
1677
|
-
"export_kafka_topic": assign_var("export_kafka_topic"),
|
|
1678
1669
|
# ENGINE_* commands are added dynamically after this dict's definition
|
|
1679
1670
|
},
|
|
1680
1671
|
DatafileKind.pipe: {
|
|
@@ -1693,6 +1684,15 @@ def parse(
|
|
|
1693
1684
|
"include": include,
|
|
1694
1685
|
"sql": sql("sql"),
|
|
1695
1686
|
"version": version,
|
|
1687
|
+
"export_connection_name": assign_var("export_connection_name"),
|
|
1688
|
+
"export_schedule": assign_var("export_schedule"),
|
|
1689
|
+
"export_bucket_uri": assign_var("export_bucket_uri"),
|
|
1690
|
+
"export_file_template": assign_var("export_file_template"),
|
|
1691
|
+
"export_format": assign_var("export_format"),
|
|
1692
|
+
"export_strategy": assign_var("export_strategy"),
|
|
1693
|
+
"export_compression": assign_var("export_compression"),
|
|
1694
|
+
"export_write_strategy": assign_var("export_write_strategy"),
|
|
1695
|
+
"export_kafka_topic": assign_var("export_kafka_topic"),
|
|
1696
1696
|
},
|
|
1697
1697
|
DatafileKind.connection: {
|
|
1698
1698
|
"description": description,
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Dict, Optional
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
|
|
6
|
+
from tinybird.datafile.common import (
|
|
7
|
+
DatafileKind,
|
|
8
|
+
DatafileSyntaxError,
|
|
9
|
+
ParseResult,
|
|
10
|
+
format_filename,
|
|
11
|
+
parse,
|
|
12
|
+
)
|
|
13
|
+
from tinybird.datafile.exceptions import ParseException
|
|
14
|
+
from tinybird.sql_template import render_template_with_secrets
|
|
15
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def parse_connection(
|
|
19
|
+
filename: str,
|
|
20
|
+
replace_includes: bool = True,
|
|
21
|
+
content: Optional[str] = None,
|
|
22
|
+
skip_eval: bool = False,
|
|
23
|
+
hide_folders: bool = False,
|
|
24
|
+
add_context_to_datafile_syntax_errors: bool = True,
|
|
25
|
+
secrets: Optional[Dict[str, str]] = None,
|
|
26
|
+
) -> ParseResult:
|
|
27
|
+
basepath = ""
|
|
28
|
+
if not content:
|
|
29
|
+
with open(filename) as file:
|
|
30
|
+
s = file.read()
|
|
31
|
+
basepath = os.path.dirname(filename)
|
|
32
|
+
else:
|
|
33
|
+
s = content
|
|
34
|
+
|
|
35
|
+
s = render_template_with_secrets(filename, s, secrets=secrets or {})
|
|
36
|
+
filename = format_filename(filename, hide_folders)
|
|
37
|
+
try:
|
|
38
|
+
doc, warnings = parse(
|
|
39
|
+
s,
|
|
40
|
+
default_node="default",
|
|
41
|
+
basepath=basepath,
|
|
42
|
+
replace_includes=replace_includes,
|
|
43
|
+
skip_eval=skip_eval,
|
|
44
|
+
kind=DatafileKind.connection,
|
|
45
|
+
)
|
|
46
|
+
doc.validate()
|
|
47
|
+
except DatafileSyntaxError as e:
|
|
48
|
+
try:
|
|
49
|
+
if add_context_to_datafile_syntax_errors:
|
|
50
|
+
e.get_context_from_file_contents(s)
|
|
51
|
+
finally:
|
|
52
|
+
raise e
|
|
53
|
+
# TODO(eclbg): all these exceptions that trigger a ClickException shouldn't be here, as this code will only run in
|
|
54
|
+
# the server soon
|
|
55
|
+
except ParseException as e:
|
|
56
|
+
raise click.ClickException(
|
|
57
|
+
FeedbackManager.error_parsing_file(filename=filename, lineno=e.lineno, error=e)
|
|
58
|
+
) from None
|
|
59
|
+
|
|
60
|
+
return ParseResult(datafile=doc, warnings=warnings)
|
|
@@ -3,15 +3,15 @@ from typing import Dict, Optional
|
|
|
3
3
|
|
|
4
4
|
import click
|
|
5
5
|
|
|
6
|
-
from tinybird.
|
|
7
|
-
from tinybird.tb.modules.datafile.common import (
|
|
6
|
+
from tinybird.datafile.common import (
|
|
8
7
|
DatafileKind,
|
|
9
8
|
DatafileSyntaxError,
|
|
10
9
|
ParseResult,
|
|
11
10
|
format_filename,
|
|
12
11
|
parse,
|
|
13
12
|
)
|
|
14
|
-
from tinybird.
|
|
13
|
+
from tinybird.datafile.exceptions import ParseException
|
|
14
|
+
from tinybird.sql_template import render_template_with_secrets
|
|
15
15
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
16
16
|
|
|
17
17
|
|
|
@@ -3,15 +3,15 @@ from typing import Dict, List, Optional
|
|
|
3
3
|
|
|
4
4
|
import click
|
|
5
5
|
|
|
6
|
-
from tinybird.
|
|
7
|
-
from tinybird.tb.modules.datafile.common import (
|
|
6
|
+
from tinybird.datafile.common import (
|
|
8
7
|
DatafileKind,
|
|
9
8
|
DatafileSyntaxError,
|
|
10
9
|
ParseResult,
|
|
11
10
|
format_filename,
|
|
12
11
|
parse,
|
|
13
12
|
)
|
|
14
|
-
from tinybird.
|
|
13
|
+
from tinybird.datafile.exceptions import IncludeFileNotFoundException, ParseException
|
|
14
|
+
from tinybird.sql_template import get_template_and_variables, render_sql_template, secret_template_key
|
|
15
15
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
16
16
|
from tinybird.tornado_template import UnClosedIfError
|
|
17
17
|
|
tinybird/tb/__cli__.py
CHANGED
|
@@ -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__ = '0.0.1.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '0.0.1.dev215'
|
|
8
|
+
__revision__ = 'cdd01a6'
|
tinybird/tb/cli.py
CHANGED
|
@@ -25,6 +25,7 @@ import tinybird.tb.modules.mock
|
|
|
25
25
|
import tinybird.tb.modules.open
|
|
26
26
|
import tinybird.tb.modules.pipe
|
|
27
27
|
import tinybird.tb.modules.secret
|
|
28
|
+
import tinybird.tb.modules.sink
|
|
28
29
|
import tinybird.tb.modules.test
|
|
29
30
|
import tinybird.tb.modules.token
|
|
30
31
|
import tinybird.tb.modules.workspace
|
tinybird/tb/client.py
CHANGED
|
@@ -650,13 +650,13 @@ class TinyB:
|
|
|
650
650
|
async def pipe_remove_copy(self, pipe_name_or_id: str, node_id: str):
|
|
651
651
|
return await self._req(f"/v0/pipes/{pipe_name_or_id}/nodes/{node_id}/copy", method="DELETE")
|
|
652
652
|
|
|
653
|
-
async def
|
|
654
|
-
self, pipe_name_or_id: str, params: Optional[Dict[str, str]] = None, mode: Optional[str] = None
|
|
653
|
+
async def pipe_run(
|
|
654
|
+
self, pipe_name_or_id: str, pipe_type: str, params: Optional[Dict[str, str]] = None, mode: Optional[str] = None
|
|
655
655
|
):
|
|
656
656
|
params = {**params} if params else {}
|
|
657
657
|
if mode:
|
|
658
658
|
params["_mode"] = mode
|
|
659
|
-
return await self._req(f"/v0/pipes/{pipe_name_or_id}/
|
|
659
|
+
return await self._req(f"/v0/pipes/{pipe_name_or_id}/{pipe_type}?{urlencode(params)}", method="POST")
|
|
660
660
|
|
|
661
661
|
async def pipe_resume_copy(self, pipe_name_or_id: str):
|
|
662
662
|
return await self._req(f"/v0/pipes/{pipe_name_or_id}/copy/resume", method="POST")
|
tinybird/tb/modules/build.py
CHANGED
|
@@ -13,14 +13,14 @@ import click
|
|
|
13
13
|
import requests
|
|
14
14
|
|
|
15
15
|
import tinybird.context as context
|
|
16
|
+
from tinybird.datafile.exceptions import ParseException
|
|
17
|
+
from tinybird.datafile.parse_datasource import parse_datasource
|
|
18
|
+
from tinybird.datafile.parse_pipe import parse_pipe
|
|
16
19
|
from tinybird.tb.client import TinyB
|
|
17
20
|
from tinybird.tb.modules.cli import cli
|
|
18
21
|
from tinybird.tb.modules.common import push_data, sys_exit
|
|
19
22
|
from tinybird.tb.modules.config import CLIConfig
|
|
20
|
-
from tinybird.tb.modules.datafile.exceptions import ParseException
|
|
21
23
|
from tinybird.tb.modules.datafile.fixture import FixtureExtension, get_fixture_dir, persist_fixture
|
|
22
|
-
from tinybird.tb.modules.datafile.parse_datasource import parse_datasource
|
|
23
|
-
from tinybird.tb.modules.datafile.parse_pipe import parse_pipe
|
|
24
24
|
from tinybird.tb.modules.datafile.playground import folder_playground
|
|
25
25
|
from tinybird.tb.modules.dev_server import BuildStatus, start_server
|
|
26
26
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
@@ -110,7 +110,7 @@ def build_project(project: Project, tb_client: TinyB, silent: bool = False) -> O
|
|
|
110
110
|
return False
|
|
111
111
|
|
|
112
112
|
for file_path in project_files:
|
|
113
|
-
relative_path =
|
|
113
|
+
relative_path = Path(file_path).relative_to(project_path).as_posix()
|
|
114
114
|
with open(file_path, "rb") as fd:
|
|
115
115
|
content_type = DATAFILE_TYPE_TO_CONTENT_TYPE.get(Path(file_path).suffix, "application/unknown")
|
|
116
116
|
files.append(
|
tinybird/tb/modules/common.py
CHANGED
|
@@ -1707,6 +1707,7 @@ async def run_aws_iamrole_connection_flow(
|
|
|
1707
1707
|
service: str,
|
|
1708
1708
|
environment: str,
|
|
1709
1709
|
connection_name: str,
|
|
1710
|
+
policy: str,
|
|
1710
1711
|
) -> Tuple[str, str, str]:
|
|
1711
1712
|
if service == DataConnectorType.AMAZON_DYNAMODB:
|
|
1712
1713
|
raise NotImplementedError("DynamoDB is not supported")
|
|
@@ -1721,7 +1722,7 @@ async def run_aws_iamrole_connection_flow(
|
|
|
1721
1722
|
validate_string_connector_param("Region", region)
|
|
1722
1723
|
|
|
1723
1724
|
access_policy, trust_policy, _ = await get_aws_iamrole_policies(
|
|
1724
|
-
client, service=service, policy=
|
|
1725
|
+
client, service=service, policy=policy, bucket=bucket_name, external_id_seed=connection_name
|
|
1725
1726
|
)
|
|
1726
1727
|
|
|
1727
1728
|
click.echo(FeedbackManager.prompt_s3_iamrole_connection_login_aws())
|
|
@@ -1810,9 +1811,10 @@ async def production_aws_iamrole_only(
|
|
|
1810
1811
|
bucket_name: str,
|
|
1811
1812
|
environment: str,
|
|
1812
1813
|
connection_name: str,
|
|
1814
|
+
policy: str,
|
|
1813
1815
|
) -> Tuple[str, str, str]:
|
|
1814
1816
|
_, trust_policy, external_id = await get_aws_iamrole_policies(
|
|
1815
|
-
prod_client, service=service, policy=
|
|
1817
|
+
prod_client, service=service, policy=policy, bucket=bucket_name, external_id_seed=connection_name
|
|
1816
1818
|
)
|
|
1817
1819
|
|
|
1818
1820
|
trust_policy_copied = True
|
|
@@ -178,12 +178,28 @@ async def connection_create_s3(ctx: Context) -> None:
|
|
|
178
178
|
|
|
179
179
|
service = DataConnectorType.AMAZON_S3
|
|
180
180
|
click.echo(FeedbackManager.prompt_s3_connection_header())
|
|
181
|
+
|
|
182
|
+
# Ask user for access type
|
|
183
|
+
access_type = click.prompt(
|
|
184
|
+
FeedbackManager.highlight(
|
|
185
|
+
message="What type of access do you need for this S3 connection?\n"
|
|
186
|
+
' - "read" for S3 Data Source (reading from S3)\n'
|
|
187
|
+
' - "write" for S3 Sink (writing to S3)\n'
|
|
188
|
+
"Access type",
|
|
189
|
+
),
|
|
190
|
+
type=click.Choice(["read", "write"], case_sensitive=False),
|
|
191
|
+
default="read",
|
|
192
|
+
show_choices=True,
|
|
193
|
+
show_default=True,
|
|
194
|
+
)
|
|
195
|
+
|
|
181
196
|
connection_name = get_s3_connection_name(project.folder)
|
|
182
197
|
role_arn, region, bucket_name = await run_aws_iamrole_connection_flow(
|
|
183
198
|
client,
|
|
184
199
|
service=service,
|
|
185
200
|
environment=obj["env"],
|
|
186
201
|
connection_name=connection_name,
|
|
202
|
+
policy=access_type.lower(),
|
|
187
203
|
)
|
|
188
204
|
unique_suffix = uuid.uuid4().hex[:8] # Use first 8 chars of a UUID for brevity
|
|
189
205
|
secret_name = f"s3_role_arn_{connection_name}_{unique_suffix}"
|
|
@@ -211,6 +227,7 @@ async def connection_create_s3(ctx: Context) -> None:
|
|
|
211
227
|
bucket_name=bucket_name,
|
|
212
228
|
environment="cloud",
|
|
213
229
|
connection_name=connection_name,
|
|
230
|
+
policy=access_type.lower(),
|
|
214
231
|
)
|
|
215
232
|
await prod_client.create_secret(name=secret_name, value=prod_role_arn)
|
|
216
233
|
|
|
@@ -222,12 +239,20 @@ async def connection_create_s3(ctx: Context) -> None:
|
|
|
222
239
|
folder=project.folder,
|
|
223
240
|
)
|
|
224
241
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
242
|
+
if access_type.lower() == "write":
|
|
243
|
+
click.echo(
|
|
244
|
+
FeedbackManager.prompt_s3_iamrole_success_write(
|
|
245
|
+
connection_name=connection_name,
|
|
246
|
+
connection_path=str(connection_file_path),
|
|
247
|
+
)
|
|
248
|
+
)
|
|
249
|
+
else:
|
|
250
|
+
click.echo(
|
|
251
|
+
FeedbackManager.prompt_s3_iamrole_success_read(
|
|
252
|
+
connection_name=connection_name,
|
|
253
|
+
connection_path=str(connection_file_path),
|
|
254
|
+
)
|
|
229
255
|
)
|
|
230
|
-
)
|
|
231
256
|
|
|
232
257
|
|
|
233
258
|
@connection_create.command(name="gcs", short_help="Creates a Google Cloud Storage connection.")
|
tinybird/tb/modules/copy.py
CHANGED
|
@@ -10,10 +10,10 @@ from typing import Optional, Tuple
|
|
|
10
10
|
import click
|
|
11
11
|
from click import Context
|
|
12
12
|
|
|
13
|
+
from tinybird.datafile.common import get_name_version
|
|
13
14
|
from tinybird.tb.client import AuthNoTokenException, TinyB
|
|
14
15
|
from tinybird.tb.modules.cli import cli
|
|
15
16
|
from tinybird.tb.modules.common import coro, echo_safe_humanfriendly_tables_format_smart_table, wait_job
|
|
16
|
-
from tinybird.tb.modules.datafile.common import get_name_version
|
|
17
17
|
from tinybird.tb.modules.exceptions import CLIPipeException
|
|
18
18
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
19
19
|
|
|
@@ -93,8 +93,7 @@ async def copy_run(ctx: click.Context, pipe_name_or_id: str, wait: bool, mode: s
|
|
|
93
93
|
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
94
94
|
|
|
95
95
|
try:
|
|
96
|
-
response = await client.
|
|
97
|
-
|
|
96
|
+
response = await client.pipe_run(pipe_name_or_id, "copy", params, mode)
|
|
98
97
|
job_id = response["job"]["job_id"]
|
|
99
98
|
job_url = response["job"]["job_url"]
|
|
100
99
|
target_datasource_id = response["tags"]["copy_target_datasource"]
|
|
@@ -112,43 +111,3 @@ async def copy_run(ctx: click.Context, pipe_name_or_id: str, wait: bool, mode: s
|
|
|
112
111
|
raise
|
|
113
112
|
except Exception as e:
|
|
114
113
|
raise CLIPipeException(FeedbackManager.error_creating_copy_job(error=e))
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
@copy.command(name="resume", short_help="Resume a paused copy pipe")
|
|
118
|
-
@click.argument("pipe_name_or_id")
|
|
119
|
-
@click.pass_context
|
|
120
|
-
@coro
|
|
121
|
-
async def copy_resume(ctx: click.Context, pipe_name_or_id: str):
|
|
122
|
-
"""Resume a paused copy pipe"""
|
|
123
|
-
|
|
124
|
-
click.echo(FeedbackManager.info_copy_pipe_resuming(pipe=pipe_name_or_id))
|
|
125
|
-
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
126
|
-
|
|
127
|
-
try:
|
|
128
|
-
await client.pipe_resume_copy(pipe_name_or_id)
|
|
129
|
-
click.echo(FeedbackManager.success_copy_pipe_resumed(pipe=pipe_name_or_id))
|
|
130
|
-
|
|
131
|
-
except AuthNoTokenException:
|
|
132
|
-
raise
|
|
133
|
-
except Exception as e:
|
|
134
|
-
raise CLIPipeException(FeedbackManager.error_resuming_copy_pipe(error=e))
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
@copy.command(name="pause", short_help="Pause a running copy pipe")
|
|
138
|
-
@click.argument("pipe_name_or_id")
|
|
139
|
-
@click.pass_context
|
|
140
|
-
@coro
|
|
141
|
-
async def copy_pause(ctx: click.Context, pipe_name_or_id: str):
|
|
142
|
-
"""Pause a running copy pipe"""
|
|
143
|
-
|
|
144
|
-
click.echo(FeedbackManager.info_copy_pipe_pausing(pipe=pipe_name_or_id))
|
|
145
|
-
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
146
|
-
|
|
147
|
-
try:
|
|
148
|
-
await client.pipe_pause_copy(pipe_name_or_id)
|
|
149
|
-
click.echo(FeedbackManager.success_copy_pipe_paused(pipe=pipe_name_or_id))
|
|
150
|
-
|
|
151
|
-
except AuthNoTokenException:
|
|
152
|
-
raise
|
|
153
|
-
except Exception as e:
|
|
154
|
-
raise CLIPipeException(FeedbackManager.error_pausing_copy_pipe(error=e))
|
|
@@ -11,18 +11,7 @@ from typing import Any, Dict, Iterable, List, Optional, Set, Tuple, Union
|
|
|
11
11
|
import click
|
|
12
12
|
from toposort import toposort
|
|
13
13
|
|
|
14
|
-
from tinybird.
|
|
15
|
-
from tinybird.sql_template import get_used_tables_in_template, render_sql_template
|
|
16
|
-
from tinybird.tb.client import TinyB
|
|
17
|
-
from tinybird.tb.modules.common import get_ca_pem_content
|
|
18
|
-
from tinybird.tb.modules.datafile.build_datasource import is_datasource
|
|
19
|
-
from tinybird.tb.modules.datafile.build_pipe import (
|
|
20
|
-
get_target_materialized_data_source_name,
|
|
21
|
-
is_endpoint,
|
|
22
|
-
is_endpoint_with_no_dependencies,
|
|
23
|
-
is_materialized,
|
|
24
|
-
)
|
|
25
|
-
from tinybird.tb.modules.datafile.common import (
|
|
14
|
+
from tinybird.datafile.common import (
|
|
26
15
|
DEFAULT_CRON_PERIOD,
|
|
27
16
|
INTERNAL_TABLES,
|
|
28
17
|
ON_DEMAND,
|
|
@@ -38,9 +27,20 @@ from tinybird.tb.modules.datafile.common import (
|
|
|
38
27
|
get_project_filenames,
|
|
39
28
|
pp,
|
|
40
29
|
)
|
|
41
|
-
from tinybird.
|
|
42
|
-
from tinybird.
|
|
43
|
-
from tinybird.
|
|
30
|
+
from tinybird.datafile.exceptions import AlreadyExistsException, IncludeFileNotFoundException
|
|
31
|
+
from tinybird.datafile.parse_datasource import parse_datasource
|
|
32
|
+
from tinybird.datafile.parse_pipe import parse_pipe
|
|
33
|
+
from tinybird.sql import parse_table_structure, schema_to_sql_columns
|
|
34
|
+
from tinybird.sql_template import get_used_tables_in_template, render_sql_template
|
|
35
|
+
from tinybird.tb.client import TinyB
|
|
36
|
+
from tinybird.tb.modules.common import get_ca_pem_content
|
|
37
|
+
from tinybird.tb.modules.datafile.build_datasource import is_datasource
|
|
38
|
+
from tinybird.tb.modules.datafile.build_pipe import (
|
|
39
|
+
get_target_materialized_data_source_name,
|
|
40
|
+
is_endpoint,
|
|
41
|
+
is_endpoint_with_no_dependencies,
|
|
42
|
+
is_materialized,
|
|
43
|
+
)
|
|
44
44
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
45
45
|
from tinybird.tb.modules.project import Project
|
|
46
46
|
|
|
@@ -5,8 +5,8 @@ from typing import Any, Dict, List, Optional
|
|
|
5
5
|
|
|
6
6
|
import click
|
|
7
7
|
|
|
8
|
+
from tinybird.datafile.common import PREVIEW_CONNECTOR_SERVICES, ImportReplacements
|
|
8
9
|
from tinybird.tb.client import DoesNotExistException, TinyB
|
|
9
|
-
from tinybird.tb.modules.datafile.common import PREVIEW_CONNECTOR_SERVICES, ImportReplacements
|
|
10
10
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
11
11
|
|
|
12
12
|
|
|
@@ -6,10 +6,10 @@ from urllib.parse import urlencode
|
|
|
6
6
|
import click
|
|
7
7
|
import requests
|
|
8
8
|
|
|
9
|
+
from tinybird.datafile.common import PipeNodeTypes
|
|
9
10
|
from tinybird.tb.client import TinyB
|
|
10
11
|
from tinybird.tb.modules.common import requests_get
|
|
11
12
|
from tinybird.tb.modules.config import CLIConfig
|
|
12
|
-
from tinybird.tb.modules.datafile.common import PipeNodeTypes
|
|
13
13
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
14
14
|
|
|
15
15
|
|
|
@@ -22,9 +22,9 @@ import sys
|
|
|
22
22
|
|
|
23
23
|
import click
|
|
24
24
|
|
|
25
|
+
from tinybird.datafile.common import get_name_version, get_project_filenames, is_file_a_datasource, peek
|
|
25
26
|
from tinybird.sql_template_fmt import DEFAULT_FMT_LINE_LENGTH
|
|
26
27
|
from tinybird.tb.client import TinyB
|
|
27
|
-
from tinybird.tb.modules.datafile.common import get_name_version, get_project_filenames, is_file_a_datasource, peek
|
|
28
28
|
from tinybird.tb.modules.datafile.format_datasource import format_datasource
|
|
29
29
|
from tinybird.tb.modules.datafile.format_pipe import format_pipe
|
|
30
30
|
from tinybird.tb.modules.datafile.pull import folder_pull
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from typing import Any, Dict, List, Optional
|
|
2
2
|
|
|
3
|
+
from tinybird.datafile.common import Datafile
|
|
4
|
+
from tinybird.datafile.parse_datasource import parse_datasource
|
|
3
5
|
from tinybird.sql import schema_to_sql_columns
|
|
4
6
|
from tinybird.tb.client import TinyB
|
|
5
|
-
from tinybird.tb.modules.datafile.common import Datafile
|
|
6
7
|
from tinybird.tb.modules.datafile.format_common import (
|
|
7
8
|
DATAFILE_INDENT,
|
|
8
9
|
DATAFILE_NEW_LINE,
|
|
@@ -12,7 +13,6 @@ from tinybird.tb.modules.datafile.format_common import (
|
|
|
12
13
|
format_tags,
|
|
13
14
|
format_tokens,
|
|
14
15
|
)
|
|
15
|
-
from tinybird.tb.modules.datafile.parse_datasource import parse_datasource
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
async def format_datasource(
|
|
@@ -2,8 +2,7 @@ import os
|
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
from typing import Any, Dict, List, Optional
|
|
4
4
|
|
|
5
|
-
from tinybird.
|
|
6
|
-
from tinybird.tb.modules.datafile.common import (
|
|
5
|
+
from tinybird.datafile.common import (
|
|
7
6
|
ON_DEMAND,
|
|
8
7
|
CopyParameters,
|
|
9
8
|
Datafile,
|
|
@@ -12,6 +11,8 @@ from tinybird.tb.modules.datafile.common import (
|
|
|
12
11
|
_unquote,
|
|
13
12
|
eval_var,
|
|
14
13
|
)
|
|
14
|
+
from tinybird.datafile.parse_pipe import parse_pipe
|
|
15
|
+
from tinybird.sql_template_fmt import DEFAULT_FMT_LINE_LENGTH, format_sql_template
|
|
15
16
|
from tinybird.tb.modules.datafile.format_common import (
|
|
16
17
|
DATAFILE_INDENT,
|
|
17
18
|
DATAFILE_NEW_LINE,
|
|
@@ -21,7 +22,6 @@ from tinybird.tb.modules.datafile.format_common import (
|
|
|
21
22
|
format_tokens,
|
|
22
23
|
)
|
|
23
24
|
from tinybird.tb.modules.datafile.format_datasource import format_engine
|
|
24
|
-
from tinybird.tb.modules.datafile.parse_pipe import parse_pipe
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
def format_node_sql(
|
|
@@ -14,8 +14,8 @@ import requests
|
|
|
14
14
|
from humanfriendly import format_size
|
|
15
15
|
from requests import Response
|
|
16
16
|
|
|
17
|
+
from tinybird.datafile.common import normalize_array
|
|
17
18
|
from tinybird.tb.modules.common import getenv_bool
|
|
18
|
-
from tinybird.tb.modules.datafile.common import normalize_array
|
|
19
19
|
|
|
20
20
|
PIPE_CHECKER_RETRIES: int = 3
|
|
21
21
|
|
|
@@ -11,20 +11,7 @@ from typing import Any, Dict, Iterable, List, Optional, Set, Tuple, Union
|
|
|
11
11
|
import click
|
|
12
12
|
from toposort import toposort
|
|
13
13
|
|
|
14
|
-
from tinybird.
|
|
15
|
-
from tinybird.sql_template import get_used_tables_in_template, render_sql_template
|
|
16
|
-
from tinybird.tb.client import TinyB
|
|
17
|
-
from tinybird.tb.modules.common import get_ca_pem_content
|
|
18
|
-
from tinybird.tb.modules.config import CLIConfig
|
|
19
|
-
from tinybird.tb.modules.datafile.build_datasource import is_datasource
|
|
20
|
-
from tinybird.tb.modules.datafile.build_pipe import (
|
|
21
|
-
get_target_materialized_data_source_name,
|
|
22
|
-
is_endpoint,
|
|
23
|
-
is_endpoint_with_no_dependencies,
|
|
24
|
-
is_materialized,
|
|
25
|
-
new_pipe,
|
|
26
|
-
)
|
|
27
|
-
from tinybird.tb.modules.datafile.common import (
|
|
14
|
+
from tinybird.datafile.common import (
|
|
28
15
|
DEFAULT_CRON_PERIOD,
|
|
29
16
|
INTERNAL_TABLES,
|
|
30
17
|
ON_DEMAND,
|
|
@@ -40,9 +27,22 @@ from tinybird.tb.modules.datafile.common import (
|
|
|
40
27
|
get_project_filenames,
|
|
41
28
|
pp,
|
|
42
29
|
)
|
|
43
|
-
from tinybird.
|
|
44
|
-
from tinybird.
|
|
45
|
-
from tinybird.
|
|
30
|
+
from tinybird.datafile.exceptions import AlreadyExistsException, IncludeFileNotFoundException
|
|
31
|
+
from tinybird.datafile.parse_datasource import parse_datasource
|
|
32
|
+
from tinybird.datafile.parse_pipe import parse_pipe
|
|
33
|
+
from tinybird.sql import parse_table_structure, schema_to_sql_columns
|
|
34
|
+
from tinybird.sql_template import get_used_tables_in_template, render_sql_template
|
|
35
|
+
from tinybird.tb.client import TinyB
|
|
36
|
+
from tinybird.tb.modules.common import get_ca_pem_content
|
|
37
|
+
from tinybird.tb.modules.config import CLIConfig
|
|
38
|
+
from tinybird.tb.modules.datafile.build_datasource import is_datasource
|
|
39
|
+
from tinybird.tb.modules.datafile.build_pipe import (
|
|
40
|
+
get_target_materialized_data_source_name,
|
|
41
|
+
is_endpoint,
|
|
42
|
+
is_endpoint_with_no_dependencies,
|
|
43
|
+
is_materialized,
|
|
44
|
+
new_pipe,
|
|
45
|
+
)
|
|
46
46
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
47
47
|
from tinybird.tb.modules.project import Project
|
|
48
48
|
|
|
@@ -18,6 +18,7 @@ import humanfriendly
|
|
|
18
18
|
import requests
|
|
19
19
|
from click import Context
|
|
20
20
|
|
|
21
|
+
from tinybird.datafile.common import get_name_version
|
|
21
22
|
from tinybird.prompts import quarantine_prompt
|
|
22
23
|
from tinybird.syncasync import sync_to_async
|
|
23
24
|
from tinybird.tb.client import AuthNoTokenException, DoesNotExistException, TinyB
|
|
@@ -40,7 +41,6 @@ from tinybird.tb.modules.create import (
|
|
|
40
41
|
generate_aws_iamrole_connection_file_with_secret,
|
|
41
42
|
generate_gcs_connection_file_with_secrets,
|
|
42
43
|
)
|
|
43
|
-
from tinybird.tb.modules.datafile.common import get_name_version
|
|
44
44
|
from tinybird.tb.modules.datafile.fixture import persist_fixture
|
|
45
45
|
from tinybird.tb.modules.exceptions import CLIDatasourceException
|
|
46
46
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
@@ -541,7 +541,7 @@ def create_deployment(
|
|
|
541
541
|
("context://", ("cli-version", "1.0.0", "text/plain")),
|
|
542
542
|
]
|
|
543
543
|
for file_path in project.get_project_files():
|
|
544
|
-
relative_path =
|
|
544
|
+
relative_path = Path(file_path).relative_to(project.path).as_posix()
|
|
545
545
|
with open(file_path, "rb") as fd:
|
|
546
546
|
content_type = DATAFILE_TYPE_TO_CONTENT_TYPE.get(Path(file_path).suffix, "application/unknown")
|
|
547
547
|
files.append((MULTIPART_BOUNDARY_DATA_PROJECT, (relative_path, fd.read().decode("utf-8"), content_type)))
|
tinybird/tb/modules/endpoint.py
CHANGED
|
@@ -14,10 +14,10 @@ import pyperclip
|
|
|
14
14
|
import requests
|
|
15
15
|
from click import Context
|
|
16
16
|
|
|
17
|
+
from tinybird.datafile.common import get_name_version
|
|
17
18
|
from tinybird.tb.client import AuthNoTokenException, DoesNotExistException, TinyB
|
|
18
19
|
from tinybird.tb.modules.cli import cli
|
|
19
20
|
from tinybird.tb.modules.common import coro, echo_safe_humanfriendly_tables_format_smart_table
|
|
20
|
-
from tinybird.tb.modules.datafile.common import get_name_version
|
|
21
21
|
from tinybird.tb.modules.exceptions import CLIPipeException
|
|
22
22
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
23
23
|
|
|
@@ -587,7 +587,7 @@ STEP {step}: CREATE IAM ROLE FOR {environment} ENVIRONMENT
|
|
|
587
587
|
Please enter the ARN of the role you just created"""
|
|
588
588
|
)
|
|
589
589
|
|
|
590
|
-
|
|
590
|
+
prompt_s3_iamrole_success_read = success_message("""
|
|
591
591
|
✅ S3 CONNECTION CONFIGURED SUCCESSFULLY
|
|
592
592
|
|
|
593
593
|
• File created at: {connection_path}
|
|
@@ -595,6 +595,14 @@ Please enter the ARN of the role you just created"""
|
|
|
595
595
|
• Learn more about our S3 Connector: https://www.tinybird.co/docs/forward/get-data-in/connectors/s3
|
|
596
596
|
""")
|
|
597
597
|
|
|
598
|
+
prompt_s3_iamrole_success_write = success_message("""
|
|
599
|
+
✅ S3 CONNECTION CONFIGURED SUCCESSFULLY
|
|
600
|
+
|
|
601
|
+
• File created at: {connection_path}
|
|
602
|
+
• You can now use this connection in your Data Sources with: EXPORT_CONNECTION_NAME '{connection_name}'
|
|
603
|
+
• Learn more about our S3 Sinks: https://www.tinybird.co/docs/forward/work-with-data/publish-data/s3-sinks
|
|
604
|
+
""")
|
|
605
|
+
|
|
598
606
|
# S3 IAM Role Connection Messages
|
|
599
607
|
prompt_gcs_connection_header = info_highlight_message("""
|
|
600
608
|
──────────────────────────────────────────────────────────────
|
|
@@ -3,6 +3,7 @@ import re
|
|
|
3
3
|
|
|
4
4
|
import click
|
|
5
5
|
|
|
6
|
+
from tinybird.datafile.common import PipeTypes, get_name_version
|
|
6
7
|
from tinybird.tb.client import TinyB
|
|
7
8
|
from tinybird.tb.modules.cli import cli
|
|
8
9
|
from tinybird.tb.modules.common import (
|
|
@@ -10,7 +11,6 @@ from tinybird.tb.modules.common import (
|
|
|
10
11
|
echo_safe_humanfriendly_tables_format_smart_table,
|
|
11
12
|
wait_job,
|
|
12
13
|
)
|
|
13
|
-
from tinybird.tb.modules.datafile.common import PipeTypes, get_name_version
|
|
14
14
|
from tinybird.tb.modules.exceptions import CLIPipeException
|
|
15
15
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
16
16
|
|
tinybird/tb/modules/pipe.py
CHANGED
|
@@ -9,13 +9,13 @@ import re
|
|
|
9
9
|
import click
|
|
10
10
|
from click import Context
|
|
11
11
|
|
|
12
|
+
from tinybird.datafile.common import get_name_version
|
|
12
13
|
from tinybird.tb.client import TinyB
|
|
13
14
|
from tinybird.tb.modules.cli import cli
|
|
14
15
|
from tinybird.tb.modules.common import (
|
|
15
16
|
coro,
|
|
16
17
|
echo_safe_humanfriendly_tables_format_smart_table,
|
|
17
18
|
)
|
|
18
|
-
from tinybird.tb.modules.datafile.common import get_name_version
|
|
19
19
|
from tinybird.tb.modules.exceptions import CLIPipeException
|
|
20
20
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
21
21
|
|
tinybird/tb/modules/project.py
CHANGED
|
@@ -3,9 +3,9 @@ import re
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import Dict, List, Optional
|
|
5
5
|
|
|
6
|
-
from tinybird.
|
|
7
|
-
from tinybird.
|
|
8
|
-
from tinybird.
|
|
6
|
+
from tinybird.datafile.common import Datafile
|
|
7
|
+
from tinybird.datafile.parse_datasource import parse_datasource
|
|
8
|
+
from tinybird.datafile.parse_pipe import parse_pipe
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class Project:
|
|
@@ -125,6 +125,8 @@ class Project:
|
|
|
125
125
|
return "materialization"
|
|
126
126
|
elif re.search(r"TYPE copy", content, re.IGNORECASE):
|
|
127
127
|
return "copy"
|
|
128
|
+
elif re.search(r"TYPE sink", content, re.IGNORECASE):
|
|
129
|
+
return "sink"
|
|
128
130
|
return "pipe"
|
|
129
131
|
except Exception:
|
|
130
132
|
return "pipe"
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import re
|
|
3
|
+
from typing import Optional, Tuple
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from click import Context
|
|
7
|
+
|
|
8
|
+
from tinybird.datafile.common import get_name_version
|
|
9
|
+
from tinybird.tb.client import AuthNoTokenException, TinyB
|
|
10
|
+
from tinybird.tb.modules.cli import cli
|
|
11
|
+
from tinybird.tb.modules.common import coro, echo_safe_humanfriendly_tables_format_smart_table, wait_job
|
|
12
|
+
from tinybird.tb.modules.exceptions import CLIPipeException
|
|
13
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@cli.group()
|
|
17
|
+
@click.pass_context
|
|
18
|
+
def sink(ctx):
|
|
19
|
+
"""Sink pipe commands."""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@sink.command(name="ls")
|
|
23
|
+
@click.option("--match", default=None, help="Retrieve any resourcing matching the pattern. eg --match _test")
|
|
24
|
+
@click.option(
|
|
25
|
+
"--format",
|
|
26
|
+
"format_",
|
|
27
|
+
type=click.Choice(["json"], case_sensitive=False),
|
|
28
|
+
default=None,
|
|
29
|
+
help="Force a type of the output",
|
|
30
|
+
)
|
|
31
|
+
@click.pass_context
|
|
32
|
+
@coro
|
|
33
|
+
async def sink_ls(ctx: Context, match: str, format_: str):
|
|
34
|
+
"""List sink pipes"""
|
|
35
|
+
|
|
36
|
+
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
37
|
+
pipes = await client.pipes(dependencies=False, node_attrs="name", attrs="name,updated_at,type")
|
|
38
|
+
sinks = [p for p in pipes if p.get("type") == "sink"]
|
|
39
|
+
sinks = sorted(sinks, key=lambda p: p["updated_at"])
|
|
40
|
+
columns = ["name", "updated at", "nodes"]
|
|
41
|
+
table_human_readable = []
|
|
42
|
+
table_machine_readable = []
|
|
43
|
+
pattern = re.compile(match) if match else None
|
|
44
|
+
for t in sinks:
|
|
45
|
+
tk = get_name_version(t["name"])
|
|
46
|
+
if pattern and not pattern.search(tk["name"]):
|
|
47
|
+
continue
|
|
48
|
+
table_human_readable.append((tk["name"], t["updated_at"][:-7], len(t["nodes"])))
|
|
49
|
+
table_machine_readable.append(
|
|
50
|
+
{
|
|
51
|
+
"name": tk["name"],
|
|
52
|
+
"updated at": t["updated_at"][:-7],
|
|
53
|
+
"nodes": len(t["nodes"]),
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
if not format_:
|
|
58
|
+
click.echo(FeedbackManager.info_pipes())
|
|
59
|
+
echo_safe_humanfriendly_tables_format_smart_table(table_human_readable, column_names=columns)
|
|
60
|
+
click.echo("\n")
|
|
61
|
+
elif format_ == "json":
|
|
62
|
+
click.echo(json.dumps({"pipes": table_machine_readable}, indent=2))
|
|
63
|
+
else:
|
|
64
|
+
raise CLIPipeException(FeedbackManager.error_pipe_ls_type())
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@sink.command(name="run", short_help="Run an on-demand sink job")
|
|
68
|
+
@click.argument("pipe_name_or_id")
|
|
69
|
+
@click.option("--wait", is_flag=True, default=False, help="Wait for the sink job to finish")
|
|
70
|
+
@click.option(
|
|
71
|
+
"--mode", type=click.Choice(["append", "replace"], case_sensitive=True), default=None, help="Sink strategy"
|
|
72
|
+
)
|
|
73
|
+
@click.option(
|
|
74
|
+
"--param",
|
|
75
|
+
nargs=1,
|
|
76
|
+
type=str,
|
|
77
|
+
multiple=True,
|
|
78
|
+
default=None,
|
|
79
|
+
help="Key and value of the params you want the Sink pipe to be called with. For example: tb pipe sink run <my_sink_pipe> --param foo=bar",
|
|
80
|
+
)
|
|
81
|
+
@click.pass_context
|
|
82
|
+
@coro
|
|
83
|
+
async def sink_run(ctx: click.Context, pipe_name_or_id: str, wait: bool, mode: str, param: Optional[Tuple[str]]):
|
|
84
|
+
"""Run a sink pipe"""
|
|
85
|
+
|
|
86
|
+
params = dict(key_value.split("=") for key_value in param) if param else {}
|
|
87
|
+
click.echo(FeedbackManager.highlight(message=f"\n» Running sink '{pipe_name_or_id}'"))
|
|
88
|
+
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
response = await client.pipe_run(pipe_name_or_id, "sink", params, mode)
|
|
92
|
+
job_id = response["job"]["id"]
|
|
93
|
+
job_url = response["job"]["job_url"]
|
|
94
|
+
click.echo(FeedbackManager.gray(message="Job URL: ") + FeedbackManager.info(message=f"{job_url}"))
|
|
95
|
+
click.echo(FeedbackManager.success(message="✓ Sink job created"))
|
|
96
|
+
|
|
97
|
+
if wait:
|
|
98
|
+
click.echo("\n")
|
|
99
|
+
await wait_job(client, job_id, job_url, FeedbackManager.highlight(message="» Exporting data"))
|
|
100
|
+
click.echo(FeedbackManager.success(message="✓ Data exported"))
|
|
101
|
+
|
|
102
|
+
except AuthNoTokenException:
|
|
103
|
+
raise
|
|
104
|
+
except Exception as e:
|
|
105
|
+
raise CLIPipeException(FeedbackManager.error_creating_sink_job(error=e))
|
tinybird/tb/modules/watch.py
CHANGED
|
@@ -15,7 +15,7 @@ from watchdog.events import (
|
|
|
15
15
|
)
|
|
16
16
|
from watchdog.observers import Observer
|
|
17
17
|
|
|
18
|
-
from tinybird.
|
|
18
|
+
from tinybird.datafile.common import Datafile, DatafileKind
|
|
19
19
|
from tinybird.tb.modules.datafile.fixture import FixtureExtension
|
|
20
20
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
21
21
|
from tinybird.tb.modules.project import Project
|
|
@@ -12,26 +12,31 @@ tinybird/syncasync.py,sha256=IPnOx6lMbf9SNddN1eBtssg8vCLHMt76SuZ6YNYm-Yk,27761
|
|
|
12
12
|
tinybird/tornado_template.py,sha256=jjNVDMnkYFWXflmT8KU_Ssbo5vR8KQq3EJMk5vYgXRw,41959
|
|
13
13
|
tinybird/ch_utils/constants.py,sha256=aYvg2C_WxYWsnqPdZB1ZFoIr8ZY-XjUXYyHKE9Ansj0,3890
|
|
14
14
|
tinybird/ch_utils/engine.py,sha256=X4tE9OrfaUy6kO9cqVEzyI9cDcmOF3IAssRRzsTsfEQ,40781
|
|
15
|
-
tinybird/
|
|
15
|
+
tinybird/datafile/common.py,sha256=JPhLqYfmGYCc5dln7zMbr4m2TvUwbqZTxmC_pF5BzJY,91534
|
|
16
|
+
tinybird/datafile/exceptions.py,sha256=8rw2umdZjtby85QbuRKFO5ETz_eRHwUY5l7eHsy1wnI,556
|
|
17
|
+
tinybird/datafile/parse_connection.py,sha256=tRyn2Rpr1TeWet5BXmMoQgaotbGdYep1qiTak_OqC5E,1825
|
|
18
|
+
tinybird/datafile/parse_datasource.py,sha256=ssW8QeFSgglVFi3sDZj_HgkJiTJ2069v2JgqnH3CkDE,1825
|
|
19
|
+
tinybird/datafile/parse_pipe.py,sha256=xf4m0Tw44QWJzHzAm7Z7FwUoUUtr7noMYjU1NiWnX0k,3880
|
|
20
|
+
tinybird/tb/__cli__.py,sha256=7SUurDL5cvd_jq8kgVKbNv0nYu14klnwH04iy8Jzih0,247
|
|
16
21
|
tinybird/tb/check_pypi.py,sha256=i3l2L8IajeB7sreikR7oPlYJki9MtS3c_M4crnmbByc,760
|
|
17
|
-
tinybird/tb/cli.py,sha256=
|
|
18
|
-
tinybird/tb/client.py,sha256=
|
|
22
|
+
tinybird/tb/cli.py,sha256=0xYk2Ip4vb3nNFbxfTdG3VoIgdRvUKVbUVU_mviErPA,1107
|
|
23
|
+
tinybird/tb/client.py,sha256=FKj61vY9STPW03kfVcxYuY1_csI-kP-mc1ERQfqJtg8,56505
|
|
19
24
|
tinybird/tb/config.py,sha256=jT9xndpeCY_g0HdB5qE2EquC0TFRRnkPnQFWZWd04jo,3998
|
|
20
|
-
tinybird/tb/modules/build.py,sha256=
|
|
25
|
+
tinybird/tb/modules/build.py,sha256=T36msoBK5g9AZlrJnFRPvlZbrdE265LY1q3Y4YqvS3w,20067
|
|
21
26
|
tinybird/tb/modules/cicd.py,sha256=Njb6eZOHHbUkoJJx6KoixO9PsfA_T-3Ybkya9-50Ca8,7328
|
|
22
27
|
tinybird/tb/modules/cli.py,sha256=k6Bp-lWC-ruMMB47lxwsinLQt4qJL_n84hjyxi9JYt4,15676
|
|
23
|
-
tinybird/tb/modules/common.py,sha256=
|
|
28
|
+
tinybird/tb/modules/common.py,sha256=nzAF52gkDPx1_LKg3l-j1Ko9Y1o_Wq9dYxxhu47bAeg,84221
|
|
24
29
|
tinybird/tb/modules/config.py,sha256=VnzYVUo4q1RBEEMMce4_OCrKp4erhgkRPHElydVlKj0,11488
|
|
25
|
-
tinybird/tb/modules/connection.py,sha256=
|
|
26
|
-
tinybird/tb/modules/copy.py,sha256=
|
|
30
|
+
tinybird/tb/modules/connection.py,sha256=rdEsdcP-AqyHiW3KNoETGPeTjk7Wt3It6z_SnmInGcc,18648
|
|
31
|
+
tinybird/tb/modules/copy.py,sha256=zHN1d5NA-MFsgbk2kKJq2P9qA8dNOnIsIa60QpVnSwc,4458
|
|
27
32
|
tinybird/tb/modules/create.py,sha256=sncG6iaeS_AApY1EmmfYEdj9B6-1CPZJzvTmfJQj_Rc,22112
|
|
28
|
-
tinybird/tb/modules/datasource.py,sha256=
|
|
29
|
-
tinybird/tb/modules/deployment.py,sha256=
|
|
33
|
+
tinybird/tb/modules/datasource.py,sha256=jpe5-C-rZ5Dnitwo_t84OPqS_bV44Sz1y1u85-2djnQ,39362
|
|
34
|
+
tinybird/tb/modules/deployment.py,sha256=ByXIgEvwxB49pJEKKj0EJIfORWyflCYr04k8961nBkA,28391
|
|
30
35
|
tinybird/tb/modules/deprecations.py,sha256=rrszC1f_JJeJ8mUxGoCxckQTJFBCR8wREf4XXXN-PRc,4507
|
|
31
36
|
tinybird/tb/modules/dev_server.py,sha256=57FCKuWpErwYUYgHspYDkLWEm9F4pbvVOtMrFXX1fVU,10129
|
|
32
|
-
tinybird/tb/modules/endpoint.py,sha256=
|
|
37
|
+
tinybird/tb/modules/endpoint.py,sha256=rC1CZiEZDMb5chByf4xZhv5PsfkoLeIVDScHQ-QcBsE,12072
|
|
33
38
|
tinybird/tb/modules/exceptions.py,sha256=5jK91w1LPmtqIUfDpHe_Op5OxGz8-p1BPgtLREMIni0,5217
|
|
34
|
-
tinybird/tb/modules/feedback_manager.py,sha256=
|
|
39
|
+
tinybird/tb/modules/feedback_manager.py,sha256=DL_nRFO6akpApNdbGnTmqikEM-gI_eUkyX_nJOGEOo8,77292
|
|
35
40
|
tinybird/tb/modules/info.py,sha256=NqSsoyzFqbtUEGH_tSowNOI_jSsNuixibln6-plsfOY,6810
|
|
36
41
|
tinybird/tb/modules/infra.py,sha256=fve30Gj3mG9zbquGxS2e4ipcOYOxviWQCpNFfEzJN_Q,33195
|
|
37
42
|
tinybird/tb/modules/job.py,sha256=AsUCRNzy7HG5oJ4fyk9NpIm5NtNJgBZSy8MtJdXBe5A,3167
|
|
@@ -41,36 +46,33 @@ tinybird/tb/modules/local.py,sha256=mLSgMMP3H1MdanVLsFZieeqOANSnctPLey3pJ_L1ZBI,
|
|
|
41
46
|
tinybird/tb/modules/local_common.py,sha256=8CSEVygFi0fIISatYxCStcHizugXCA9WNTLO_zDKmXw,17195
|
|
42
47
|
tinybird/tb/modules/login.py,sha256=qfY17J3FryTPl8A0ucQgxiyJ7jLy81qHdlHXgqohi0c,10170
|
|
43
48
|
tinybird/tb/modules/logout.py,sha256=sniI4JNxpTrVeRCp0oGJuQ3yRerG4hH5uz6oBmjv724,1009
|
|
44
|
-
tinybird/tb/modules/materialization.py,sha256=
|
|
49
|
+
tinybird/tb/modules/materialization.py,sha256=neugOziGfh50GSOgfZJX8giVPKgauoE313LUw6kXowo,5467
|
|
45
50
|
tinybird/tb/modules/mock.py,sha256=IyHweMUM6bUH8IhyiX2tTMpdVpTFUeAJ41lZ5P42-HQ,5303
|
|
46
51
|
tinybird/tb/modules/open.py,sha256=OuctINN77oexpSjth9uoIZPCelKO4Li-yyVxeSnk1io,1371
|
|
47
|
-
tinybird/tb/modules/pipe.py,sha256=
|
|
48
|
-
tinybird/tb/modules/project.py,sha256=
|
|
52
|
+
tinybird/tb/modules/pipe.py,sha256=ExDOk3ze76JacNEVrN4DbIopNvSurDCSR7QR9ii2xGQ,2421
|
|
53
|
+
tinybird/tb/modules/project.py,sha256=pOcvtgsR0ibPi0sNu-6GuAI4WS2DORRALezisjN3xY8,5662
|
|
49
54
|
tinybird/tb/modules/regions.py,sha256=QjsL5H6Kg-qr0aYVLrvb1STeJ5Sx_sjvbOYO0LrEGMk,166
|
|
50
55
|
tinybird/tb/modules/secret.py,sha256=jw1DIDKmS1L1U-y7LRYo65sVSGuRcpIHGo5CNiKHjo4,4945
|
|
51
56
|
tinybird/tb/modules/shell.py,sha256=Zd_4Ak_5tKVX-cw6B4ag36xZeEGHeh-jZpAsIXkoMoE,14116
|
|
57
|
+
tinybird/tb/modules/sink.py,sha256=bIjLjog4XH42yfp944cMnaE4il7Kl7Wn7F-nLKfH2Bc,3913
|
|
52
58
|
tinybird/tb/modules/table.py,sha256=4XrtjM-N0zfNtxVkbvLDQQazno1EPXnxTyo7llivfXk,11035
|
|
53
59
|
tinybird/tb/modules/telemetry.py,sha256=T9gtsQffWqG_4hRBaUJPzOfMkPwz7mH-R6Bn1XRYViA,11482
|
|
54
60
|
tinybird/tb/modules/test.py,sha256=XakpYi0Q2gGKItpPdtRVLKzQldkvCPqzPhwwbUxyrmc,13292
|
|
55
61
|
tinybird/tb/modules/token.py,sha256=2fmKwu10_M0pqs6YmJVeILR9ZQB0ejRAET86agASbKM,13488
|
|
56
|
-
tinybird/tb/modules/watch.py,sha256=
|
|
62
|
+
tinybird/tb/modules/watch.py,sha256=HhruZoUrehlxL_nFIK3BlpHp2uyzKAM9cmNXBCa4Zgs,8965
|
|
57
63
|
tinybird/tb/modules/workspace.py,sha256=WDi3Vu9t60b4Ht5vbPsakUErFmsECtFRcfXb1l300xc,11057
|
|
58
64
|
tinybird/tb/modules/workspace_members.py,sha256=RYLpyPM1ECCasHRg3uvpckzXplX0_KgNFsSPZn_i6qk,8744
|
|
59
|
-
tinybird/tb/modules/datafile/build.py,sha256=
|
|
65
|
+
tinybird/tb/modules/datafile/build.py,sha256=SinuhM61FKdEt0MTV_4qfJFQ78dYndcmWHf_LMGe7Z8,51351
|
|
60
66
|
tinybird/tb/modules/datafile/build_common.py,sha256=LU24kAQmxDJIyoIapDaYG-SU3P4FrMG9UBf8m9PgVSI,4565
|
|
61
|
-
tinybird/tb/modules/datafile/build_datasource.py,sha256=
|
|
62
|
-
tinybird/tb/modules/datafile/build_pipe.py,sha256=
|
|
63
|
-
tinybird/tb/modules/datafile/
|
|
64
|
-
tinybird/tb/modules/datafile/diff.py,sha256=MTmj53RYjER4neLgWVjabn-FKVFgh8h8uYiBo55lFQg,6757
|
|
65
|
-
tinybird/tb/modules/datafile/exceptions.py,sha256=8rw2umdZjtby85QbuRKFO5ETz_eRHwUY5l7eHsy1wnI,556
|
|
67
|
+
tinybird/tb/modules/datafile/build_datasource.py,sha256=1df45f4YmgiCxwr6_JbYVEJD9Sxp_Y9PfglQD09CIr0,17371
|
|
68
|
+
tinybird/tb/modules/datafile/build_pipe.py,sha256=Zc3e9Bw-2WX_6_9cMHFNa2ut9FUd1Yw8Yyj56CxdL1E,11374
|
|
69
|
+
tinybird/tb/modules/datafile/diff.py,sha256=SxJtZQ7Am1JGM-jmC1qEGmdCghz9s0RbWNwldUFsNnw,6746
|
|
66
70
|
tinybird/tb/modules/datafile/fixture.py,sha256=gftYWeweeQDFK3cHgUmSOfltNjZVOuMt8v7WTMLhGBw,1579
|
|
67
|
-
tinybird/tb/modules/datafile/format_common.py,sha256=
|
|
68
|
-
tinybird/tb/modules/datafile/format_datasource.py,sha256=
|
|
69
|
-
tinybird/tb/modules/datafile/format_pipe.py,sha256=
|
|
70
|
-
tinybird/tb/modules/datafile/
|
|
71
|
-
tinybird/tb/modules/datafile/
|
|
72
|
-
tinybird/tb/modules/datafile/pipe_checker.py,sha256=xv7vyjN5dPc2hcw9RnLBq2VkR4nte-8bhYDT10qceQY,24620
|
|
73
|
-
tinybird/tb/modules/datafile/playground.py,sha256=f2b3QCF_En116XV4QzEoriHroatQKHjQ8v0GoJn8bFY,56639
|
|
71
|
+
tinybird/tb/modules/datafile/format_common.py,sha256=5w6GX_8RDFueW9AtDfWpc1OicEu8wWdrjUBdCEidCQk,1951
|
|
72
|
+
tinybird/tb/modules/datafile/format_datasource.py,sha256=D2nZeofwcBV9h9SJsdSIYxUXZiubh7jbqixHSgQ2Uk4,6168
|
|
73
|
+
tinybird/tb/modules/datafile/format_pipe.py,sha256=ncehfeIcGlvW3tnXy9hpFzi7J7X-9zEXMXpWA6dzX5k,7414
|
|
74
|
+
tinybird/tb/modules/datafile/pipe_checker.py,sha256=dxsCQoA6ruxg1fvF6sMLFowpjaqws8lUQcM7XyhgZPE,24609
|
|
75
|
+
tinybird/tb/modules/datafile/playground.py,sha256=qRGahuXE7wynqcbAZLufDcHR1Yyr2ob3bg75_u2qxzc,56595
|
|
74
76
|
tinybird/tb/modules/datafile/pull.py,sha256=CP6-TVZ9ErrEOAFajn9HSEdq-GgYnOPHEIUAuReQGaM,4508
|
|
75
77
|
tinybird/tb/modules/tinyunit/tinyunit.py,sha256=qc3OHiXYSOv3TQCFRYrMnR47xJbUH0LnV4FBcBtWN1s,11713
|
|
76
78
|
tinybird/tb/modules/tinyunit/tinyunit_lib.py,sha256=hGh1ZaXC1af7rKnX7222urkj0QJMhMWclqMy59dOqwE,1922
|
|
@@ -80,8 +82,8 @@ tinybird/tb_cli_modules/config.py,sha256=IsgdtFRnUrkY8-Zo32lmk6O7u3bHie1QCxLwgp4
|
|
|
80
82
|
tinybird/tb_cli_modules/exceptions.py,sha256=pmucP4kTF4irIt7dXiG-FcnI-o3mvDusPmch1L8RCWk,3367
|
|
81
83
|
tinybird/tb_cli_modules/regions.py,sha256=QjsL5H6Kg-qr0aYVLrvb1STeJ5Sx_sjvbOYO0LrEGMk,166
|
|
82
84
|
tinybird/tb_cli_modules/telemetry.py,sha256=Hh2Io8ZPROSunbOLuMvuIFU4TqwWPmQTqal4WS09K1A,10449
|
|
83
|
-
tinybird-0.0.1.
|
|
84
|
-
tinybird-0.0.1.
|
|
85
|
-
tinybird-0.0.1.
|
|
86
|
-
tinybird-0.0.1.
|
|
87
|
-
tinybird-0.0.1.
|
|
85
|
+
tinybird-0.0.1.dev215.dist-info/METADATA,sha256=zGTBhqtryJztGGmmcNeOBfOqUV49VhZQgyA3RxGnmog,1682
|
|
86
|
+
tinybird-0.0.1.dev215.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
87
|
+
tinybird-0.0.1.dev215.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
|
|
88
|
+
tinybird-0.0.1.dev215.dist-info/top_level.txt,sha256=VqqqEmkAy7UNaD8-V51FCoMMWXjLUlR0IstvK7tJYVY,54
|
|
89
|
+
tinybird-0.0.1.dev215.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|