tinybird 0.0.1.dev293__py3-none-any.whl → 0.0.1.dev295__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/ch_utils/constants.py +1 -0
- tinybird/tb/__cli__.py +2 -2
- tinybird/tb/modules/agent/agent.py +14 -9
- tinybird/tb/modules/build.py +9 -147
- tinybird/tb/modules/build_common.py +140 -1
- tinybird/tb/modules/datasource.py +1 -1
- tinybird/tb/modules/local_common.py +14 -2
- tinybird/tb/modules/test.py +7 -4
- tinybird/tb/modules/test_common.py +19 -10
- tinybird/tb/modules/watch.py +5 -3
- {tinybird-0.0.1.dev293.dist-info → tinybird-0.0.1.dev295.dist-info}/METADATA +1 -1
- {tinybird-0.0.1.dev293.dist-info → tinybird-0.0.1.dev295.dist-info}/RECORD +15 -15
- {tinybird-0.0.1.dev293.dist-info → tinybird-0.0.1.dev295.dist-info}/WHEEL +0 -0
- {tinybird-0.0.1.dev293.dist-info → tinybird-0.0.1.dev295.dist-info}/entry_points.txt +0 -0
- {tinybird-0.0.1.dev293.dist-info → tinybird-0.0.1.dev295.dist-info}/top_level.txt +0 -0
tinybird/ch_utils/constants.py
CHANGED
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.dev295'
|
|
8
|
+
__revision__ = '6b3c823'
|
|
@@ -373,7 +373,7 @@ class TinybirdAgent:
|
|
|
373
373
|
execute_query_local=partial(execute_query_local, config=config),
|
|
374
374
|
request_endpoint_cloud=partial(request_endpoint_cloud, config=config),
|
|
375
375
|
request_endpoint_local=partial(request_endpoint_local, config=config),
|
|
376
|
-
build_project_test=partial(build_project_test, project=project, client=test_client),
|
|
376
|
+
build_project_test=partial(build_project_test, project=project, client=test_client, config=config),
|
|
377
377
|
get_pipe_data_test=partial(get_pipe_data_test, client=test_client),
|
|
378
378
|
get_datasource_datafile_cloud=partial(get_datasource_datafile_cloud, config=config),
|
|
379
379
|
get_datasource_datafile_local=partial(get_datasource_datafile_local, config=config),
|
|
@@ -382,7 +382,7 @@ class TinybirdAgent:
|
|
|
382
382
|
get_connection_datafile_cloud=partial(get_connection_datafile_cloud, config=config),
|
|
383
383
|
get_connection_datafile_local=partial(get_connection_datafile_local, config=config),
|
|
384
384
|
get_project_files=project.get_project_files,
|
|
385
|
-
run_tests=partial(run_tests, project=project, client=test_client),
|
|
385
|
+
run_tests=partial(run_tests, project=project, client=test_client, config=config),
|
|
386
386
|
folder=folder,
|
|
387
387
|
thinking_animation=self.thinking_animation,
|
|
388
388
|
workspace_id=self.workspace_id,
|
|
@@ -482,9 +482,9 @@ def run_agent(
|
|
|
482
482
|
if yes:
|
|
483
483
|
update_cli()
|
|
484
484
|
click.echo(FeedbackManager.highlight(message="» Initializing Tinybird Code..."))
|
|
485
|
-
token = config.get("token",
|
|
486
|
-
host = config.get("host",
|
|
487
|
-
user_token = config.get("user_token",
|
|
485
|
+
token = config.get("token", "")
|
|
486
|
+
host = config.get("host", "")
|
|
487
|
+
user_token = config.get("user_token", "")
|
|
488
488
|
workspace_id = config.get("id", "")
|
|
489
489
|
workspace_name = config.get("name", "")
|
|
490
490
|
try:
|
|
@@ -501,8 +501,8 @@ def run_agent(
|
|
|
501
501
|
login(host, auth_host="https://cloud.tinybird.co", workspace=None, interactive=False, method="browser")
|
|
502
502
|
cli_config = CLIConfig.get_project_config()
|
|
503
503
|
config = {**config, **cli_config.to_dict()}
|
|
504
|
-
token = cli_config.get_token()
|
|
505
|
-
user_token = cli_config.get_user_token()
|
|
504
|
+
token = cli_config.get_token() or ""
|
|
505
|
+
user_token = cli_config.get_user_token() or ""
|
|
506
506
|
host = cli_config.get_host()
|
|
507
507
|
workspace_id = cli_config.get("id", "")
|
|
508
508
|
workspace_name = cli_config.get("name", "")
|
|
@@ -652,6 +652,7 @@ def build_project(
|
|
|
652
652
|
build_error = build_process(
|
|
653
653
|
project=project,
|
|
654
654
|
tb_client=client,
|
|
655
|
+
config=config,
|
|
655
656
|
watch=False,
|
|
656
657
|
silent=silent,
|
|
657
658
|
exit_on_error=False,
|
|
@@ -664,11 +665,13 @@ def build_project(
|
|
|
664
665
|
def build_project_test(
|
|
665
666
|
client: TinyB,
|
|
666
667
|
project: Project,
|
|
668
|
+
config: dict[str, Any],
|
|
667
669
|
silent: bool = False,
|
|
668
670
|
) -> None:
|
|
669
671
|
build_error = build_process(
|
|
670
672
|
project=project,
|
|
671
673
|
tb_client=client,
|
|
674
|
+
config=config,
|
|
672
675
|
watch=False,
|
|
673
676
|
silent=silent,
|
|
674
677
|
exit_on_error=False,
|
|
@@ -821,9 +824,11 @@ def get_connection_datafile_local(config: dict[str, Any], connection_name: str)
|
|
|
821
824
|
return "Connection not found"
|
|
822
825
|
|
|
823
826
|
|
|
824
|
-
def run_tests(
|
|
827
|
+
def run_tests(
|
|
828
|
+
client: TinyB, project: Project, config: dict[str, Any], pipe_name: Optional[str] = None
|
|
829
|
+
) -> Optional[str]:
|
|
825
830
|
try:
|
|
826
|
-
return run_tests_common(name=(pipe_name,) if pipe_name else (), project=project, client=client)
|
|
831
|
+
return run_tests_common(name=(pipe_name,) if pipe_name else (), project=project, client=client, config=config)
|
|
827
832
|
except SystemExit as e:
|
|
828
833
|
raise Exception(e.args[0])
|
|
829
834
|
|
tinybird/tb/modules/build.py
CHANGED
|
@@ -3,7 +3,7 @@ import time
|
|
|
3
3
|
from copy import deepcopy
|
|
4
4
|
from functools import partial
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from typing import Any, Callable, Dict, List
|
|
6
|
+
from typing import Any, Callable, Dict, List
|
|
7
7
|
from urllib.parse import urlencode
|
|
8
8
|
|
|
9
9
|
import click
|
|
@@ -19,7 +19,6 @@ from tinybird.tb.modules.config import CLIConfig
|
|
|
19
19
|
from tinybird.tb.modules.datafile.playground import folder_playground
|
|
20
20
|
from tinybird.tb.modules.dev_server import BuildStatus, start_server
|
|
21
21
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
22
|
-
from tinybird.tb.modules.local_common import get_local_tokens
|
|
23
22
|
from tinybird.tb.modules.project import Project
|
|
24
23
|
from tinybird.tb.modules.shell import Shell, print_table_formatted
|
|
25
24
|
from tinybird.tb.modules.watch import watch_files, watch_project
|
|
@@ -48,19 +47,14 @@ def build(ctx: click.Context, watch: bool) -> None:
|
|
|
48
47
|
)
|
|
49
48
|
)
|
|
50
49
|
|
|
51
|
-
# First, build vendored workspaces if present
|
|
52
|
-
|
|
53
|
-
build_vendored_workspaces(project=project, tb_client=tb_client, config=config)
|
|
54
|
-
# Ensure SHARED_WITH workspaces exist before building and sharing
|
|
55
|
-
build_shared_with_workspaces(project=project, tb_client=tb_client, config=config)
|
|
56
|
-
|
|
57
50
|
click.echo(FeedbackManager.highlight_building_project())
|
|
58
|
-
process(project=project, tb_client=tb_client, watch=False)
|
|
51
|
+
process(project=project, tb_client=tb_client, watch=False, config=config)
|
|
59
52
|
if watch:
|
|
60
53
|
run_watch(
|
|
61
54
|
project=project,
|
|
62
55
|
tb_client=tb_client,
|
|
63
|
-
|
|
56
|
+
config=config,
|
|
57
|
+
process=partial(process, project=project, tb_client=tb_client, watch=True, config=config),
|
|
64
58
|
)
|
|
65
59
|
|
|
66
60
|
|
|
@@ -83,26 +77,22 @@ def dev(ctx: click.Context, data_origin: str, ui: bool) -> None:
|
|
|
83
77
|
# Wait for the server to start
|
|
84
78
|
time.sleep(0.5)
|
|
85
79
|
|
|
86
|
-
# Build vendored workspaces before starting dev build/watch
|
|
87
|
-
build_vendored_workspaces(project=project, tb_client=tb_client, config=config)
|
|
88
|
-
# Ensure SHARED_WITH workspaces exist before dev build/watch
|
|
89
|
-
build_shared_with_workspaces(project=project, tb_client=tb_client, config=config)
|
|
90
|
-
|
|
91
80
|
click.echo(FeedbackManager.highlight_building_project())
|
|
92
|
-
process(project=project, tb_client=tb_client, watch=True, build_status=build_status)
|
|
81
|
+
process(project=project, tb_client=tb_client, watch=True, config=config, build_status=build_status)
|
|
93
82
|
run_watch(
|
|
94
83
|
project=project,
|
|
95
84
|
tb_client=tb_client,
|
|
96
|
-
|
|
85
|
+
config=config,
|
|
86
|
+
process=partial(process, project=project, tb_client=tb_client, build_status=build_status, config=config),
|
|
97
87
|
)
|
|
98
88
|
|
|
99
89
|
|
|
100
|
-
def run_watch(project: Project, tb_client: TinyB, process: Callable) -> None:
|
|
90
|
+
def run_watch(project: Project, tb_client: TinyB, process: Callable, config: dict[str, Any]) -> None:
|
|
101
91
|
shell = Shell(project=project, tb_client=tb_client, playground=False)
|
|
102
92
|
click.echo(FeedbackManager.gray(message="\nWatching for changes..."))
|
|
103
93
|
watcher_thread = threading.Thread(
|
|
104
94
|
target=watch_project,
|
|
105
|
-
args=(shell, process, project),
|
|
95
|
+
args=(shell, process, project, config),
|
|
106
96
|
daemon=True,
|
|
107
97
|
)
|
|
108
98
|
watcher_thread.start()
|
|
@@ -141,134 +131,6 @@ def check_filenames(filenames: List[str]):
|
|
|
141
131
|
parser(filename)
|
|
142
132
|
|
|
143
133
|
|
|
144
|
-
def find_workspace_or_create(user_client: TinyB, workspace_name: str) -> Optional[str]:
|
|
145
|
-
# Get a client scoped to the vendored workspace using the user token
|
|
146
|
-
ws_token = None
|
|
147
|
-
org_id = None
|
|
148
|
-
try:
|
|
149
|
-
# Fetch org id and workspaces with tokens
|
|
150
|
-
info = user_client.user_workspaces_with_organization(version="v1")
|
|
151
|
-
org_id = info.get("organization_id")
|
|
152
|
-
workspaces = info.get("workspaces", [])
|
|
153
|
-
found = next((w for w in workspaces if w.get("name") == workspace_name), None)
|
|
154
|
-
if found:
|
|
155
|
-
ws_token = found.get("token")
|
|
156
|
-
# If still not found, try the generic listing
|
|
157
|
-
if not ws_token:
|
|
158
|
-
workspaces_full = user_client.user_workspaces_and_branches(version="v1")
|
|
159
|
-
created_ws = next(
|
|
160
|
-
(w for w in workspaces_full.get("workspaces", []) if w.get("name") == workspace_name), None
|
|
161
|
-
)
|
|
162
|
-
if created_ws:
|
|
163
|
-
ws_token = created_ws.get("token")
|
|
164
|
-
except Exception:
|
|
165
|
-
ws_token = None
|
|
166
|
-
|
|
167
|
-
# If workspace doesn't exist, try to create it and fetch its token
|
|
168
|
-
if not ws_token:
|
|
169
|
-
try:
|
|
170
|
-
user_client.create_workspace(workspace_name, assign_to_organization_id=org_id, version="v1")
|
|
171
|
-
# Fetch token for newly created workspace
|
|
172
|
-
info_after = user_client.user_workspaces_and_branches(version="v1")
|
|
173
|
-
created = next((w for w in info_after.get("workspaces", []) if w.get("name") == workspace_name), None)
|
|
174
|
-
ws_token = created.get("token") if created else None
|
|
175
|
-
except Exception as e:
|
|
176
|
-
click.echo(
|
|
177
|
-
FeedbackManager.warning(
|
|
178
|
-
message=(f"Skipping vendored workspace '{workspace_name}': unable to create or resolve token ({e})")
|
|
179
|
-
)
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
return ws_token
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
def build_vendored_workspaces(project: Project, tb_client: TinyB, config: Dict[str, Any]) -> None:
|
|
186
|
-
"""Build each vendored workspace under project.vendor_path if present.
|
|
187
|
-
|
|
188
|
-
Directory structure expected: vendor/<workspace_name>/<data_project_inside>
|
|
189
|
-
Each top-level directory under vendor is treated as a separate workspace
|
|
190
|
-
whose project files will be built using that workspace's token.
|
|
191
|
-
"""
|
|
192
|
-
try:
|
|
193
|
-
vendor_root = Path(project.vendor_path)
|
|
194
|
-
|
|
195
|
-
if not vendor_root.exists() or not vendor_root.is_dir():
|
|
196
|
-
return
|
|
197
|
-
|
|
198
|
-
tokens = get_local_tokens()
|
|
199
|
-
user_token = tokens["user_token"]
|
|
200
|
-
user_client = deepcopy(tb_client)
|
|
201
|
-
user_client.token = user_token
|
|
202
|
-
|
|
203
|
-
# Iterate over vendored workspace folders
|
|
204
|
-
for ws_dir in sorted([p for p in vendor_root.iterdir() if p.is_dir()]):
|
|
205
|
-
workspace_name = ws_dir.name
|
|
206
|
-
ws_token = find_workspace_or_create(user_client, workspace_name)
|
|
207
|
-
|
|
208
|
-
if not ws_token:
|
|
209
|
-
click.echo(
|
|
210
|
-
FeedbackManager.warning(
|
|
211
|
-
message=f"Skipping vendored workspace '{workspace_name}': could not resolve token after creation"
|
|
212
|
-
)
|
|
213
|
-
)
|
|
214
|
-
continue
|
|
215
|
-
|
|
216
|
-
# Build using a client scoped to the vendor workspace token
|
|
217
|
-
vendor_client = deepcopy(tb_client)
|
|
218
|
-
vendor_client.token = ws_token
|
|
219
|
-
vendor_project = Project(folder=str(ws_dir), workspace_name=workspace_name, max_depth=project.max_depth)
|
|
220
|
-
|
|
221
|
-
# Do not exit on error to allow main project to continue
|
|
222
|
-
process(
|
|
223
|
-
project=vendor_project,
|
|
224
|
-
tb_client=vendor_client,
|
|
225
|
-
watch=False,
|
|
226
|
-
silent=False,
|
|
227
|
-
exit_on_error=True,
|
|
228
|
-
load_fixtures=True,
|
|
229
|
-
)
|
|
230
|
-
except Exception as e:
|
|
231
|
-
# Never break the main build due to vendored build errors
|
|
232
|
-
click.echo(FeedbackManager.error_exception(error=e))
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
def build_shared_with_workspaces(project: Project, tb_client: TinyB, config: Dict[str, Any]) -> None:
|
|
236
|
-
"""Scan project for .datasource files and ensure SHARED_WITH workspaces exist."""
|
|
237
|
-
|
|
238
|
-
try:
|
|
239
|
-
# Gather SHARED_WITH workspace names from all .datasource files
|
|
240
|
-
datasource_files = project.get_datasource_files()
|
|
241
|
-
shared_ws_names = set()
|
|
242
|
-
|
|
243
|
-
for filename in datasource_files:
|
|
244
|
-
try:
|
|
245
|
-
doc = parse_datasource(filename).datafile
|
|
246
|
-
for ws_name in doc.shared_with or []:
|
|
247
|
-
shared_ws_names.add(ws_name)
|
|
248
|
-
except Exception:
|
|
249
|
-
# Ignore parse errors here; they'll be handled during the main process()
|
|
250
|
-
continue
|
|
251
|
-
|
|
252
|
-
if not shared_ws_names:
|
|
253
|
-
return
|
|
254
|
-
|
|
255
|
-
# Need a user token to list/create workspaces
|
|
256
|
-
tokens = get_local_tokens()
|
|
257
|
-
user_token = tokens.get("user_token")
|
|
258
|
-
if not user_token:
|
|
259
|
-
click.echo(FeedbackManager.info_skipping_shared_with_entry())
|
|
260
|
-
return
|
|
261
|
-
|
|
262
|
-
user_client = deepcopy(tb_client)
|
|
263
|
-
user_client.token = user_token
|
|
264
|
-
|
|
265
|
-
# Ensure each SHARED_WITH workspace exists
|
|
266
|
-
for ws_name in sorted(shared_ws_names):
|
|
267
|
-
find_workspace_or_create(user_client, ws_name)
|
|
268
|
-
except Exception as e:
|
|
269
|
-
click.echo(FeedbackManager.error_exception(error=e))
|
|
270
|
-
|
|
271
|
-
|
|
272
134
|
def dev_cloud(
|
|
273
135
|
ctx: click.Context,
|
|
274
136
|
) -> None:
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
3
|
import time
|
|
4
|
+
from copy import deepcopy
|
|
4
5
|
from pathlib import Path
|
|
5
|
-
from typing import Optional
|
|
6
|
+
from typing import Any, Optional
|
|
6
7
|
from urllib.parse import urlencode, urljoin
|
|
7
8
|
|
|
8
9
|
import click
|
|
9
10
|
import requests
|
|
10
11
|
|
|
12
|
+
from tinybird.datafile.parse_datasource import parse_datasource
|
|
11
13
|
from tinybird.tb.client import TinyB
|
|
12
14
|
from tinybird.tb.modules.common import push_data, sys_exit
|
|
13
15
|
from tinybird.tb.modules.datafile.fixture import FixtureExtension, get_fixture_dir, persist_fixture
|
|
14
16
|
from tinybird.tb.modules.dev_server import BuildStatus
|
|
15
17
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
18
|
+
from tinybird.tb.modules.local_common import get_local_tokens
|
|
16
19
|
from tinybird.tb.modules.project import Project
|
|
17
20
|
from tinybird.tb.modules.shell import print_table_formatted
|
|
18
21
|
|
|
@@ -21,6 +24,7 @@ def process(
|
|
|
21
24
|
project: Project,
|
|
22
25
|
tb_client: TinyB,
|
|
23
26
|
watch: bool,
|
|
27
|
+
config: dict[str, Any],
|
|
24
28
|
file_changed: Optional[str] = None,
|
|
25
29
|
diff: Optional[str] = None,
|
|
26
30
|
silent: bool = False,
|
|
@@ -29,6 +33,12 @@ def process(
|
|
|
29
33
|
load_fixtures: bool = True,
|
|
30
34
|
) -> Optional[str]:
|
|
31
35
|
time_start = time.time()
|
|
36
|
+
|
|
37
|
+
# Build vendored workspaces before build
|
|
38
|
+
build_vendored_workspaces(project=project, tb_client=tb_client, config=config)
|
|
39
|
+
# Ensure SHARED_WITH workspaces exist before build
|
|
40
|
+
build_shared_with_workspaces(project=project, tb_client=tb_client, config=config)
|
|
41
|
+
|
|
32
42
|
build_failed = False
|
|
33
43
|
build_error: Optional[str] = None
|
|
34
44
|
build_result: Optional[bool] = None
|
|
@@ -320,3 +330,132 @@ def echo_changes(project: Project, changes: list[str], extension: str, status: s
|
|
|
320
330
|
if path_str:
|
|
321
331
|
path_str = path_str.replace(f"{project.folder}/", "")
|
|
322
332
|
click.echo(FeedbackManager.info(message=f"✓ {path_str} {status}"))
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def find_workspace_or_create(user_client: TinyB, workspace_name: str) -> Optional[str]:
|
|
336
|
+
# Get a client scoped to the vendored workspace using the user token
|
|
337
|
+
ws_token = None
|
|
338
|
+
org_id = None
|
|
339
|
+
try:
|
|
340
|
+
# Fetch org id and workspaces with tokens
|
|
341
|
+
info = user_client.user_workspaces_with_organization(version="v1")
|
|
342
|
+
org_id = info.get("organization_id")
|
|
343
|
+
workspaces = info.get("workspaces", [])
|
|
344
|
+
found = next((w for w in workspaces if w.get("name") == workspace_name), None)
|
|
345
|
+
if found:
|
|
346
|
+
ws_token = found.get("token")
|
|
347
|
+
# If still not found, try the generic listing
|
|
348
|
+
if not ws_token:
|
|
349
|
+
workspaces_full = user_client.user_workspaces_and_branches(version="v1")
|
|
350
|
+
created_ws = next(
|
|
351
|
+
(w for w in workspaces_full.get("workspaces", []) if w.get("name") == workspace_name), None
|
|
352
|
+
)
|
|
353
|
+
if created_ws:
|
|
354
|
+
ws_token = created_ws.get("token")
|
|
355
|
+
except Exception:
|
|
356
|
+
ws_token = None
|
|
357
|
+
|
|
358
|
+
# If workspace doesn't exist, try to create it and fetch its token
|
|
359
|
+
if not ws_token:
|
|
360
|
+
try:
|
|
361
|
+
user_client.create_workspace(workspace_name, assign_to_organization_id=org_id, version="v1")
|
|
362
|
+
# Fetch token for newly created workspace
|
|
363
|
+
info_after = user_client.user_workspaces_and_branches(version="v1")
|
|
364
|
+
created = next((w for w in info_after.get("workspaces", []) if w.get("name") == workspace_name), None)
|
|
365
|
+
ws_token = created.get("token") if created else None
|
|
366
|
+
except Exception as e:
|
|
367
|
+
click.echo(
|
|
368
|
+
FeedbackManager.warning(
|
|
369
|
+
message=(f"Skipping vendored workspace '{workspace_name}': unable to create or resolve token ({e})")
|
|
370
|
+
)
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
return ws_token
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def build_vendored_workspaces(project: Project, tb_client: TinyB, config: dict[str, Any]) -> None:
|
|
377
|
+
"""Build each vendored workspace under project.vendor_path if present.
|
|
378
|
+
|
|
379
|
+
Directory structure expected: vendor/<workspace_name>/<data_project_inside>
|
|
380
|
+
Each top-level directory under vendor is treated as a separate workspace
|
|
381
|
+
whose project files will be built using that workspace's token.
|
|
382
|
+
"""
|
|
383
|
+
try:
|
|
384
|
+
vendor_root = Path(project.vendor_path)
|
|
385
|
+
|
|
386
|
+
if not vendor_root.exists() or not vendor_root.is_dir():
|
|
387
|
+
return
|
|
388
|
+
|
|
389
|
+
tokens = get_local_tokens()
|
|
390
|
+
user_token = tokens["user_token"]
|
|
391
|
+
user_client = deepcopy(tb_client)
|
|
392
|
+
user_client.token = user_token
|
|
393
|
+
|
|
394
|
+
# Iterate over vendored workspace folders
|
|
395
|
+
for ws_dir in sorted([p for p in vendor_root.iterdir() if p.is_dir()]):
|
|
396
|
+
workspace_name = ws_dir.name
|
|
397
|
+
ws_token = find_workspace_or_create(user_client, workspace_name)
|
|
398
|
+
|
|
399
|
+
if not ws_token:
|
|
400
|
+
click.echo(
|
|
401
|
+
FeedbackManager.warning(
|
|
402
|
+
message=f"Skipping vendored workspace '{workspace_name}': could not resolve token after creation"
|
|
403
|
+
)
|
|
404
|
+
)
|
|
405
|
+
continue
|
|
406
|
+
|
|
407
|
+
# Build using a client scoped to the vendor workspace token
|
|
408
|
+
vendor_client = deepcopy(tb_client)
|
|
409
|
+
vendor_client.token = ws_token
|
|
410
|
+
vendor_project = Project(folder=str(ws_dir), workspace_name=workspace_name, max_depth=project.max_depth)
|
|
411
|
+
|
|
412
|
+
# Do not exit on error to allow main project to continue
|
|
413
|
+
process(
|
|
414
|
+
project=vendor_project,
|
|
415
|
+
tb_client=vendor_client,
|
|
416
|
+
watch=False,
|
|
417
|
+
silent=True,
|
|
418
|
+
exit_on_error=True,
|
|
419
|
+
load_fixtures=True,
|
|
420
|
+
config=config,
|
|
421
|
+
)
|
|
422
|
+
except Exception as e:
|
|
423
|
+
# Never break the main build due to vendored build errors
|
|
424
|
+
click.echo(FeedbackManager.error_exception(error=e))
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def build_shared_with_workspaces(project: Project, tb_client: TinyB, config: dict[str, Any]) -> None:
|
|
428
|
+
"""Scan project for .datasource files and ensure SHARED_WITH workspaces exist."""
|
|
429
|
+
|
|
430
|
+
try:
|
|
431
|
+
# Gather SHARED_WITH workspace names from all .datasource files
|
|
432
|
+
datasource_files = project.get_datasource_files()
|
|
433
|
+
shared_ws_names = set()
|
|
434
|
+
|
|
435
|
+
for filename in datasource_files:
|
|
436
|
+
try:
|
|
437
|
+
doc = parse_datasource(filename).datafile
|
|
438
|
+
for ws_name in doc.shared_with or []:
|
|
439
|
+
shared_ws_names.add(ws_name)
|
|
440
|
+
except Exception:
|
|
441
|
+
# Ignore parse errors here; they'll be handled during the main process()
|
|
442
|
+
continue
|
|
443
|
+
|
|
444
|
+
if not shared_ws_names:
|
|
445
|
+
return
|
|
446
|
+
|
|
447
|
+
# Need a user token to list/create workspaces
|
|
448
|
+
tokens = get_local_tokens()
|
|
449
|
+
user_token = tokens.get("user_token")
|
|
450
|
+
if not user_token:
|
|
451
|
+
click.echo(FeedbackManager.info_skipping_shared_with_entry())
|
|
452
|
+
return
|
|
453
|
+
|
|
454
|
+
user_client = deepcopy(tb_client)
|
|
455
|
+
user_client.token = user_token
|
|
456
|
+
|
|
457
|
+
# Ensure each SHARED_WITH workspace exists
|
|
458
|
+
for ws_name in sorted(shared_ws_names):
|
|
459
|
+
find_workspace_or_create(user_client, ws_name)
|
|
460
|
+
except Exception as e:
|
|
461
|
+
click.echo(FeedbackManager.error_exception(error=e))
|
|
@@ -931,7 +931,7 @@ def datasource_create(
|
|
|
931
931
|
default=True,
|
|
932
932
|
):
|
|
933
933
|
click.echo(FeedbackManager.gray(message="» Building project..."))
|
|
934
|
-
build_project(project=project, tb_client=client, watch=False, silent=True)
|
|
934
|
+
build_project(project=project, tb_client=client, watch=False, config=config, silent=True)
|
|
935
935
|
click.echo(FeedbackManager.success(message="✓ Build completed!"))
|
|
936
936
|
connections = client.connections("kafka")
|
|
937
937
|
|
|
@@ -5,6 +5,7 @@ import os
|
|
|
5
5
|
import re
|
|
6
6
|
import subprocess
|
|
7
7
|
import time
|
|
8
|
+
import uuid
|
|
8
9
|
from typing import Any, Dict, Optional
|
|
9
10
|
|
|
10
11
|
import boto3
|
|
@@ -56,6 +57,17 @@ def get_tinybird_local_config(config_obj: Dict[str, Any], test: bool = False, si
|
|
|
56
57
|
if path:
|
|
57
58
|
user_client = config.get_client(host=TB_LOCAL_ADDRESS, token=user_token)
|
|
58
59
|
if test:
|
|
60
|
+
# delete any Tinybird_Local_Test_* workspace
|
|
61
|
+
user_workspaces = requests.get(
|
|
62
|
+
f"{TB_LOCAL_ADDRESS}/v1/user/workspaces?with_organization=true&token={admin_token}"
|
|
63
|
+
).json()
|
|
64
|
+
local_workspaces = user_workspaces.get("workspaces", [])
|
|
65
|
+
for ws in local_workspaces:
|
|
66
|
+
if ws["name"].startswith("Tinybird_Local_Test_"):
|
|
67
|
+
requests.delete(
|
|
68
|
+
f"{TB_LOCAL_ADDRESS}/v1/workspaces/{ws['id']}?token={user_token}&hard_delete_confirmation=yes"
|
|
69
|
+
)
|
|
70
|
+
|
|
59
71
|
ws_name = get_test_workspace_name(path)
|
|
60
72
|
else:
|
|
61
73
|
ws_name = config.get("name") or config_obj.get("name") or get_build_workspace_name(path)
|
|
@@ -104,8 +116,8 @@ def get_build_workspace_name(path: str) -> str:
|
|
|
104
116
|
|
|
105
117
|
|
|
106
118
|
def get_test_workspace_name(path: str) -> str:
|
|
107
|
-
|
|
108
|
-
return f"Tinybird_Local_Test_{
|
|
119
|
+
random_folder_suffix = str(uuid.uuid4()).replace("-", "_")
|
|
120
|
+
return f"Tinybird_Local_Test_{random_folder_suffix}"
|
|
109
121
|
|
|
110
122
|
|
|
111
123
|
def get_local_tokens() -> Dict[str, str]:
|
tinybird/tb/modules/test.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# - If it makes sense and only when strictly necessary, you can create utility functions in this file.
|
|
4
4
|
# - But please, **do not** interleave utility functions and command definitions.
|
|
5
5
|
|
|
6
|
-
from typing import Tuple
|
|
6
|
+
from typing import Any, Tuple
|
|
7
7
|
|
|
8
8
|
import click
|
|
9
9
|
|
|
@@ -34,7 +34,8 @@ def test_create(ctx: click.Context, name_or_filename: str, prompt: str) -> None:
|
|
|
34
34
|
"""
|
|
35
35
|
project: Project = ctx.ensure_object(dict)["project"]
|
|
36
36
|
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
37
|
-
|
|
37
|
+
config: dict[str, Any] = ctx.ensure_object(dict)["config"]
|
|
38
|
+
create_test(name_or_filename, prompt, project, client, config=config)
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
@test.command(
|
|
@@ -46,7 +47,8 @@ def test_create(ctx: click.Context, name_or_filename: str, prompt: str) -> None:
|
|
|
46
47
|
def test_update(ctx: click.Context, pipe: str) -> None:
|
|
47
48
|
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
48
49
|
project: Project = ctx.ensure_object(dict)["project"]
|
|
49
|
-
|
|
50
|
+
config: dict[str, Any] = ctx.ensure_object(dict)["config"]
|
|
51
|
+
update_test(pipe, project, client, config=config)
|
|
50
52
|
|
|
51
53
|
|
|
52
54
|
@test.command(
|
|
@@ -58,4 +60,5 @@ def test_update(ctx: click.Context, pipe: str) -> None:
|
|
|
58
60
|
def run_tests_command(ctx: click.Context, name: Tuple[str, ...]) -> None:
|
|
59
61
|
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
60
62
|
project: Project = ctx.ensure_object(dict)["project"]
|
|
61
|
-
|
|
63
|
+
config: dict[str, Any] = ctx.ensure_object(dict)["config"]
|
|
64
|
+
run_tests(name, project, client, config=config)
|
|
@@ -18,7 +18,6 @@ from tinybird.prompts import test_create_prompt
|
|
|
18
18
|
from tinybird.tb.client import TinyB
|
|
19
19
|
from tinybird.tb.modules.build_common import process as build_project
|
|
20
20
|
from tinybird.tb.modules.common import sys_exit
|
|
21
|
-
from tinybird.tb.modules.config import CLIConfig
|
|
22
21
|
from tinybird.tb.modules.exceptions import CLITestException
|
|
23
22
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
24
23
|
from tinybird.tb.modules.llm import LLM
|
|
@@ -55,7 +54,7 @@ def generate_test_file(pipe_name: str, tests: List[Dict[str, Any]], folder: Opti
|
|
|
55
54
|
|
|
56
55
|
|
|
57
56
|
def create_test(
|
|
58
|
-
name_or_filename: str, prompt: str, project: Project, client: TinyB, preview: bool = False
|
|
57
|
+
name_or_filename: str, prompt: str, project: Project, client: TinyB, config: dict[str, Any], preview: bool = False
|
|
59
58
|
) -> list[dict[str, Any]]:
|
|
60
59
|
"""
|
|
61
60
|
Create a test for an existing pipe
|
|
@@ -64,11 +63,12 @@ def create_test(
|
|
|
64
63
|
|
|
65
64
|
try:
|
|
66
65
|
click.echo(FeedbackManager.highlight(message="\n» Building test environment"))
|
|
67
|
-
build_error = build_project(
|
|
66
|
+
build_error = build_project(
|
|
67
|
+
project=project, tb_client=client, watch=False, silent=True, exit_on_error=False, config=config
|
|
68
|
+
)
|
|
68
69
|
if build_error:
|
|
69
70
|
raise Exception(build_error)
|
|
70
71
|
click.echo(FeedbackManager.info(message="✓ Done!\n"))
|
|
71
|
-
config = CLIConfig.get_project_config()
|
|
72
72
|
folder = project.folder
|
|
73
73
|
pipe_path = get_pipe_path(name_or_filename, folder)
|
|
74
74
|
pipe_name = pipe_path.stem
|
|
@@ -82,11 +82,11 @@ def create_test(
|
|
|
82
82
|
content=pipe_content,
|
|
83
83
|
parameters=parameters or "No parameters",
|
|
84
84
|
)
|
|
85
|
-
user_token = config.
|
|
85
|
+
user_token = config.get("user_token")
|
|
86
86
|
if not user_token:
|
|
87
87
|
raise Exception("No user token found")
|
|
88
88
|
|
|
89
|
-
llm = LLM(user_token=user_token, host=config.
|
|
89
|
+
llm = LLM(user_token=user_token, host=config.get("host") or "")
|
|
90
90
|
response_llm = llm.ask(system_prompt=system_prompt, prompt=prompt, feature="tb_test_create")
|
|
91
91
|
response_xml = extract_xml(response_llm, "response")
|
|
92
92
|
tests_content = parse_xml(response_xml, "test")
|
|
@@ -142,11 +142,13 @@ def dump_tests(tests: List[Dict[str, Any]]) -> str:
|
|
|
142
142
|
return yaml_str.replace("- name:", "\n- name:")
|
|
143
143
|
|
|
144
144
|
|
|
145
|
-
def update_test(pipe: str, project: Project, client: TinyB) -> None:
|
|
145
|
+
def update_test(pipe: str, project: Project, client: TinyB, config: dict[str, Any]) -> None:
|
|
146
146
|
try:
|
|
147
147
|
folder = project.folder
|
|
148
148
|
click.echo(FeedbackManager.highlight(message="\n» Building test environment"))
|
|
149
|
-
build_error = build_project(
|
|
149
|
+
build_error = build_project(
|
|
150
|
+
project=project, tb_client=client, watch=False, silent=True, exit_on_error=False, config=config
|
|
151
|
+
)
|
|
150
152
|
if build_error:
|
|
151
153
|
raise Exception(build_error)
|
|
152
154
|
|
|
@@ -190,11 +192,18 @@ def update_test(pipe: str, project: Project, client: TinyB) -> None:
|
|
|
190
192
|
cleanup_test_workspace(client, project.folder)
|
|
191
193
|
|
|
192
194
|
|
|
193
|
-
def run_tests(name: Tuple[str, ...], project: Project, client: TinyB) -> Optional[str]:
|
|
195
|
+
def run_tests(name: Tuple[str, ...], project: Project, client: TinyB, config: dict[str, Any]) -> Optional[str]:
|
|
194
196
|
full_error = ""
|
|
195
197
|
try:
|
|
196
198
|
click.echo(FeedbackManager.highlight(message="\n» Building test environment"))
|
|
197
|
-
build_error = build_project(
|
|
199
|
+
build_error = build_project(
|
|
200
|
+
project=project,
|
|
201
|
+
tb_client=client,
|
|
202
|
+
watch=False,
|
|
203
|
+
silent=True,
|
|
204
|
+
exit_on_error=False,
|
|
205
|
+
config=config,
|
|
206
|
+
)
|
|
198
207
|
if build_error:
|
|
199
208
|
raise Exception(build_error)
|
|
200
209
|
click.echo(FeedbackManager.info(message="✓ Done!"))
|
tinybird/tb/modules/watch.py
CHANGED
|
@@ -33,9 +33,10 @@ class WatchProjectHandler(PatternMatchingEventHandler):
|
|
|
33
33
|
".env.local",
|
|
34
34
|
]
|
|
35
35
|
|
|
36
|
-
def __init__(self, shell: Shell, project: Project, process: Callable):
|
|
36
|
+
def __init__(self, shell: Shell, project: Project, config: dict[str, Any], process: Callable):
|
|
37
37
|
self.shell = shell
|
|
38
38
|
self.project = project
|
|
39
|
+
self.config = config
|
|
39
40
|
self.process = process
|
|
40
41
|
self.datafiles = project.get_project_datafiles()
|
|
41
42
|
patterns = [f"**/*{ext}" for ext in self.valid_extensions]
|
|
@@ -58,7 +59,7 @@ class WatchProjectHandler(PatternMatchingEventHandler):
|
|
|
58
59
|
|
|
59
60
|
def _process(self, path: Optional[str] = None) -> None:
|
|
60
61
|
click.echo(FeedbackManager.highlight(message="» Rebuilding project..."))
|
|
61
|
-
self.process(watch=True, file_changed=path, diff=self.diff(path))
|
|
62
|
+
self.process(watch=True, file_changed=path, diff=self.diff(path), config=self.config)
|
|
62
63
|
self.shell.reprint_prompt()
|
|
63
64
|
|
|
64
65
|
def diff(self, path: Optional[str] = None) -> Optional[str]:
|
|
@@ -137,8 +138,9 @@ def watch_project(
|
|
|
137
138
|
shell: Shell,
|
|
138
139
|
process: Callable[[bool, Optional[str], Optional[str]], None],
|
|
139
140
|
project: Project,
|
|
141
|
+
config: dict[str, Any],
|
|
140
142
|
) -> None:
|
|
141
|
-
event_handler = WatchProjectHandler(shell=shell, project=project, process=process)
|
|
143
|
+
event_handler = WatchProjectHandler(shell=shell, project=project, process=process, config=config)
|
|
142
144
|
observer = Observer()
|
|
143
145
|
observer.schedule(event_handler, path=str(project.path), recursive=True)
|
|
144
146
|
observer.start()
|
|
@@ -11,20 +11,20 @@ tinybird/sql_template_fmt.py,sha256=KUHdj5rYCYm_rKKdXYSJAE9vIyXUQLB0YSZnUXHeBlY,
|
|
|
11
11
|
tinybird/sql_toolset.py,sha256=Y2_fQrbk5GSNoRncAmRS_snpV61XQbiOy4uYkeF6pr4,19767
|
|
12
12
|
tinybird/syncasync.py,sha256=IPnOx6lMbf9SNddN1eBtssg8vCLHMt76SuZ6YNYm-Yk,27761
|
|
13
13
|
tinybird/tornado_template.py,sha256=jjNVDMnkYFWXflmT8KU_Ssbo5vR8KQq3EJMk5vYgXRw,41959
|
|
14
|
-
tinybird/ch_utils/constants.py,sha256=
|
|
14
|
+
tinybird/ch_utils/constants.py,sha256=eQhAxN1vBBzFCP0-UGbBjkuCp4jrFzZRUkfVcKQ2osg,4231
|
|
15
15
|
tinybird/ch_utils/engine.py,sha256=4X1B-iuhdW_mxKnX_m3iCsxgP9RPVgR75g7yH1vsJ6A,40851
|
|
16
16
|
tinybird/datafile/common.py,sha256=hr9Qv4Xot21l2dW6xKPa5_JUu8pnGuDNnVpDf8pgthc,105659
|
|
17
17
|
tinybird/datafile/exceptions.py,sha256=8rw2umdZjtby85QbuRKFO5ETz_eRHwUY5l7eHsy1wnI,556
|
|
18
18
|
tinybird/datafile/parse_connection.py,sha256=tRyn2Rpr1TeWet5BXmMoQgaotbGdYep1qiTak_OqC5E,1825
|
|
19
19
|
tinybird/datafile/parse_datasource.py,sha256=ssW8QeFSgglVFi3sDZj_HgkJiTJ2069v2JgqnH3CkDE,1825
|
|
20
20
|
tinybird/datafile/parse_pipe.py,sha256=8e9LMecSQVWHC4AXf8cdxoQ1nxUR4fTObYxTctO_EXQ,3816
|
|
21
|
-
tinybird/tb/__cli__.py,sha256=
|
|
21
|
+
tinybird/tb/__cli__.py,sha256=E3lB-KnSHTQ-FxDGmiqdPjPn6asGH5nhTprDqg3HDYY,247
|
|
22
22
|
tinybird/tb/check_pypi.py,sha256=Gp0HkHHDFMSDL6nxKlOY51z7z1Uv-2LRexNTZSHHGmM,552
|
|
23
23
|
tinybird/tb/cli.py,sha256=FdDFEIayjmsZEVsVSSvRiVYn_FHOVg_zWQzchnzfWho,1008
|
|
24
24
|
tinybird/tb/client.py,sha256=IQRaInDjOwr9Fzaz3_xXc3aUGqh94tM2lew7IZbB9eM,53733
|
|
25
25
|
tinybird/tb/config.py,sha256=mhMTGnMB5KcxGoh3dewIr2Jjsa6pHE183gCPAQWyp6o,3973
|
|
26
|
-
tinybird/tb/modules/build.py,sha256=
|
|
27
|
-
tinybird/tb/modules/build_common.py,sha256=
|
|
26
|
+
tinybird/tb/modules/build.py,sha256=vyhQyyDGLUHrJGdKoRy0gCc62vzZrRjtyzdXAJttYE4,7925
|
|
27
|
+
tinybird/tb/modules/build_common.py,sha256=O9WXbZHRjBUwczCr2CGlXIkLQOiwAEJGL9TiY-0eEh8,18627
|
|
28
28
|
tinybird/tb/modules/cicd.py,sha256=0KLKccha9IP749QvlXBmzdWv1On3mFwMY4DUcJlBxiE,7326
|
|
29
29
|
tinybird/tb/modules/cli.py,sha256=-hkwg2ZIWPtldkLkgdY7RYWacOJtkMx58eqqYzMoMfw,17793
|
|
30
30
|
tinybird/tb/modules/common.py,sha256=zY0PFDQVWjhu2MivBtUmcXtAlv7imgO-RG_PUK37XvI,83659
|
|
@@ -32,7 +32,7 @@ tinybird/tb/modules/config.py,sha256=gK7rgaWTDd4ZKCrNEg_Uemr26EQjqWt6TjyQKujxOws
|
|
|
32
32
|
tinybird/tb/modules/connection.py,sha256=axp8Fny1_4PSLJGN4UF6WygyRbQtM3Lbt6thxHKTxzw,17790
|
|
33
33
|
tinybird/tb/modules/copy.py,sha256=dPZkcIDvxjJrlQUIvToO0vsEEEs4EYumbNV77-BzNoU,4404
|
|
34
34
|
tinybird/tb/modules/create.py,sha256=pJxHXG69c9Z_21s-7VuJ3RZOF_nJU51LEwiAkvI3dZY,23251
|
|
35
|
-
tinybird/tb/modules/datasource.py,sha256=
|
|
35
|
+
tinybird/tb/modules/datasource.py,sha256=7Ugj62Nyj6eBB7v9Jyny44KenYSce7rVs2h09N_0hyE,41812
|
|
36
36
|
tinybird/tb/modules/deployment.py,sha256=v0layOmG0IMnuXc3RT39mpGfa5M8yPlrL9F089fJFCo,15964
|
|
37
37
|
tinybird/tb/modules/deployment_common.py,sha256=ZX27oUw7u1ld20qiXH69j7m0DImOc5nckABZ37BPAn4,20406
|
|
38
38
|
tinybird/tb/modules/deprecations.py,sha256=rrszC1f_JJeJ8mUxGoCxckQTJFBCR8wREf4XXXN-PRc,4507
|
|
@@ -46,7 +46,7 @@ tinybird/tb/modules/job.py,sha256=wBsnu8UPTOha2rkLvucgmw4xYv73ubmui3eeSIF68ZM,31
|
|
|
46
46
|
tinybird/tb/modules/llm.py,sha256=fPBBCmM3KlCksLlgJkg4joDn6y3H5QjDzE-Pm4YNf7E,1782
|
|
47
47
|
tinybird/tb/modules/llm_utils.py,sha256=nS9r4FAElJw8yXtmdYrx-rtI2zXR8qXfi1QqUDCfxvg,3469
|
|
48
48
|
tinybird/tb/modules/local.py,sha256=kW3IHwJPvhBsa1eMh_xzow9Az3yYpHthkzsLSHeP5HE,6512
|
|
49
|
-
tinybird/tb/modules/local_common.py,sha256=
|
|
49
|
+
tinybird/tb/modules/local_common.py,sha256=Otvx7R8FjqEpI_5FS8BaraINChpF9XNuw5LW_WTL2XA,18474
|
|
50
50
|
tinybird/tb/modules/login.py,sha256=zerXZqIv15pbFk5XRt746xGcVnp01YmL_403byBf4jQ,1245
|
|
51
51
|
tinybird/tb/modules/login_common.py,sha256=CKXD_BjivhGUmBtNbLTJwzQDr6885C72XPZjo0GLLvI,12010
|
|
52
52
|
tinybird/tb/modules/logout.py,sha256=sniI4JNxpTrVeRCp0oGJuQ3yRerG4hH5uz6oBmjv724,1009
|
|
@@ -63,14 +63,14 @@ tinybird/tb/modules/shell.py,sha256=_9PaKkkh6ZjkixVtKNAtoCPqXMXMn1aQJM_Xzirn7ZM,
|
|
|
63
63
|
tinybird/tb/modules/sink.py,sha256=dK2s__my0ePIUYrqBzhPSgdWN9rbpvP1G4dT7DJzz80,3865
|
|
64
64
|
tinybird/tb/modules/table.py,sha256=4XrtjM-N0zfNtxVkbvLDQQazno1EPXnxTyo7llivfXk,11035
|
|
65
65
|
tinybird/tb/modules/telemetry.py,sha256=T9gtsQffWqG_4hRBaUJPzOfMkPwz7mH-R6Bn1XRYViA,11482
|
|
66
|
-
tinybird/tb/modules/test.py,sha256=
|
|
67
|
-
tinybird/tb/modules/test_common.py,sha256=
|
|
66
|
+
tinybird/tb/modules/test.py,sha256=gi7fH6zavFp1jDs3SoRWdf9uBiKjp1hdOPAEleg7H-Y,2145
|
|
67
|
+
tinybird/tb/modules/test_common.py,sha256=pvHVXZb9xGosh4h_updz13qsIg3pyAtroFnjjrxaoPU,14673
|
|
68
68
|
tinybird/tb/modules/token.py,sha256=ZhW_o7XCr90wJRhMN6816vyo_TVfnzPXyIhrhzQ7oZ0,13807
|
|
69
|
-
tinybird/tb/modules/watch.py,sha256=
|
|
69
|
+
tinybird/tb/modules/watch.py,sha256=R0wERRyL-PrwxKOLSk-T-EvkIczHpeoGirrl3JZxXa8,8935
|
|
70
70
|
tinybird/tb/modules/workspace.py,sha256=tCP1zZMwBhLRGm22TGfpSd4cHvQLAS1o_azIXv_r6uw,11172
|
|
71
71
|
tinybird/tb/modules/workspace_members.py,sha256=5JdkJgfuEwbq-t6vxkBhYwgsiTDxF790wsa6Xfif9nk,8608
|
|
72
72
|
tinybird/tb/modules/agent/__init__.py,sha256=i3oe3vDIWWPaicdCM0zs7D7BJ1W0k7th93ooskHAV00,54
|
|
73
|
-
tinybird/tb/modules/agent/agent.py,sha256=
|
|
73
|
+
tinybird/tb/modules/agent/agent.py,sha256=TqmXTsEGgt3rx6hPlRegCLdVxUzYF5P-x4OuOvIqFg0,37863
|
|
74
74
|
tinybird/tb/modules/agent/animations.py,sha256=4WOC5_2BracttmMCrV0H91tXfWcUzQHBUaIJc5FA7tE,3490
|
|
75
75
|
tinybird/tb/modules/agent/banner.py,sha256=l6cO5Fi7lbVKp-GsBP8jf3IkjOWxg2jpAt9NBCy0WR8,4085
|
|
76
76
|
tinybird/tb/modules/agent/command_agent.py,sha256=0Z08rQsir59zQAr-kkOvsKIFpIBsBSTGJJ1VgqqF5WA,3654
|
|
@@ -121,8 +121,8 @@ tinybird/tb_cli_modules/config.py,sha256=IsgdtFRnUrkY8-Zo32lmk6O7u3bHie1QCxLwgp4
|
|
|
121
121
|
tinybird/tb_cli_modules/exceptions.py,sha256=pmucP4kTF4irIt7dXiG-FcnI-o3mvDusPmch1L8RCWk,3367
|
|
122
122
|
tinybird/tb_cli_modules/regions.py,sha256=QjsL5H6Kg-qr0aYVLrvb1STeJ5Sx_sjvbOYO0LrEGMk,166
|
|
123
123
|
tinybird/tb_cli_modules/telemetry.py,sha256=Hh2Io8ZPROSunbOLuMvuIFU4TqwWPmQTqal4WS09K1A,10449
|
|
124
|
-
tinybird-0.0.1.
|
|
125
|
-
tinybird-0.0.1.
|
|
126
|
-
tinybird-0.0.1.
|
|
127
|
-
tinybird-0.0.1.
|
|
128
|
-
tinybird-0.0.1.
|
|
124
|
+
tinybird-0.0.1.dev295.dist-info/METADATA,sha256=kW3YFTFWs9vaXjrNuSRqJs1XNJpu7Ef_tncRV-r8ffM,1845
|
|
125
|
+
tinybird-0.0.1.dev295.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
126
|
+
tinybird-0.0.1.dev295.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
|
|
127
|
+
tinybird-0.0.1.dev295.dist-info/top_level.txt,sha256=VqqqEmkAy7UNaD8-V51FCoMMWXjLUlR0IstvK7tJYVY,54
|
|
128
|
+
tinybird-0.0.1.dev295.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|