tinybird 0.0.1.dev300__py3-none-any.whl → 0.0.1.dev302__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/connectors.py +1 -7
- tinybird/datafile/common.py +2 -6
- tinybird/service_datasources.py +0 -2
- tinybird/tb/__cli__.py +2 -2
- tinybird/tb/client.py +0 -4
- tinybird/tb/modules/agent/agent.py +55 -50
- tinybird/tb/modules/agent/models.py +6 -2
- tinybird/tb/modules/agent/utils.py +1 -2
- tinybird/tb/modules/build.py +2 -2
- tinybird/tb/modules/build_common.py +2 -2
- tinybird/tb/modules/cli.py +2 -3
- tinybird/tb/modules/common.py +2 -2
- tinybird/tb/modules/create.py +72 -150
- tinybird/tb/modules/datafile/diff.py +1 -1
- tinybird/tb/modules/datafile/format_pipe.py +1 -1
- tinybird/tb/modules/datasource.py +24 -6
- tinybird/tb/modules/exceptions.py +7 -0
- tinybird/tb/modules/mock.py +5 -54
- tinybird/tb/modules/mock_common.py +0 -54
- tinybird/tb/modules/shell.py +1 -1
- tinybird/tb/modules/test.py +7 -6
- tinybird/tb/modules/test_common.py +0 -89
- tinybird/tb_cli_modules/common.py +2 -2
- tinybird/tornado_template.py +1 -1
- {tinybird-0.0.1.dev300.dist-info → tinybird-0.0.1.dev302.dist-info}/METADATA +1 -1
- {tinybird-0.0.1.dev300.dist-info → tinybird-0.0.1.dev302.dist-info}/RECORD +29 -29
- {tinybird-0.0.1.dev300.dist-info → tinybird-0.0.1.dev302.dist-info}/WHEEL +0 -0
- {tinybird-0.0.1.dev300.dist-info → tinybird-0.0.1.dev302.dist-info}/entry_points.txt +0 -0
- {tinybird-0.0.1.dev300.dist-info → tinybird-0.0.1.dev302.dist-info}/top_level.txt +0 -0
tinybird/connectors.py
CHANGED
|
@@ -369,13 +369,7 @@ class Snowflake(Connector):
|
|
|
369
369
|
the_type = "String"
|
|
370
370
|
if t.startswith("NUMBER"):
|
|
371
371
|
the_type = "Int32"
|
|
372
|
-
if (
|
|
373
|
-
t.startswith("FLOAT")
|
|
374
|
-
or t.startswith("DOUBLE")
|
|
375
|
-
or t.startswith("REAL")
|
|
376
|
-
or t.startswith("NUMERIC")
|
|
377
|
-
or t.startswith("DECIMAL")
|
|
378
|
-
):
|
|
372
|
+
if t.startswith(("FLOAT", "DOUBLE", "REAL", "NUMERIC", "DECIMAL")):
|
|
379
373
|
the_type = "Float32"
|
|
380
374
|
if t == "DATE":
|
|
381
375
|
the_type = "Date"
|
tinybird/datafile/common.py
CHANGED
|
@@ -2051,11 +2051,7 @@ def parse(
|
|
|
2051
2051
|
lexer = list(sa)
|
|
2052
2052
|
if lexer:
|
|
2053
2053
|
cmd, args = lexer[0], lexer[1:]
|
|
2054
|
-
if (
|
|
2055
|
-
parser_state.multiline
|
|
2056
|
-
and cmd.lower() in cmds
|
|
2057
|
-
and not (line.startswith(" ") or line.startswith("\t"))
|
|
2058
|
-
):
|
|
2054
|
+
if parser_state.multiline and cmd.lower() in cmds and not line.startswith((" ", "\t")):
|
|
2059
2055
|
cmds[parser_state.command](
|
|
2060
2056
|
parser_state.multiline_string,
|
|
2061
2057
|
lineno=lineno,
|
|
@@ -2508,7 +2504,7 @@ def is_file_a_datasource(filename: str) -> bool:
|
|
|
2508
2504
|
|
|
2509
2505
|
for line in lines:
|
|
2510
2506
|
trimmed_line = line.strip().lower()
|
|
2511
|
-
if trimmed_line.startswith("schema"
|
|
2507
|
+
if trimmed_line.startswith(("schema", "engine")):
|
|
2512
2508
|
return True
|
|
2513
2509
|
|
|
2514
2510
|
return False
|
tinybird/service_datasources.py
CHANGED
|
@@ -446,7 +446,6 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
446
446
|
{"name": "workspace_name", "type": "String"},
|
|
447
447
|
{"name": "user_email", "type": "String"},
|
|
448
448
|
{"name": "request_id", "type": "String"},
|
|
449
|
-
{"name": "model", "type": "LowCardinality(String)"},
|
|
450
449
|
{"name": "prompt_tokens", "type": "UInt32"},
|
|
451
450
|
{"name": "completion_tokens", "type": "UInt32"},
|
|
452
451
|
{"name": "total_tokens", "type": "UInt32"},
|
|
@@ -927,7 +926,6 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
927
926
|
{"name": "workspace_name", "type": "String"},
|
|
928
927
|
{"name": "user_email", "type": "String"},
|
|
929
928
|
{"name": "request_id", "type": "String"},
|
|
930
|
-
{"name": "model", "type": "LowCardinality(String)"},
|
|
931
929
|
{"name": "prompt_tokens", "type": "UInt32"},
|
|
932
930
|
{"name": "completion_tokens", "type": "UInt32"},
|
|
933
931
|
{"name": "total_tokens", "type": "UInt32"},
|
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.dev302'
|
|
8
|
+
__revision__ = 'cf4d28e'
|
tinybird/tb/client.py
CHANGED
|
@@ -1390,7 +1390,3 @@ class TinyB:
|
|
|
1390
1390
|
|
|
1391
1391
|
def delete_tag(self, name: str):
|
|
1392
1392
|
self._req(f"/v0/tags/{name}", method="DELETE")
|
|
1393
|
-
|
|
1394
|
-
def explore_data(self, prompt: str) -> str:
|
|
1395
|
-
params = urlencode({"prompt": prompt, "host": self.host, "origin": "cli"})
|
|
1396
|
-
return self._req(f"/v1/agents/explore?{params}")
|
|
@@ -6,8 +6,7 @@ import sys
|
|
|
6
6
|
import urllib.parse
|
|
7
7
|
import uuid
|
|
8
8
|
from functools import partial
|
|
9
|
-
from
|
|
10
|
-
from typing import Any, Optional
|
|
9
|
+
from typing import Any, Callable, Optional
|
|
11
10
|
|
|
12
11
|
import click
|
|
13
12
|
import humanfriendly
|
|
@@ -27,7 +26,6 @@ from tinybird.tb.modules.agent.file_agent import FileAgent
|
|
|
27
26
|
from tinybird.tb.modules.agent.memory import (
|
|
28
27
|
clear_history,
|
|
29
28
|
clear_messages,
|
|
30
|
-
get_last_messages_from_last_user_prompt,
|
|
31
29
|
save_messages,
|
|
32
30
|
)
|
|
33
31
|
from tinybird.tb.modules.agent.mock_agent import MockAgent
|
|
@@ -67,16 +65,17 @@ from tinybird.tb.modules.common import (
|
|
|
67
65
|
echo_safe_humanfriendly_tables_format_pretty_table,
|
|
68
66
|
get_region_from_host,
|
|
69
67
|
get_regions,
|
|
68
|
+
sys_exit,
|
|
70
69
|
update_cli,
|
|
71
70
|
)
|
|
72
71
|
from tinybird.tb.modules.config import CLIConfig
|
|
73
72
|
from tinybird.tb.modules.deployment_common import create_deployment
|
|
74
|
-
from tinybird.tb.modules.exceptions import CLIBuildException, CLIDeploymentException
|
|
73
|
+
from tinybird.tb.modules.exceptions import CLIBuildException, CLIDeploymentException
|
|
75
74
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
76
75
|
from tinybird.tb.modules.llm import LLM
|
|
77
76
|
from tinybird.tb.modules.local_common import get_tinybird_local_client
|
|
78
77
|
from tinybird.tb.modules.login_common import login
|
|
79
|
-
from tinybird.tb.modules.mock_common import append_mock_data
|
|
78
|
+
from tinybird.tb.modules.mock_common import append_mock_data
|
|
80
79
|
from tinybird.tb.modules.project import Project
|
|
81
80
|
from tinybird.tb.modules.test_common import run_tests as run_tests_common
|
|
82
81
|
|
|
@@ -91,6 +90,7 @@ class TinybirdAgent:
|
|
|
91
90
|
project: Project,
|
|
92
91
|
dangerously_skip_permissions: bool,
|
|
93
92
|
prompt_mode: bool,
|
|
93
|
+
feature: Optional[str] = None,
|
|
94
94
|
):
|
|
95
95
|
self.token = token
|
|
96
96
|
self.user_token = user_token
|
|
@@ -100,14 +100,12 @@ class TinybirdAgent:
|
|
|
100
100
|
self.project = project
|
|
101
101
|
self.thinking_animation = ThinkingAnimation()
|
|
102
102
|
self.confirmed_plan_id: Optional[str] = None
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
else:
|
|
106
|
-
self.messages = []
|
|
103
|
+
self.feature = feature
|
|
104
|
+
self.messages: list[ModelMessage] = []
|
|
107
105
|
cli_config = CLIConfig.get_project_config()
|
|
108
106
|
regions = get_regions(cli_config)
|
|
109
107
|
self.agent = Agent(
|
|
110
|
-
model=create_model(user_token, host, workspace_id),
|
|
108
|
+
model=create_model(user_token, host, workspace_id, feature=feature),
|
|
111
109
|
deps_type=TinybirdAgentContext,
|
|
112
110
|
instructions=[agent_system_prompt],
|
|
113
111
|
tools=[
|
|
@@ -381,7 +379,6 @@ class TinybirdAgent:
|
|
|
381
379
|
build_project=partial(build_project, project=project, config=config),
|
|
382
380
|
deploy_project=partial(deploy_project, project=project, config=config),
|
|
383
381
|
deploy_check_project=partial(deploy_check_project, project=project, config=config),
|
|
384
|
-
mock_data=partial(mock_data, project=project, config=config),
|
|
385
382
|
append_data_local=partial(append_data_local, config=config),
|
|
386
383
|
append_data_cloud=partial(append_data_cloud, config=config),
|
|
387
384
|
analyze_fixture=partial(analyze_fixture, config=config),
|
|
@@ -428,7 +425,6 @@ class TinybirdAgent:
|
|
|
428
425
|
save_messages(new_messages)
|
|
429
426
|
self.thinking_animation.stop()
|
|
430
427
|
click.echo(result.output)
|
|
431
|
-
self.echo_usage(config)
|
|
432
428
|
|
|
433
429
|
async def run_iter(self, user_prompt: str, config: dict[str, Any], run_id: Optional[str] = None) -> None:
|
|
434
430
|
model = create_model(self.user_token, self.host, self.workspace_id, run_id=run_id)
|
|
@@ -455,34 +451,67 @@ class TinybirdAgent:
|
|
|
455
451
|
self.messages.extend(new_messages)
|
|
456
452
|
save_messages(new_messages)
|
|
457
453
|
self.thinking_animation.stop()
|
|
458
|
-
self.echo_usage(config)
|
|
459
454
|
|
|
460
|
-
def echo_usage(self, config: dict[str, Any]) -> None:
|
|
455
|
+
def echo_usage(self, config: dict[str, Any], show_credits: bool = False) -> None:
|
|
461
456
|
try:
|
|
462
457
|
client = _get_tb_client(config["user_token"], config["host"])
|
|
463
458
|
workspace_id = config.get("id", "")
|
|
464
459
|
workspace = client.workspace(workspace_id, with_organization=True, version="v1")
|
|
460
|
+
is_free_plan = workspace["organization"]["plan"].get("billing") == "free_shared_infrastructure_usage"
|
|
461
|
+
|
|
462
|
+
if not is_free_plan and not show_credits:
|
|
463
|
+
return
|
|
464
|
+
|
|
465
465
|
limits_data = client.organization_limits(workspace["organization"]["id"])
|
|
466
466
|
llm_usage_limits = limits_data.get("limits", {}).get("llm_usage", {})
|
|
467
467
|
current_llm_usage = llm_usage_limits.get("quantity") or 0
|
|
468
468
|
llm_usage = llm_usage_limits.get("max") or 0
|
|
469
469
|
remaining_credits = round(max(llm_usage - current_llm_usage, 0), 2)
|
|
470
470
|
current_llm_usage = round(min(llm_usage, current_llm_usage), 2)
|
|
471
|
+
|
|
471
472
|
if not llm_usage:
|
|
472
473
|
return
|
|
473
|
-
|
|
474
|
-
|
|
474
|
+
|
|
475
|
+
def get_message(current_llm_usage, llm_usage: int) -> tuple[Callable[..., str], str, bool]:
|
|
476
|
+
warning_threshold = llm_usage * 0.8
|
|
477
|
+
ui_host = get_display_cloud_host(config["host"])
|
|
478
|
+
|
|
479
|
+
if is_free_plan:
|
|
480
|
+
upgrade_link = f"{ui_host}/organizations/{workspace['organization']['name']}/upgrade?from=agent"
|
|
481
|
+
if current_llm_usage >= llm_usage:
|
|
482
|
+
return (
|
|
483
|
+
FeedbackManager.error,
|
|
484
|
+
f" You have reached the maximum number of credits. Please upgrade to continue using Tinybird Code: {upgrade_link}",
|
|
485
|
+
True,
|
|
486
|
+
)
|
|
487
|
+
if current_llm_usage >= warning_threshold:
|
|
488
|
+
return (
|
|
489
|
+
FeedbackManager.warning,
|
|
490
|
+
f" You are reaching the maximum number of credits. Please upgrade to continue using Tinybird Code: {upgrade_link}",
|
|
491
|
+
False,
|
|
492
|
+
)
|
|
493
|
+
return FeedbackManager.gray, "", False
|
|
494
|
+
|
|
495
|
+
message_color, upgrade_message, should_exit = get_message(current_llm_usage, llm_usage)
|
|
475
496
|
click.echo(
|
|
476
497
|
message_color(
|
|
477
|
-
message=f"{remaining_credits} credits left ({current_llm_usage}/{llm_usage}).
|
|
498
|
+
message=f"{remaining_credits} credits left ({current_llm_usage}/{llm_usage}).{upgrade_message}"
|
|
478
499
|
)
|
|
479
500
|
)
|
|
501
|
+
|
|
502
|
+
if should_exit:
|
|
503
|
+
sys_exit("tinybird_code_error", "Maximum number of credits reached")
|
|
504
|
+
|
|
480
505
|
except Exception:
|
|
481
506
|
pass
|
|
482
507
|
|
|
483
508
|
|
|
484
509
|
def run_agent(
|
|
485
|
-
config: dict[str, Any],
|
|
510
|
+
config: dict[str, Any],
|
|
511
|
+
project: Project,
|
|
512
|
+
dangerously_skip_permissions: bool,
|
|
513
|
+
prompt: Optional[str] = None,
|
|
514
|
+
feature: Optional[str] = None,
|
|
486
515
|
):
|
|
487
516
|
if not prompt:
|
|
488
517
|
latest_version = CheckPypi().get_latest_version()
|
|
@@ -497,7 +526,10 @@ def run_agent(
|
|
|
497
526
|
)
|
|
498
527
|
if yes:
|
|
499
528
|
update_cli()
|
|
500
|
-
|
|
529
|
+
|
|
530
|
+
if not prompt:
|
|
531
|
+
click.echo(FeedbackManager.highlight(message="» Initializing Tinybird Code..."))
|
|
532
|
+
|
|
501
533
|
token = config.get("token", "")
|
|
502
534
|
host = config.get("host", "")
|
|
503
535
|
user_token = config.get("user_token", "")
|
|
@@ -556,6 +588,7 @@ def run_agent(
|
|
|
556
588
|
project,
|
|
557
589
|
dangerously_skip_permissions,
|
|
558
590
|
prompt_mode,
|
|
591
|
+
feature,
|
|
559
592
|
)
|
|
560
593
|
|
|
561
594
|
# Print mode: run once with the provided prompt and exit
|
|
@@ -577,7 +610,6 @@ def run_agent(
|
|
|
577
610
|
)
|
|
578
611
|
)
|
|
579
612
|
agent.echo_usage(config)
|
|
580
|
-
click.echo()
|
|
581
613
|
|
|
582
614
|
except Exception as e:
|
|
583
615
|
click.echo(FeedbackManager.error(message=f"Failed to initialize agent: {e}"))
|
|
@@ -630,6 +662,9 @@ def run_agent(
|
|
|
630
662
|
elif user_input.lower() == "/help":
|
|
631
663
|
subprocess.run(["tb", "--help"], check=True)
|
|
632
664
|
continue
|
|
665
|
+
elif user_input.lower() == "/usage":
|
|
666
|
+
agent.echo_usage(config, show_credits=True)
|
|
667
|
+
continue
|
|
633
668
|
elif user_input.strip() == "":
|
|
634
669
|
continue
|
|
635
670
|
else:
|
|
@@ -732,36 +767,6 @@ def append_data_cloud(config: dict[str, Any], datasource_name: str, path: str) -
|
|
|
732
767
|
append_mock_data(client, datasource_name, path)
|
|
733
768
|
|
|
734
769
|
|
|
735
|
-
def mock_data(
|
|
736
|
-
config: dict[str, Any],
|
|
737
|
-
project: Project,
|
|
738
|
-
datasource_name: str,
|
|
739
|
-
data_format: str,
|
|
740
|
-
rows: int,
|
|
741
|
-
context: Optional[str] = None,
|
|
742
|
-
) -> list[dict[str, Any]]:
|
|
743
|
-
client = get_tinybird_local_client(config, test=False, silent=False)
|
|
744
|
-
cli_config = CLIConfig.get_project_config()
|
|
745
|
-
datasource_path = project.get_resource_path(datasource_name, "datasource")
|
|
746
|
-
|
|
747
|
-
if not datasource_path:
|
|
748
|
-
raise CLIMockException(f"Datasource {datasource_name} not found")
|
|
749
|
-
|
|
750
|
-
datasource_content = Path(datasource_path).read_text()
|
|
751
|
-
return create_mock_data(
|
|
752
|
-
datasource_name,
|
|
753
|
-
datasource_content,
|
|
754
|
-
rows,
|
|
755
|
-
context or "",
|
|
756
|
-
cli_config,
|
|
757
|
-
config,
|
|
758
|
-
cli_config.get_user_token() or "",
|
|
759
|
-
client,
|
|
760
|
-
data_format,
|
|
761
|
-
project.folder,
|
|
762
|
-
)
|
|
763
|
-
|
|
764
|
-
|
|
765
770
|
def analyze_fixture(config: dict[str, Any], fixture_path: str, format: str = "json") -> dict[str, Any]:
|
|
766
771
|
local_client = get_tinybird_local_client(config, test=False, silent=True)
|
|
767
772
|
meta, _data = _analyze(fixture_path, local_client, format)
|
|
@@ -8,7 +8,7 @@ from pydantic_ai.retries import AsyncTenacityTransport, wait_retry_after
|
|
|
8
8
|
from tenacity import AsyncRetrying, retry_if_exception_type, stop_after_attempt, wait_exponential
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
def create_retrying_client(token: str, workspace_id: str):
|
|
11
|
+
def create_retrying_client(token: str, workspace_id: str, feature: Optional[str] = None):
|
|
12
12
|
"""Create a client with smart retry handling for multiple error types."""
|
|
13
13
|
|
|
14
14
|
def should_retry_status(response):
|
|
@@ -29,7 +29,10 @@ def create_retrying_client(token: str, workspace_id: str):
|
|
|
29
29
|
),
|
|
30
30
|
validate_response=should_retry_status,
|
|
31
31
|
)
|
|
32
|
-
|
|
32
|
+
params = {"token": token, "workspace_id": workspace_id}
|
|
33
|
+
if feature:
|
|
34
|
+
params["feature"] = feature
|
|
35
|
+
return AsyncClient(transport=transport, params=params)
|
|
33
36
|
|
|
34
37
|
|
|
35
38
|
def create_model(
|
|
@@ -38,6 +41,7 @@ def create_model(
|
|
|
38
41
|
workspace_id: str,
|
|
39
42
|
model: AnthropicModelName = "claude-4-sonnet-20250514",
|
|
40
43
|
run_id: Optional[str] = None,
|
|
44
|
+
feature: Optional[str] = None,
|
|
41
45
|
):
|
|
42
46
|
default_headers = {}
|
|
43
47
|
if run_id:
|
|
@@ -44,7 +44,6 @@ class TinybirdAgentContext(BaseModel):
|
|
|
44
44
|
build_project_test: Callable[..., None]
|
|
45
45
|
deploy_project: Callable[..., None]
|
|
46
46
|
deploy_check_project: Callable[[], None]
|
|
47
|
-
mock_data: Callable[..., list[dict[str, Any]]]
|
|
48
47
|
append_data_local: Callable[..., None]
|
|
49
48
|
append_data_cloud: Callable[..., None]
|
|
50
49
|
analyze_fixture: Callable[..., dict[str, Any]]
|
|
@@ -512,7 +511,7 @@ def create_terminal_box(content: str, new_content: Optional[str] = None, title:
|
|
|
512
511
|
new_line_num = int(match.group(2))
|
|
513
512
|
old_index = old_line_num - 1
|
|
514
513
|
new_index = new_line_num - 1
|
|
515
|
-
elif line.startswith("---"
|
|
514
|
+
elif line.startswith(("---", "+++")):
|
|
516
515
|
# Skip file headers
|
|
517
516
|
pass
|
|
518
517
|
elif line.startswith(" "):
|
tinybird/tb/modules/build.py
CHANGED
|
@@ -8,7 +8,7 @@ from urllib.parse import urlencode
|
|
|
8
8
|
|
|
9
9
|
import click
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
from tinybird import context
|
|
12
12
|
from tinybird.datafile.exceptions import ParseException
|
|
13
13
|
from tinybird.datafile.parse_datasource import parse_datasource
|
|
14
14
|
from tinybird.datafile.parse_pipe import parse_pipe
|
|
@@ -140,7 +140,7 @@ def dev_cloud(
|
|
|
140
140
|
context.disable_template_security_validation.set(True)
|
|
141
141
|
|
|
142
142
|
def process(filenames: List[str], watch: bool = False):
|
|
143
|
-
datafiles = [f for f in filenames if f.endswith(".datasource"
|
|
143
|
+
datafiles = [f for f in filenames if f.endswith((".datasource", ".pipe"))]
|
|
144
144
|
if len(datafiles) > 0:
|
|
145
145
|
check_filenames(filenames=datafiles)
|
|
146
146
|
folder_playground(
|
|
@@ -51,7 +51,7 @@ def process(
|
|
|
51
51
|
return build_status.error
|
|
52
52
|
else:
|
|
53
53
|
build_status.building = True
|
|
54
|
-
if file_changed and
|
|
54
|
+
if file_changed and file_changed.endswith((FixtureExtension.NDJSON, FixtureExtension.CSV)):
|
|
55
55
|
rebuild_fixture(project, tb_client, file_changed)
|
|
56
56
|
if build_status:
|
|
57
57
|
build_status.building = False
|
|
@@ -61,7 +61,7 @@ def process(
|
|
|
61
61
|
if build_status:
|
|
62
62
|
build_status.building = False
|
|
63
63
|
build_status.error = None
|
|
64
|
-
elif file_changed and
|
|
64
|
+
elif file_changed and file_changed.endswith((".env.local", ".env")):
|
|
65
65
|
if build_status:
|
|
66
66
|
build_status.building = False
|
|
67
67
|
build_status.error = None
|
tinybird/tb/modules/cli.py
CHANGED
|
@@ -302,7 +302,7 @@ def sql(
|
|
|
302
302
|
)
|
|
303
303
|
|
|
304
304
|
query = ""
|
|
305
|
-
for
|
|
305
|
+
for elem in dependencies_graph.to_run.values():
|
|
306
306
|
for _node in elem["nodes"]:
|
|
307
307
|
if _node["params"]["name"].lower() == node.lower():
|
|
308
308
|
query = "".join(_node["sql"])
|
|
@@ -488,7 +488,6 @@ def create_ctx_client(
|
|
|
488
488
|
"logout",
|
|
489
489
|
"update",
|
|
490
490
|
"upgrade",
|
|
491
|
-
"create",
|
|
492
491
|
"info",
|
|
493
492
|
"tag",
|
|
494
493
|
"push",
|
|
@@ -502,7 +501,7 @@ def create_ctx_client(
|
|
|
502
501
|
return None
|
|
503
502
|
|
|
504
503
|
commands_always_cloud = ["infra"]
|
|
505
|
-
commands_always_local = ["build", "dev"]
|
|
504
|
+
commands_always_local = ["build", "dev", "create"]
|
|
506
505
|
command_always_test = ["test"]
|
|
507
506
|
|
|
508
507
|
if (
|
tinybird/tb/modules/common.py
CHANGED
|
@@ -908,7 +908,7 @@ def get_format_from_filename_or_url(filename_or_url: str) -> str:
|
|
|
908
908
|
'csv'
|
|
909
909
|
"""
|
|
910
910
|
filename_or_url = filename_or_url.lower()
|
|
911
|
-
if filename_or_url.endswith("json"
|
|
911
|
+
if filename_or_url.endswith(("json", "ndjson")):
|
|
912
912
|
return "ndjson"
|
|
913
913
|
if filename_or_url.endswith("parquet"):
|
|
914
914
|
return "parquet"
|
|
@@ -916,7 +916,7 @@ def get_format_from_filename_or_url(filename_or_url: str) -> str:
|
|
|
916
916
|
return "csv"
|
|
917
917
|
try:
|
|
918
918
|
parsed = urlparse(filename_or_url)
|
|
919
|
-
if parsed.path.endswith("json"
|
|
919
|
+
if parsed.path.endswith(("json", "ndjson")):
|
|
920
920
|
return "ndjson"
|
|
921
921
|
if parsed.path.endswith("parquet"):
|
|
922
922
|
return "parquet"
|