tinybird 0.0.1.dev174__tar.gz → 0.0.1.dev175__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.

Potentially problematic release.


This version of tinybird might be problematic. Click here for more details.

Files changed (110) hide show
  1. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/PKG-INFO +1 -1
  2. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/datafile.py +1 -1
  3. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/sql_template.py +3 -3
  4. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/__cli__.py +2 -2
  5. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/common.py +79 -15
  6. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/format_common.py +1 -1
  7. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datasource.py +4 -4
  8. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/tinyunit/tinyunit.py +1 -1
  9. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/connection.py +1 -1
  10. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/fmt.py +1 -1
  11. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +1 -1
  12. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird.egg-info/PKG-INFO +1 -1
  13. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/setup.cfg +0 -0
  14. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/__cli__.py +0 -0
  15. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/ch_utils/constants.py +0 -0
  16. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/ch_utils/engine.py +0 -0
  17. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/check_pypi.py +0 -0
  18. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/client.py +0 -0
  19. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/config.py +0 -0
  20. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/connectors.py +0 -0
  21. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/context.py +0 -0
  22. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/datatypes.py +0 -0
  23. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/feedback_manager.py +0 -0
  24. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/git_settings.py +0 -0
  25. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/prompts.py +0 -0
  26. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/sql.py +0 -0
  27. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/sql_template_fmt.py +0 -0
  28. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/sql_toolset.py +0 -0
  29. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/syncasync.py +0 -0
  30. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/check_pypi.py +0 -0
  31. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/cli.py +0 -0
  32. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/client.py +0 -0
  33. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/config.py +0 -0
  34. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/build.py +0 -0
  35. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/cicd.py +0 -0
  36. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/cli.py +0 -0
  37. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/common.py +0 -0
  38. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/config.py +0 -0
  39. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/connection.py +0 -0
  40. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/copy.py +0 -0
  41. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/create.py +0 -0
  42. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/build.py +0 -0
  43. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/build_common.py +0 -0
  44. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  45. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  46. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/diff.py +0 -0
  47. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/exceptions.py +0 -0
  48. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/fixture.py +0 -0
  49. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  50. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  51. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/parse_datasource.py +0 -0
  52. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/parse_pipe.py +0 -0
  53. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  54. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/playground.py +0 -0
  55. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/datafile/pull.py +0 -0
  56. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/deployment.py +0 -0
  57. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/deprecations.py +0 -0
  58. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/dev_server.py +0 -0
  59. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/endpoint.py +0 -0
  60. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/exceptions.py +0 -0
  61. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/feedback_manager.py +0 -0
  62. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/info.py +0 -0
  63. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/infra.py +0 -0
  64. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/job.py +0 -0
  65. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/llm.py +0 -0
  66. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/llm_utils.py +0 -0
  67. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/local.py +0 -0
  68. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/local_common.py +0 -0
  69. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/login.py +0 -0
  70. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/logout.py +0 -0
  71. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/materialization.py +0 -0
  72. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/mock.py +0 -0
  73. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/open.py +0 -0
  74. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/pipe.py +0 -0
  75. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/project.py +0 -0
  76. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/regions.py +0 -0
  77. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/secret.py +0 -0
  78. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/shell.py +0 -0
  79. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/table.py +0 -0
  80. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/telemetry.py +0 -0
  81. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/test.py +0 -0
  82. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  83. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/token.py +0 -0
  84. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/watch.py +0 -0
  85. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/workspace.py +0 -0
  86. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb/modules/workspace_members.py +0 -0
  87. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli.py +0 -0
  88. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/auth.py +0 -0
  89. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/branch.py +0 -0
  90. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/cicd.py +0 -0
  91. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/cli.py +0 -0
  92. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/common.py +0 -0
  93. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/config.py +0 -0
  94. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/datasource.py +0 -0
  95. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/exceptions.py +0 -0
  96. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/job.py +0 -0
  97. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/pipe.py +0 -0
  98. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/regions.py +0 -0
  99. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/tag.py +0 -0
  100. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/telemetry.py +0 -0
  101. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/test.py +0 -0
  102. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  103. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/workspace.py +0 -0
  104. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  105. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird/tornado_template.py +0 -0
  106. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird.egg-info/SOURCES.txt +0 -0
  107. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird.egg-info/dependency_links.txt +0 -0
  108. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird.egg-info/entry_points.txt +0 -0
  109. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird.egg-info/requires.txt +0 -0
  110. {tinybird-0.0.1.dev174 → tinybird-0.0.1.dev175}/tinybird.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev174
3
+ Version: 0.0.1.dev175
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -4848,7 +4848,7 @@ def format_include(file_parts: List[str], doc: Datafile, unroll_includes: bool =
4848
4848
  assert doc.raw is not None
4849
4849
 
4850
4850
  include = [line for line in doc.raw if "INCLUDE" in line and ".incl" in line]
4851
- if len(include):
4851
+ if include:
4852
4852
  file_parts.append(include[0])
4853
4853
  file_parts.append(DATAFILE_NEW_LINE)
4854
4854
  return file_parts
@@ -1657,7 +1657,7 @@ def get_var_data(content, node_id=None):
1657
1657
  # It will be overriden in later definitions or left as is otherwise.
1658
1658
  # args[0] check is used to avoid adding unnamed parameters found in
1659
1659
  # templates like: `split_to_array('')`
1660
- if len(args) and isinstance(args[0], list):
1660
+ if args and isinstance(args[0], list):
1661
1661
  raise ValueError(f'"{args[0]}" can not be used as a variable name')
1662
1662
  if len(args) > 0 and args[0] not in vars and args[0]:
1663
1663
  vars[args[0]] = {
@@ -1669,7 +1669,7 @@ def get_var_data(content, node_id=None):
1669
1669
  if "default" not in kwargs:
1670
1670
  default = kwargs.get("default", args[2] if len(args) > 2 and args[2] else None)
1671
1671
  kwargs["default"] = check_default_value(default)
1672
- if len(args):
1672
+ if args:
1673
1673
  if isinstance(args[0], list):
1674
1674
  raise ValueError(f'"{args[0]}" can not be used as a variable name')
1675
1675
  vars[args[0]] = {
@@ -1678,7 +1678,7 @@ def get_var_data(content, node_id=None):
1678
1678
  }
1679
1679
  elif func in parameter_types:
1680
1680
  # avoid variable names to be None
1681
- if len(args) and args[0] is not None:
1681
+ if args and args[0] is not None:
1682
1682
  # if this is a cast use the function name to get the type
1683
1683
  if "default" not in kwargs:
1684
1684
  default = kwargs.get("default", args[1] if len(args) > 1 else None)
@@ -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.dev174'
8
- __revision__ = '39f0b89'
7
+ __version__ = '0.0.1.dev175'
8
+ __revision__ = '943d7b4'
@@ -110,6 +110,19 @@ class PipeNodeTypes:
110
110
  DATA_SINK = "sink"
111
111
  COPY = "copy"
112
112
  STREAM = "stream"
113
+ EMPTY = ""
114
+
115
+
116
+ VALID_PIPE_NODE_TYPES = {
117
+ PipeNodeTypes.MATERIALIZED,
118
+ PipeNodeTypes.STANDARD,
119
+ PipeNodeTypes.COPY,
120
+ PipeNodeTypes.EMPTY,
121
+ PipeNodeTypes.ENDPOINT,
122
+ PipeNodeTypes.STREAM,
123
+ PipeNodeTypes.DATA_SINK,
124
+ }
125
+ VISIBLE_PIPE_NODE_TYPES = {PipeNodeTypes.MATERIALIZED, PipeNodeTypes.COPY, PipeNodeTypes.ENDPOINT}
113
126
 
114
127
 
115
128
  class DataFileExtensions:
@@ -130,10 +143,43 @@ class CopyModes:
130
143
  return node_mode.lower() in CopyModes.valid_modes
131
144
 
132
145
 
133
- class CopyParameters:
146
+ class Parameters:
147
+ ACCEPTED_ATTRIBUTES: set[str] = set()
148
+ MANDATORY_ATTRIBUTES: set[str] = set()
149
+ _PARAMS_ALIASES: dict[str, str] = {"name": "node", "mode": "copy_mode"}
150
+
151
+ @classmethod
152
+ def valid_params(cls) -> set[str]:
153
+ return cls.ACCEPTED_ATTRIBUTES
154
+
155
+ @classmethod
156
+ def required_params(cls) -> set[str]:
157
+ return cls.MANDATORY_ATTRIBUTES
158
+
159
+ @staticmethod
160
+ def canonical_name(name: str):
161
+ return Parameters._PARAMS_ALIASES.get(name, name)
162
+
163
+
164
+ class PipeParameters(Parameters):
165
+ MANDATORY_ATTRIBUTES = {"name", "sql", "type"}
166
+ ACCEPTED_ATTRIBUTES = {"description"}.union(MANDATORY_ATTRIBUTES)
167
+
168
+
169
+ class CopyParameters(Parameters):
134
170
  TARGET_DATASOURCE = "target_datasource"
135
171
  COPY_SCHEDULE = "copy_schedule"
136
172
  COPY_MODE = "copy_mode"
173
+ COPY_MODE_ALIAS = "mode" # we need this because bot MODE and COPY_MODE go to `mode` variable inside the node
174
+ MANDATORY_ATTRIBUTES = PipeParameters.MANDATORY_ATTRIBUTES.union({TARGET_DATASOURCE})
175
+ ACCEPTED_ATTRIBUTES = PipeParameters.ACCEPTED_ATTRIBUTES.union(MANDATORY_ATTRIBUTES).union(
176
+ {COPY_SCHEDULE, COPY_MODE_ALIAS}
177
+ )
178
+
179
+
180
+ class MaterializedParameters(Parameters):
181
+ MANDATORY_ATTRIBUTES = PipeParameters.MANDATORY_ATTRIBUTES.union({"datasource"})
182
+ ACCEPTED_ATTRIBUTES = PipeParameters.ACCEPTED_ATTRIBUTES.union(MANDATORY_ATTRIBUTES)
137
183
 
138
184
 
139
185
  DATAFILE_NEW_LINE = "\n"
@@ -228,8 +274,10 @@ class Datafile:
228
274
  self.kind = kind
229
275
 
230
276
  def validate_copy_node(self, node: Dict[str, Any]):
231
- if "target_datasource" not in node:
232
- raise DatafileValidationError("COPY node missing target datasource")
277
+ if missing := [param for param in CopyParameters.required_params() if param not in node]:
278
+ raise DatafileValidationError(
279
+ f"Some copy node params have been provided, but the following required ones are missing: {missing}"
280
+ )
233
281
  # copy mode must be append or replace
234
282
  if node.get("mode") and node["mode"] not in ["append", "replace"]:
235
283
  raise DatafileValidationError("COPY node mode must be append or replace")
@@ -240,6 +288,22 @@ class Datafile:
240
288
  and not croniter.is_valid(node["copy_schedule"])
241
289
  ):
242
290
  raise DatafileValidationError("COPY node schedule must be @on-demand or a valid cron expression.")
291
+ for key in node.keys():
292
+ if key not in CopyParameters.valid_params():
293
+ raise DatafileValidationError(
294
+ f"Copy node {repr(node['name'])} has an invalid attribute ({CopyParameters.canonical_name(key)})"
295
+ )
296
+
297
+ def validate_materialized_node(self, node: Dict[str, Any]):
298
+ if missing := [param for param in MaterializedParameters.required_params() if param not in node]:
299
+ raise DatafileValidationError(
300
+ f"Some materialized node params have been provided, but the following required ones are missing: {missing}"
301
+ )
302
+ for key in node.keys():
303
+ if key not in MaterializedParameters.valid_params():
304
+ raise DatafileValidationError(
305
+ f"Materialized node {repr(node['name'])} has an invalid attribute ({MaterializedParameters.canonical_name(key)})"
306
+ )
243
307
 
244
308
  def validate(self):
245
309
  if self.kind == DatafileKind.pipe:
@@ -250,19 +314,21 @@ class Datafile:
250
314
  # [x] Only one materialized node
251
315
  # [x] Only one node of any specific type
252
316
  # (rbarbadillo): there's a HUGE amount of validations in api_pipes.py, we should somehow merge them
253
- for node in self.nodes:
254
- if "sql" not in node:
255
- raise DatafileValidationError(f"SQL missing for node {repr(node['name'])}")
256
317
  non_standard_nodes_count = 0
257
318
  for node in self.nodes:
258
- if node.get("type", "").lower() not in {PipeNodeTypes.STANDARD, ""}:
319
+ node_type = node.get("type", "").lower()
320
+ if node_type not in {PipeNodeTypes.STANDARD, ""}:
259
321
  non_standard_nodes_count += 1
260
322
  if non_standard_nodes_count > 1:
261
323
  raise DatafileValidationError("Multiple non-standard nodes in pipe. There can only be one")
262
- if node.get("type", "").lower() == PipeNodeTypes.MATERIALIZED and "datasource" not in node:
263
- raise DatafileValidationError(f"Materialized node {repr(node['name'])} missing target datasource")
264
- if node.get("type", "").lower() == PipeNodeTypes.COPY:
324
+ if node_type == PipeNodeTypes.MATERIALIZED:
325
+ self.validate_materialized_node(node)
326
+ if node_type == PipeNodeTypes.COPY:
265
327
  self.validate_copy_node(node)
328
+ if node_type not in VALID_PIPE_NODE_TYPES:
329
+ raise DatafileValidationError(
330
+ f"Invalid node type ({node_type}) in pipe {repr(node['name'])}. Allowed node types: {VISIBLE_PIPE_NODE_TYPES}"
331
+ )
266
332
  for token in self.tokens:
267
333
  if token["permission"].upper() != "READ":
268
334
  raise DatafileValidationError(
@@ -289,17 +355,15 @@ class Datafile:
289
355
  f"Invalid permission {token['permission']} for token {token['token_name']}. Only READ and APPEND are allowed for datasources"
290
356
  )
291
357
  # Validate Kafka params
292
- if any(param in node for param in KAFKA_PARAMS) and not all(
293
- param in node for param in REQUIRED_KAFKA_PARAMS
358
+ if any(param in node for param in KAFKA_PARAMS) and (
359
+ missing := [param for param in REQUIRED_KAFKA_PARAMS if param not in node]
294
360
  ):
295
- missing = [param for param in REQUIRED_KAFKA_PARAMS if param not in node]
296
361
  raise DatafileValidationError(
297
362
  f"Some Kafka params have been provided, but the following required ones are missing: {missing}"
298
363
  )
299
364
  # Validate S3 params
300
365
  if any(param in node for param in BLOB_STORAGE_PARAMS):
301
- if not all(param in node for param in REQUIRED_BLOB_STORAGE_PARAMS):
302
- missing = [param for param in REQUIRED_BLOB_STORAGE_PARAMS if param not in node]
366
+ if missing := [param for param in REQUIRED_BLOB_STORAGE_PARAMS if param not in node]:
303
367
  raise DatafileValidationError(
304
368
  f"Some connection params have been provided, but the following required ones are missing: {missing}"
305
369
  )
@@ -53,7 +53,7 @@ def format_include(file_parts: List[str], doc: Datafile, unroll_includes: bool =
53
53
  assert doc.raw is not None
54
54
 
55
55
  include = [line for line in doc.raw if "INCLUDE" in line and ".incl" in line]
56
- if len(include):
56
+ if include:
57
57
  file_parts.append(include[0])
58
58
  file_parts.append(DATAFILE_NEW_LINE)
59
59
  return file_parts
@@ -107,8 +107,8 @@ async def datasource_ls(ctx: Context, match: Optional[str], format_: str):
107
107
 
108
108
 
109
109
  @datasource.command(name="append")
110
- @click.argument("datasource_name")
111
- @click.argument("url", nargs=-1)
110
+ @click.argument("datasource_name", required=True)
111
+ @click.argument("url", nargs=-1, required=True)
112
112
  @click.option("--concurrency", help="How many files to submit concurrently", default=1, hidden=True)
113
113
  @click.pass_context
114
114
  @coro
@@ -137,8 +137,8 @@ async def datasource_append(
137
137
 
138
138
 
139
139
  @datasource.command(name="replace")
140
- @click.argument("datasource_name")
141
- @click.argument("url", nargs=-1)
140
+ @click.argument("datasource_name", required=True)
141
+ @click.argument("url", nargs=-1, required=True)
142
142
  @click.option("--sql-condition", default=None, help="SQL WHERE condition to replace data", hidden=True)
143
143
  @click.option("--skip-incompatible-partition-key", is_flag=True, default=False, hidden=True)
144
144
  @click.pass_context
@@ -317,7 +317,7 @@ def test_run_summary(results: List[TestSummaryResults], only_fail: bool = False,
317
317
  if test.error:
318
318
  click.secho(test.error, fg=test.status.color, bold=True, nl=True, err=True)
319
319
 
320
- if len(total_counts):
320
+ if total_counts:
321
321
  click.echo("\nTotals:")
322
322
  for key_status, value_total in total_counts.items():
323
323
  code_summary = f"Total {key_status.description}: {value_total}"
@@ -293,7 +293,7 @@ async def connection_create_snowflake(
293
293
  if not warehouse:
294
294
  warehouses = await client.get_snowflake_warehouses(account, username, password, role) or []
295
295
  warehouses_names = [w["name"] for w in warehouses]
296
- default_warehouse = warehouses_names[0] if len(warehouses_names) else ""
296
+ default_warehouse = warehouses_names[0] if warehouses_names else ""
297
297
  warehouse = click.prompt(
298
298
  "Warehouse (optional)",
299
299
  type=click.types.Choice(warehouses_names, case_sensitive=False),
@@ -83,7 +83,7 @@ async def fmt(
83
83
 
84
84
  click.echo(FeedbackManager.success_generated_local_file(file=filename))
85
85
 
86
- if len(failed):
86
+ if failed:
87
87
  click.echo(FeedbackManager.error_failed_to_format_files(number=len(failed)))
88
88
  for f in failed:
89
89
  click.echo(f"tb fmt {f} --yes")
@@ -317,7 +317,7 @@ def test_run_summary(results: List[TestSummaryResults], only_fail: bool = False,
317
317
  if test.error:
318
318
  click.secho(test.error, fg=test.status.color, bold=True, nl=True, err=True)
319
319
 
320
- if len(total_counts):
320
+ if total_counts:
321
321
  click.echo("\nTotals:")
322
322
  for key_status, value_total in total_counts.items():
323
323
  code_summary = f"Total {key_status.description}: {value_total}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev174
3
+ Version: 0.0.1.dev175
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird