tinybird-cli 6.2.1.dev0__tar.gz → 6.3.1.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/PKG-INFO +6 -1
  2. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/__cli__.py +2 -2
  3. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/client.py +7 -1
  4. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/config.py +1 -1
  5. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/sql.py +2 -1
  6. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/sql_toolset.py +51 -2
  7. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/syncasync.py +1 -0
  8. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/common.py +1 -1
  9. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/pipe.py +14 -2
  10. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird_cli.egg-info/PKG-INFO +6 -1
  11. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird_cli.egg-info/top_level.txt +2 -0
  12. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/setup.cfg +0 -0
  13. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/ch_utils/constants.py +0 -0
  14. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/ch_utils/engine.py +0 -0
  15. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/check_pypi.py +0 -0
  16. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/context.py +0 -0
  17. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/datafile_common.py +0 -0
  18. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/datatypes.py +0 -0
  19. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/feedback_manager.py +0 -0
  20. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/git_settings.py +0 -0
  21. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/sql_template.py +0 -0
  22. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/sql_template_fmt.py +0 -0
  23. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli.py +0 -0
  24. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/auth.py +0 -0
  25. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/branch.py +0 -0
  26. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/cicd.py +0 -0
  27. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/cli.py +0 -0
  28. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/config.py +0 -0
  29. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/connection.py +0 -0
  30. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/datasource.py +0 -0
  31. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/exceptions.py +0 -0
  32. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/fmt.py +0 -0
  33. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/job.py +0 -0
  34. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/regions.py +0 -0
  35. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/tag.py +0 -0
  36. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/telemetry.py +0 -0
  37. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/test.py +0 -0
  38. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  39. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  40. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/token.py +0 -0
  41. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/workspace.py +0 -0
  42. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  43. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird/tornado_template.py +0 -0
  44. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird_cli.egg-info/SOURCES.txt +0 -0
  45. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird_cli.egg-info/dependency_links.txt +0 -0
  46. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird_cli.egg-info/entry_points.txt +0 -0
  47. {tinybird_cli-6.2.1.dev0 → tinybird_cli-6.3.1.dev0}/tinybird_cli.egg-info/requires.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird_cli
3
- Version: 6.2.1.dev0
3
+ Version: 6.3.1.dev0
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli
6
6
  Author: Tinybird
@@ -43,6 +43,11 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
43
43
  Changelog
44
44
  ----------
45
45
 
46
+ 6.3.0
47
+ ***********
48
+
49
+ - `Added` `tb copy run` and `tb pipe copy run` have a new `--on-demand-compute` flag to use on-demand compute instances for copy jobs.
50
+
46
51
  6.2.0
47
52
  ***********
48
53
 
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
4
4
  __url__ = 'https://www.tinybird.co/docs/cli'
5
5
  __author__ = 'Tinybird'
6
6
  __author_email__ = 'support@tinybird.co'
7
- __version__ = '6.2.1.dev0'
8
- __revision__ = '0284e51'
7
+ __version__ = '6.3.1.dev0'
8
+ __revision__ = 'b610ec3'
@@ -635,11 +635,17 @@ class TinyB:
635
635
  return await self._req(f"/v0/pipes/{pipe_name_or_id}/nodes/{node_id}/copy", method="DELETE")
636
636
 
637
637
  async def pipe_run_copy(
638
- self, pipe_name_or_id: str, params: Optional[Dict[str, str]] = None, mode: Optional[str] = None
638
+ self,
639
+ pipe_name_or_id: str,
640
+ params: Optional[Dict[str, str]] = None,
641
+ mode: Optional[str] = None,
642
+ on_demand_compute: bool = False,
639
643
  ):
640
644
  params = {**params} if params else {}
641
645
  if mode:
642
646
  params["_mode"] = mode
647
+ if on_demand_compute:
648
+ params["on_demand_compute"] = "true"
643
649
  return await self._req(f"/v0/pipes/{pipe_name_or_id}/copy?{urlencode(params)}", method="POST")
644
650
 
645
651
  async def pipe_resume_copy(self, pipe_name_or_id: str):
@@ -124,7 +124,7 @@ def get_display_host(ui_host: str):
124
124
  def get_display_cloud_host(api_host: str) -> str:
125
125
  is_local = "localhost" in api_host
126
126
  if is_local:
127
- port = api_host.split(":")[-1]
127
+ port = api_host.rsplit(":", maxsplit=1)[-1]
128
128
  return f"http://cloud.tinybird.co/local/{port}"
129
129
  return CLOUD_HOSTS.get(api_host, api_host)
130
130
 
@@ -257,7 +257,8 @@ def schema_to_sql_columns(schema: List[Dict[str, Any]], skip_jsonpaths: bool = F
257
257
  name = x["normalized_name"] if "normalized_name" in x else x["name"]
258
258
  if x["nullable"]:
259
259
  if (_type := try_to_fix_nullable_in_simple_aggregating_function(x["type"])) is None:
260
- _type = "Nullable(%s)" % x["type"]
260
+ # Skip wrapping if Nullable already present, e.g. LowCardinality(Nullable(String))
261
+ _type = x["type"] if "Nullable(" in x["type"] else "Nullable(%s)" % x["type"]
261
262
  else:
262
263
  _type = x["type"]
263
264
  parts = [col_name(name, backquotes=True), _type]
@@ -3,6 +3,7 @@ import logging
3
3
  import re
4
4
  import threading
5
5
  from collections import defaultdict
6
+ from dataclasses import dataclass
6
7
  from datetime import datetime
7
8
  from functools import lru_cache
8
9
  from typing import FrozenSet, List, Optional, Set, Tuple, Union
@@ -34,7 +35,7 @@ class InvalidFunction(ValueError):
34
35
  super().__init__(self.msg)
35
36
 
36
37
 
37
- class InvalidResource(ValueError):
38
+ class MissingResource(ValueError):
38
39
  def __init__(self, database: str, table: str, default_database: str = ""):
39
40
  if default_database and database == default_database:
40
41
  database = ""
@@ -74,6 +75,54 @@ def explain_plan(sql: str) -> str:
74
75
  return chquery.explain_ast(sql)
75
76
 
76
77
 
78
+ @dataclass(frozen=True)
79
+ class ColumnInfo:
80
+ name: str
81
+ type: str
82
+ nullable: bool
83
+ default_specifier: str = ""
84
+ default_expression: str | None = None
85
+ codec: str | None = None
86
+ comment: str | None = None
87
+ ttl: str | None = None
88
+ is_primary_key: bool = False
89
+
90
+
91
+ @dataclass
92
+ class MaterializedViewTarget:
93
+ database: Optional[str]
94
+ table: str
95
+
96
+
97
+ def parse_materialized_view_target(create_table_query: str) -> Optional[MaterializedViewTarget]:
98
+ """
99
+ Extract target table info from a CREATE MATERIALIZED VIEW statement.
100
+
101
+ Parses statements like:
102
+ CREATE MATERIALIZED VIEW db.view TO target_db.target_table AS SELECT...
103
+ CREATE MATERIALIZED VIEW db.view TO `target_db`.`target_table` AS SELECT...
104
+ CREATE MATERIALIZED VIEW db.view TO `target_db`.`target_table` (col1 Type1, col2 Nullable(DateTime64(3))) AS SELECT...
105
+
106
+ Returns:
107
+ MaterializedViewTarget with database (optional) and table,
108
+ or None if the query is not a CREATE MATERIALIZED VIEW statement.
109
+ """
110
+ try:
111
+ result = chquery.parse_create_materialized_view_target_table(create_table_query)
112
+ except ValueError:
113
+ return None
114
+
115
+ return MaterializedViewTarget(
116
+ database=result["database"],
117
+ table=result["table"],
118
+ )
119
+
120
+
121
+ def get_columns_from_create_query(sql_schema: str) -> list[ColumnInfo]:
122
+ columns = chquery.get_columns_from_create_query(sql_schema)
123
+ return [ColumnInfo(**col) for col in columns]
124
+
125
+
77
126
  def has_join(sql: str) -> bool:
78
127
  return any(line.rstrip().startswith("TableJoin") for line in explain_plan(sql).split())
79
128
 
@@ -586,7 +635,7 @@ def replace_tables(
586
635
  "valid_tables": valid_tables,
587
636
  },
588
637
  )
589
- raise InvalidResource(database, table_name, default_database=default_database)
638
+ raise MissingResource(database, table_name, default_database=default_database)
590
639
 
591
640
  if current_replacements:
592
641
  # We need to transform the dictionary into something cacheable, so a sorted tuple of tuples it is
@@ -26,6 +26,7 @@
26
26
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
27
  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
28
 
29
+ import asyncio
29
30
  import asyncio.coroutines
30
31
  import functools
31
32
  import inspect
@@ -695,7 +695,7 @@ async def create_workspace_branch(
695
695
  if not branch_name:
696
696
  click.echo(FeedbackManager.info_workspace_branch_create_greeting())
697
697
  default_name = f"{workspace['name']}_{uuid.uuid4().hex[0:4]}"
698
- branch_name = click.prompt("\Branch name", default=default_name, err=True, type=str)
698
+ branch_name = click.prompt("\nBranch name", default=default_name, err=True, type=str)
699
699
  assert isinstance(branch_name, str)
700
700
 
701
701
  response = await config.get_client().create_workspace_branch(
@@ -732,10 +732,22 @@ async def regression_test(
732
732
  default=None,
733
733
  help="Key and value of the params you want the Copy pipe to be called with. For example: tb pipe copy run <my_copy_pipe> --param foo=bar",
734
734
  )
735
+ @click.option(
736
+ "--on-demand-compute",
737
+ is_flag=True,
738
+ default=False,
739
+ help="Use on-demand compute instances for the copy job.",
740
+ )
735
741
  @click.pass_context
736
742
  @coro
737
743
  async def pipe_copy_run(
738
- ctx: click.Context, pipe_name_or_id: str, wait: bool, mode: str, yes: bool, param: Optional[Tuple[str]]
744
+ ctx: click.Context,
745
+ pipe_name_or_id: str,
746
+ wait: bool,
747
+ mode: str,
748
+ yes: bool,
749
+ param: Optional[Tuple[str]],
750
+ on_demand_compute: bool,
739
751
  ):
740
752
  """Run an on-demand copy job"""
741
753
 
@@ -746,7 +758,7 @@ async def pipe_copy_run(
746
758
  client: TinyB = ctx.ensure_object(dict)["client"]
747
759
 
748
760
  try:
749
- response = await client.pipe_run_copy(pipe_name_or_id, params, mode)
761
+ response = await client.pipe_run_copy(pipe_name_or_id, params, mode, on_demand_compute=on_demand_compute)
750
762
 
751
763
  job_id = response["job"]["job_id"]
752
764
  job_url = response["job"]["job_url"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird_cli
3
- Version: 6.2.1.dev0
3
+ Version: 6.3.1.dev0
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli
6
6
  Author: Tinybird
@@ -43,6 +43,11 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
43
43
  Changelog
44
44
  ----------
45
45
 
46
+ 6.3.0
47
+ ***********
48
+
49
+ - `Added` `tb copy run` and `tb pipe copy run` have a new `--on-demand-compute` flag to use on-demand compute instances for copy jobs.
50
+
46
51
  6.2.0
47
52
  ***********
48
53
 
@@ -1,5 +1,7 @@
1
+ scripts
1
2
  tests
2
3
  tests_e2e
3
4
  tests_e2e_ingestion
4
5
  tests_tb
5
6
  tinybird
7
+ tinybird_shared