tinybird-cli 5.0.1.dev0__tar.gz → 5.0.1.dev1__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 (46) hide show
  1. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/PKG-INFO +6 -1
  2. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/__cli__.py +2 -2
  3. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/client.py +11 -10
  4. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/datafile.py +27 -0
  5. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/feedback_manager.py +3 -0
  6. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/pipe.py +7 -2
  7. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird_cli.egg-info/PKG-INFO +6 -1
  8. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/setup.cfg +0 -0
  9. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/ch_utils/constants.py +0 -0
  10. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/ch_utils/engine.py +0 -0
  11. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/check_pypi.py +0 -0
  12. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/config.py +0 -0
  13. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/connectors.py +0 -0
  14. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/context.py +0 -0
  15. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/datatypes.py +0 -0
  16. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/git_settings.py +0 -0
  17. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/sql.py +0 -0
  18. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/sql_template.py +0 -0
  19. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/sql_template_fmt.py +0 -0
  20. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/sql_toolset.py +0 -0
  21. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/syncasync.py +0 -0
  22. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli.py +0 -0
  23. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/auth.py +0 -0
  24. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/branch.py +0 -0
  25. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/cicd.py +0 -0
  26. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/cli.py +0 -0
  27. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/common.py +0 -0
  28. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/config.py +0 -0
  29. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/connection.py +0 -0
  30. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/datasource.py +0 -0
  31. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/exceptions.py +0 -0
  32. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/job.py +0 -0
  33. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/regions.py +0 -0
  34. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/telemetry.py +0 -0
  35. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/test.py +0 -0
  36. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  37. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  38. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/token.py +0 -0
  39. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/workspace.py +0 -0
  40. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  41. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird/tornado_template.py +0 -0
  42. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird_cli.egg-info/SOURCES.txt +0 -0
  43. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird_cli.egg-info/dependency_links.txt +0 -0
  44. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird_cli.egg-info/entry_points.txt +0 -0
  45. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird_cli.egg-info/requires.txt +0 -0
  46. {tinybird-cli-5.0.1.dev0 → tinybird-cli-5.0.1.dev1}/tinybird_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tinybird-cli
3
- Version: 5.0.1.dev0
3
+ Version: 5.0.1.dev1
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird
@@ -18,6 +18,11 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
18
18
  Changelog
19
19
  ----------
20
20
 
21
+ 5.1.0.dev1
22
+ ***********
23
+
24
+ - `Added` COPY pipes now support `MODE replace`
25
+
21
26
  5.0.0
22
27
  ******
23
28
 
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
4
4
  __url__ = 'https://www.tinybird.co/docs/cli/introduction.html'
5
5
  __author__ = 'Tinybird'
6
6
  __author_email__ = 'support@tinybird.co'
7
- __version__ = '5.0.1.dev0'
8
- __revision__ = '2af0ad5'
7
+ __version__ = '5.0.1.dev1'
8
+ __revision__ = '3d0cfe4'
@@ -471,6 +471,8 @@ class TinyB(object):
471
471
  self, pipe_name: str, node: Dict[str, Any], dry_run: str = "false", datasource_name: Optional[str] = None
472
472
  ):
473
473
  params = {**{"include_datafile": "true", "dry_run": dry_run}, **node.get("params", node)}
474
+ if "mode" in params:
475
+ params.pop("mode")
474
476
  node_name = node["params"]["name"] if node.get("params", None) else node["name"]
475
477
  if datasource_name:
476
478
  params["datasource"] = datasource_name
@@ -550,34 +552,33 @@ class TinyB(object):
550
552
  async def pipe_remove_endpoint(self, pipe_name_or_uid: str, published_node_uid: str):
551
553
  return await self._req(f"/v0/pipes/{pipe_name_or_uid}/nodes/{published_node_uid}/endpoint", method="DELETE")
552
554
 
553
- async def pipe_create_copy(
554
- self, pipe_name_or_id: str, node_id: str, target_datasource: str, schedule_cron: Optional[str] = None
555
- ):
556
- data = {"target_datasource": target_datasource}
557
- if schedule_cron:
558
- data["schedule_cron"] = schedule_cron
559
-
560
- return await self._req(f"/v0/pipes/{pipe_name_or_id}/nodes/{node_id}/copy", method="POST", data=data)
561
-
562
555
  async def pipe_update_copy(
563
556
  self,
564
557
  pipe_name_or_id: str,
565
558
  node_id: str,
566
559
  target_datasource: Optional[str] = None,
567
560
  schedule_cron: Optional[str] = None,
561
+ mode: Optional[str] = None,
568
562
  ):
569
563
  data = {"schedule_cron": schedule_cron}
570
564
 
571
565
  if target_datasource:
572
566
  data["target_datasource"] = target_datasource
573
567
 
568
+ if mode:
569
+ data["mode"] = mode
570
+
574
571
  return await self._req(f"/v0/pipes/{pipe_name_or_id}/nodes/{node_id}/copy", method="PUT", data=data)
575
572
 
576
573
  async def pipe_remove_copy(self, pipe_name_or_id: str, node_id: str):
577
574
  return await self._req(f"/v0/pipes/{pipe_name_or_id}/nodes/{node_id}/copy", method="DELETE")
578
575
 
579
- async def pipe_run_copy(self, pipe_name_or_id: str, params: Optional[Dict[str, str]] = None):
576
+ async def pipe_run_copy(
577
+ self, pipe_name_or_id: str, params: Optional[Dict[str, str]] = None, mode: Optional[str] = None
578
+ ):
580
579
  params = {**params} if params else {}
580
+ if mode:
581
+ params["_mode"] = mode
581
582
  return await self._req(f"/v0/pipes/{pipe_name_or_id}/copy?{urlencode(params)}", method="POST")
582
583
 
583
584
  async def pipe_resume_copy(self, pipe_name_or_id: str):
@@ -118,6 +118,18 @@ class DataFileExtensions:
118
118
  class CopyParameters:
119
119
  TARGET_DATASOURCE = "target_datasource"
120
120
  COPY_SCHEDULE = "copy_schedule"
121
+ COPY_MODE = "copy_mode"
122
+
123
+
124
+ class CopyModes:
125
+ APPEND = "append"
126
+ REPLACE = "replace"
127
+
128
+ valid_modes = (APPEND, REPLACE)
129
+
130
+ @staticmethod
131
+ def is_valid(node_mode):
132
+ return node_mode.lower() in CopyModes.valid_modes
121
133
 
122
134
 
123
135
  PREVIEW_CONNECTOR_SERVICES = ["s3", "s3_iamrole", "gcs"]
@@ -1076,6 +1088,8 @@ def parse(
1076
1088
  "tags": assign_node_var("tags"),
1077
1089
  "target_datasource": assign_node_var("target_datasource"),
1078
1090
  "copy_schedule": assign_node_var(CopyParameters.COPY_SCHEDULE),
1091
+ "copy_mode": assign_node_var("mode"),
1092
+ "mode": assign_node_var("mode"),
1079
1093
  "resource": assign_node_var("resource"),
1080
1094
  "filter": assign_node_var("filter"),
1081
1095
  "token": add_token,
@@ -1486,6 +1500,7 @@ async def process_file(
1486
1500
  "description": node.get("description", ""),
1487
1501
  "target_datasource": node.get("target_datasource", None),
1488
1502
  "copy_schedule": node.get(CopyParameters.COPY_SCHEDULE, None),
1503
+ "mode": node.get("mode", CopyModes.APPEND),
1489
1504
  }
1490
1505
 
1491
1506
  is_export_node = ExportReplacements.is_export_node(node)
@@ -2483,6 +2498,12 @@ async def check_copy_pipe(pipe, copy_node, tb_client: TinyB):
2483
2498
  if not is_valid_cron:
2484
2499
  raise CLIPipeException(FeedbackManager.error_creating_copy_pipe_invalid_cron(schedule_cron=schedule_cron))
2485
2500
 
2501
+ mode = copy_node["params"].get("mode", CopyModes.APPEND)
2502
+ is_valid_mode = CopyModes.is_valid(mode)
2503
+
2504
+ if not is_valid_mode:
2505
+ raise CLIPipeException(FeedbackManager.error_creating_copy_pipe_invalid_mode(mode=mode))
2506
+
2486
2507
  if not pipe:
2487
2508
  return
2488
2509
 
@@ -2764,6 +2785,7 @@ async def new_pipe(
2764
2785
  try:
2765
2786
  target_datasource = copy_node.get(CopyParameters.TARGET_DATASOURCE, None)
2766
2787
  schedule_cron = copy_node.get(CopyParameters.COPY_SCHEDULE, None)
2788
+ mode = copy_node.get("mode", CopyModes.APPEND)
2767
2789
  schedule_cron = None if schedule_cron == ON_DEMAND else schedule_cron
2768
2790
  current_target_datasource_id = data["copy_target_datasource"]
2769
2791
  target_datasource_response = await tb_client.get_datasource(target_datasource)
@@ -2777,6 +2799,7 @@ async def new_pipe(
2777
2799
  current_schedule_cron = current_schedule.get("cron", None) if current_schedule else None
2778
2800
  schedule_cron_should_be_removed = current_schedule_cron and not schedule_cron
2779
2801
  copy_params["schedule_cron"] = "None" if schedule_cron_should_be_removed else schedule_cron
2802
+ copy_params["mode"] = mode
2780
2803
  await tb_client.pipe_update_copy(**copy_params)
2781
2804
  except Exception as e:
2782
2805
  raise Exception(
@@ -4628,6 +4651,10 @@ async def format_node_type(file_parts: List[str], node: Dict[str, Any]) -> List[
4628
4651
  file_parts.append(node_type_upper)
4629
4652
  file_parts.append(DATAFILE_NEW_LINE)
4630
4653
  file_parts.append(f'TARGET_DATASOURCE {node["target_datasource"]}')
4654
+ if node.get("mode"):
4655
+ file_parts.append(DATAFILE_NEW_LINE)
4656
+ file_parts.append(f'COPY_MODE {node.get("mode")}')
4657
+
4631
4658
  if CopyParameters.COPY_SCHEDULE in node and node[CopyParameters.COPY_SCHEDULE]:
4632
4659
  is_ondemand = node[CopyParameters.COPY_SCHEDULE].lower() == ON_DEMAND
4633
4660
  file_parts.append(DATAFILE_NEW_LINE)
@@ -126,6 +126,9 @@ class FeedbackManager:
126
126
  error_creating_copy_pipe_invalid_cron = error_message(
127
127
  "Cannot create Copy pipe. Invalid cron expression: '{schedule_cron}'"
128
128
  )
129
+ error_creating_copy_pipe_invalid_mode = error_message(
130
+ "Cannot create Copy pipe. Invalid MODE expression: '{mode}'. Valid modes are: 'append', 'replace'"
131
+ )
129
132
  error_creating_sink_pipe_invalid_cron = error_message(
130
133
  "Cannot create Sink Pipe. Invalid cron expression: '{schedule_cron}'"
131
134
  )
@@ -604,6 +604,9 @@ async def regression_test(
604
604
  @pipe_copy.command(name="run", short_help="Run an on-demand copy job")
605
605
  @click.argument("pipe_name_or_id")
606
606
  @click.option("--wait", is_flag=True, default=False, help="Wait for the copy job to finish")
607
+ @click.option(
608
+ "--mode", type=click.Choice(["append", "replace"], case_sensitive=True), default=None, help="Copy strategy"
609
+ )
607
610
  @click.option("--yes", is_flag=True, default=False, help="Do not ask for confirmation")
608
611
  @click.option(
609
612
  "--param",
@@ -615,7 +618,9 @@ async def regression_test(
615
618
  )
616
619
  @click.pass_context
617
620
  @coro
618
- async def pipe_copy_run(ctx: click.Context, pipe_name_or_id: str, wait: bool, yes: bool, param: Optional[Tuple[str]]):
621
+ async def pipe_copy_run(
622
+ ctx: click.Context, pipe_name_or_id: str, wait: bool, mode: str, yes: bool, param: Optional[Tuple[str]]
623
+ ):
619
624
  """Run an on-demand copy job"""
620
625
 
621
626
  params = dict(key_value.split("=") for key_value in param) if param else {}
@@ -625,7 +630,7 @@ async def pipe_copy_run(ctx: click.Context, pipe_name_or_id: str, wait: bool, ye
625
630
  client: TinyB = ctx.ensure_object(dict)["client"]
626
631
 
627
632
  try:
628
- response = await client.pipe_run_copy(pipe_name_or_id, params)
633
+ response = await client.pipe_run_copy(pipe_name_or_id, params, mode)
629
634
 
630
635
  job_id = response["job"]["job_id"]
631
636
  job_url = response["job"]["job_url"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tinybird-cli
3
- Version: 5.0.1.dev0
3
+ Version: 5.0.1.dev1
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird
@@ -18,6 +18,11 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
18
18
  Changelog
19
19
  ----------
20
20
 
21
+ 5.1.0.dev1
22
+ ***********
23
+
24
+ - `Added` COPY pipes now support `MODE replace`
25
+
21
26
  5.0.0
22
27
  ******
23
28