tinybird 0.0.1.dev180__tar.gz → 0.0.1.dev182__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.dev180 → tinybird-0.0.1.dev182}/PKG-INFO +1 -1
  2. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/__cli__.py +2 -2
  3. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/client.py +28 -7
  4. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/build_datasource.py +1 -1
  5. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/common.py +21 -29
  6. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/parse_datasource.py +6 -1
  7. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/pull.py +30 -51
  8. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/job.py +13 -4
  9. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird.egg-info/PKG-INFO +1 -1
  10. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/setup.cfg +0 -0
  11. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/__cli__.py +0 -0
  12. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/ch_utils/constants.py +0 -0
  13. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/ch_utils/engine.py +0 -0
  14. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/check_pypi.py +0 -0
  15. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/client.py +0 -0
  16. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/config.py +0 -0
  17. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/connectors.py +0 -0
  18. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/context.py +0 -0
  19. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/datafile.py +0 -0
  20. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/datatypes.py +0 -0
  21. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/feedback_manager.py +0 -0
  22. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/git_settings.py +0 -0
  23. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/prompts.py +0 -0
  24. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/sql.py +0 -0
  25. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/sql_template.py +0 -0
  26. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/sql_template_fmt.py +0 -0
  27. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/sql_toolset.py +0 -0
  28. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/syncasync.py +0 -0
  29. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/check_pypi.py +0 -0
  30. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/cli.py +0 -0
  31. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/config.py +0 -0
  32. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/build.py +0 -0
  33. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/cicd.py +0 -0
  34. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/cli.py +0 -0
  35. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/common.py +0 -0
  36. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/config.py +0 -0
  37. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/connection.py +0 -0
  38. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/copy.py +0 -0
  39. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/create.py +0 -0
  40. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/build.py +0 -0
  41. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/build_common.py +0 -0
  42. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  43. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/diff.py +0 -0
  44. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/exceptions.py +0 -0
  45. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/fixture.py +0 -0
  46. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/format_common.py +0 -0
  47. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  48. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  49. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/parse_pipe.py +0 -0
  50. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  51. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datafile/playground.py +0 -0
  52. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/datasource.py +0 -0
  53. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/deployment.py +0 -0
  54. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/deprecations.py +0 -0
  55. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/dev_server.py +0 -0
  56. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/endpoint.py +0 -0
  57. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/exceptions.py +0 -0
  58. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/feedback_manager.py +0 -0
  59. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/info.py +0 -0
  60. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/infra.py +0 -0
  61. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/llm.py +0 -0
  62. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/llm_utils.py +0 -0
  63. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/local.py +0 -0
  64. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/local_common.py +0 -0
  65. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/login.py +0 -0
  66. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/logout.py +0 -0
  67. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/materialization.py +0 -0
  68. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/mock.py +0 -0
  69. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/open.py +0 -0
  70. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/pipe.py +0 -0
  71. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/project.py +0 -0
  72. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/regions.py +0 -0
  73. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/secret.py +0 -0
  74. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/shell.py +0 -0
  75. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/table.py +0 -0
  76. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/telemetry.py +0 -0
  77. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/test.py +0 -0
  78. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  79. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  80. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/token.py +0 -0
  81. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/watch.py +0 -0
  82. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/workspace.py +0 -0
  83. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb/modules/workspace_members.py +0 -0
  84. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli.py +0 -0
  85. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/auth.py +0 -0
  86. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/branch.py +0 -0
  87. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/cicd.py +0 -0
  88. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/cli.py +0 -0
  89. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/common.py +0 -0
  90. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/config.py +0 -0
  91. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/connection.py +0 -0
  92. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/datasource.py +0 -0
  93. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/exceptions.py +0 -0
  94. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/fmt.py +0 -0
  95. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/job.py +0 -0
  96. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/pipe.py +0 -0
  97. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/regions.py +0 -0
  98. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/tag.py +0 -0
  99. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/telemetry.py +0 -0
  100. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/test.py +0 -0
  101. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  102. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  103. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/workspace.py +0 -0
  104. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  105. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird/tornado_template.py +0 -0
  106. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird.egg-info/SOURCES.txt +0 -0
  107. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird.egg-info/dependency_links.txt +0 -0
  108. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird.egg-info/entry_points.txt +0 -0
  109. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/tinybird.egg-info/requires.txt +0 -0
  110. {tinybird-0.0.1.dev180 → tinybird-0.0.1.dev182}/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.dev180
3
+ Version: 0.0.1.dev182
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -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.dev180'
8
- __revision__ = '4ea1a7e'
7
+ __version__ = '0.0.1.dev182'
8
+ __revision__ = 'b1eeede'
@@ -4,7 +4,7 @@ import logging
4
4
  import os
5
5
  import ssl
6
6
  from pathlib import Path
7
- from typing import Any, Callable, Dict, List, Mapping, Optional, Set, Union
7
+ from typing import Any, Callable, Dict, List, Mapping, Optional, Set, Tuple, Union
8
8
  from urllib.parse import quote, urlencode
9
9
 
10
10
  import aiofiles
@@ -402,6 +402,9 @@ class TinyB:
402
402
  async def pipe_file(self, pipe: str):
403
403
  return await self._req(f"/v1/pipes/{pipe}.pipe")
404
404
 
405
+ async def connection_file(self, connection: str):
406
+ return await self._req(f"/v0/connectors/{connection}.connection")
407
+
405
408
  async def datasource_file(self, datasource: str):
406
409
  try:
407
410
  return await self._req(f"/v0/datasources/{datasource}.datasource")
@@ -693,12 +696,30 @@ class TinyB:
693
696
  else:
694
697
  return await self._req(f"/v0/sql?q={quote(sql, safe='')}&{urlencode(params)}")
695
698
 
696
- async def jobs(self, status=None):
697
- jobs = (await self._req("/v0/jobs"))["jobs"]
698
- if status:
699
- status = [status] if isinstance(status, str) else status
700
- jobs = [j for j in jobs if j["status"] in status]
701
- return jobs
699
+ async def jobs(
700
+ self, status: Optional[Tuple[str, ...]] = None, kind: Optional[Tuple[str, ...]] = None
701
+ ) -> List[Dict[str, Any]]:
702
+ async def fetch_jobs(params: Dict[str, str]) -> List[Dict[str, Any]]:
703
+ query_string = urlencode(params) if params else ""
704
+ endpoint = f"/v0/jobs?{query_string}" if query_string else "/v0/jobs"
705
+ response = await self._req(endpoint)
706
+ return response["jobs"]
707
+
708
+ if not status and not kind:
709
+ return await fetch_jobs({})
710
+ result: List[Dict[str, Any]] = []
711
+ if status and kind:
712
+ for s in status:
713
+ for k in kind:
714
+ result.extend(await fetch_jobs({"status": s, "kind": k}))
715
+ elif status:
716
+ for s in status:
717
+ result.extend(await fetch_jobs({"status": s}))
718
+ elif kind:
719
+ for k in kind:
720
+ result.extend(await fetch_jobs({"kind": k}))
721
+
722
+ return result
702
723
 
703
724
  async def job(self, job_id: str):
704
725
  return await self._req(f"/v0/jobs/{job_id}")
@@ -87,7 +87,7 @@ async def new_ds(
87
87
  if datasource.get("service") == "dynamodb":
88
88
  job_id = datasource_response.get("import_id", None)
89
89
  if job_id:
90
- jobs = await client.jobs(status=["waiting", "working"])
90
+ jobs = await client.jobs(status=("waiting", "working"))
91
91
  job_url = next((job["job_url"] for job in jobs if job["id"] == job_id), None)
92
92
  if job_url:
93
93
  click.echo(FeedbackManager.success_dynamodb_initial_load(job_url=job_url))
@@ -1261,22 +1261,12 @@ class ParseResult(NamedTuple):
1261
1261
 
1262
1262
  def parse(
1263
1263
  s: str,
1264
+ kind: DatafileKind,
1264
1265
  default_node: Optional[str] = None,
1265
1266
  basepath: str = ".",
1266
1267
  replace_includes: bool = True,
1267
1268
  skip_eval: bool = False,
1268
- kind: Optional[DatafileKind] = None,
1269
1269
  ) -> ParseResult:
1270
- """
1271
- Parses `s` string into a document
1272
- >>> d, w = parse("NODE \\"test_01\\"\\n DESCRIPTION this is a node that does whatever\\nSQL >\\n\\n SELECT * from test_00\\n\\n\\nNODE \\"test_02\\"\\n DESCRIPTION this is a node that does whatever\\nSQL >\\n\\n SELECT * from test_01\\n WHERE a > 1\\n GROUP by a\\n")
1273
- >>> len(d.nodes)
1274
- 2
1275
- >>> d.nodes[0]
1276
- {'name': 'test_01', 'description': 'this is a node that does whatever', 'sql': 'SELECT * from test_00'}
1277
- >>> d.nodes[1]
1278
- {'name': 'test_02', 'description': 'this is a node that does whatever', 'sql': 'SELECT * from test_01\\nWHERE a > 1\\nGROUP by a'}
1279
- """
1280
1270
  lines = list(StringIO(s, newline=None))
1281
1271
 
1282
1272
  doc = Datafile()
@@ -1403,21 +1393,28 @@ def parse(
1403
1393
 
1404
1394
  return _f
1405
1395
 
1406
- def kafka_key_avro_deserialization(*args: str, **kwargs: Any):
1396
+ def kafka_key_avro_deserialization_deprecated(*args: str, **kwargs: Any):
1407
1397
  raise DatafileSyntaxError(
1408
1398
  f'{kwargs["cmd"].upper()} has been deprecated. Use "KAFKA_KEY_FORMAT avro" in the corresponding .datasource file instead',
1409
1399
  lineno=kwargs["lineno"],
1410
1400
  pos=1,
1411
1401
  )
1412
1402
 
1413
- def kafka_target_partitions(*args: str, **kwargs: Any):
1403
+ def kafka_target_partitions_deprecated(*args: str, **kwargs: Any):
1414
1404
  warnings.append(
1415
1405
  DatafileParseWarning(
1416
1406
  message=f"{kwargs['cmd'].upper()} has been deprecated and will be ignored.",
1417
1407
  )
1418
1408
  )
1419
1409
 
1420
- def import_service(*args: str, **kwargs: Any):
1410
+ def import_external_datasource_deprecated(*args: str, **kwargs: Any):
1411
+ warnings.append(
1412
+ DatafileParseWarning(
1413
+ message=f"{kwargs['cmd'].upper()} has been deprecated and will be ignored.",
1414
+ )
1415
+ )
1416
+
1417
+ def import_service_deprecated(*args: str, **kwargs: Any):
1421
1418
  warnings.append(
1422
1419
  DatafileParseWarning(
1423
1420
  message=(
@@ -1427,14 +1424,14 @@ def parse(
1427
1424
  )
1428
1425
  )
1429
1426
 
1430
- def import_strategy(*args: str, **kwargs: Any):
1427
+ def import_strategy_deprecated(*args: str, **kwargs: Any):
1431
1428
  raise DatafileSyntaxError(
1432
1429
  f"{kwargs['cmd'].upper()} has been deprecated. It is now fixed to 'append'",
1433
1430
  lineno=kwargs["lineno"],
1434
1431
  pos=1,
1435
1432
  )
1436
1433
 
1437
- def kafka_store_binary_headers(*args: str, **kwargs: Any):
1434
+ def kafka_store_binary_headers_deprecated(*args: str, **kwargs: Any):
1438
1435
  raise DatafileSyntaxError(
1439
1436
  f"{kwargs['cmd'].upper()} has been deprecated. When KAFKA_STORE_HEADERS is True, __headers is always of type Map(String, String)",
1440
1437
  lineno=kwargs["lineno"],
@@ -1652,17 +1649,17 @@ def parse(
1652
1649
  "kafka_auto_offset_reset": assign_var("kafka_auto_offset_reset"),
1653
1650
  "kafka_store_raw_value": assign_var("kafka_store_raw_value"),
1654
1651
  "kafka_store_headers": assign_var("kafka_store_headers"),
1655
- "kafka_store_binary_headers": kafka_store_binary_headers,
1652
+ "kafka_store_binary_headers": kafka_store_binary_headers_deprecated,
1656
1653
  "kafka_key_format": assign_var("kafka_key_format"),
1657
1654
  "kafka_value_format": assign_var("kafka_value_format"),
1658
- "kafka_target_partitions": kafka_target_partitions, # Deprecated
1655
+ "kafka_target_partitions": kafka_target_partitions_deprecated, # Deprecated
1659
1656
  "import_connection_name": assign_var("import_connection_name"),
1660
1657
  "import_schedule": assign_var("import_schedule"),
1661
- "import_strategy": import_strategy, # Deprecated, always append
1658
+ "import_strategy": import_strategy_deprecated, # Deprecated, always append
1662
1659
  "import_bucket_uri": assign_var("import_bucket_uri"),
1663
1660
  "import_from_timestamp": assign_var("import_from_timestamp"),
1664
- "import_service": import_service, # Deprecated
1665
- "import_external_datasource": assign_var("import_external_datasource"), # Deprecated, BQ and SFK
1661
+ "import_service": import_service_deprecated, # Deprecated
1662
+ "import_external_datasource": import_external_datasource_deprecated, # Deprecated, BQ and SFK
1666
1663
  "import_query": assign_var("import_query"), # Deprecated, BQ and SFK
1667
1664
  "import_table_arn": assign_var("import_table_arn"), # Only for DynamoDB
1668
1665
  "import_export_bucket": assign_var("import_export_bucket"), # For DynamoDB
@@ -1678,6 +1675,7 @@ def parse(
1678
1675
  "export_compression": assign_var("export_compression"),
1679
1676
  "export_write_strategy": assign_var("export_write_strategy"),
1680
1677
  "export_kafka_topic": assign_var("export_kafka_topic"),
1678
+ # ENGINE_* commands are added dynamically after this dict's definition
1681
1679
  },
1682
1680
  DatafileKind.pipe: {
1683
1681
  "node": node,
@@ -1706,7 +1704,7 @@ def parse(
1706
1704
  "kafka_ssl_ca_pem": assign_var("kafka_ssl_ca_pem"),
1707
1705
  "kafka_security_protocol": assign_var("kafka_security_protocol"),
1708
1706
  "kafka_sasl_mechanism": assign_var("kafka_sasl_mechanism"),
1709
- "kafka_key_avro_deserialization": kafka_key_avro_deserialization,
1707
+ "kafka_key_avro_deserialization": kafka_key_avro_deserialization_deprecated,
1710
1708
  "s3_region": assign_var("s3_region"),
1711
1709
  "s3_arn": assign_var("s3_arn"),
1712
1710
  "s3_access_key": assign_var("s3_access_key"),
@@ -1729,13 +1727,7 @@ def parse(
1729
1727
  if default_node:
1730
1728
  node(default_node)
1731
1729
 
1732
- def get_all_cmds() -> dict[str, Callable]:
1733
- all_cmds: dict[str, Callable] = {}
1734
- for _, cmds in cmds_per_datafile_kind.items():
1735
- all_cmds.update(cmds)
1736
- return all_cmds
1737
-
1738
- cmds = cmds_per_datafile_kind[kind] if kind is not None else get_all_cmds()
1730
+ cmds = cmds_per_datafile_kind[kind]
1739
1731
 
1740
1732
  lineno = 1
1741
1733
  try:
@@ -36,7 +36,12 @@ def parse_datasource(
36
36
  filename = format_filename(filename, hide_folders)
37
37
  try:
38
38
  doc, warnings = parse(
39
- s, "default", basepath, replace_includes=replace_includes, skip_eval=skip_eval, kind=DatafileKind.datasource
39
+ s,
40
+ default_node="default",
41
+ basepath=basepath,
42
+ replace_includes=replace_includes,
43
+ skip_eval=skip_eval,
44
+ kind=DatafileKind.datasource,
40
45
  )
41
46
  doc.validate()
42
47
  except DatafileSyntaxError as e:
@@ -1,13 +1,11 @@
1
- import re
2
1
  from asyncio import Semaphore, gather
3
2
  from pathlib import Path
4
- from typing import Any, Dict, List, Optional, Tuple
3
+ from typing import Any, Optional
5
4
 
6
5
  import aiofiles
7
6
  import click
8
7
 
9
8
  from tinybird.tb.client import AuthNoTokenException, TinyB
10
- from tinybird.tb.modules.datafile.common import get_name_version
11
9
  from tinybird.tb.modules.datafile.format_datasource import format_datasource
12
10
  from tinybird.tb.modules.datafile.format_pipe import format_pipe
13
11
  from tinybird.tb.modules.feedback_manager import FeedbackManager
@@ -21,24 +19,11 @@ async def folder_pull(
21
19
  progress_bar: bool = False,
22
20
  fmt: bool = False,
23
21
  ):
24
- def _get_latest_versions(resources: List[Tuple[str, str]]):
25
- versions: Dict[str, Any] = {}
26
-
27
- for x, resource_type in resources:
28
- t = get_name_version(x)
29
- t["original_name"] = x
30
- if t["version"] is None:
31
- t["version"] = -1
32
- name = t["name"]
33
- t["type"] = resource_type
34
-
35
- if name not in versions or name == x or versions[name]["version"] < t["version"]:
36
- versions[name] = t
37
- return versions
38
-
39
22
  def get_file_folder(extension: str, resource_type: Optional[str]):
40
23
  if extension == "datasource":
41
24
  return "datasources"
25
+ if extension == "connection":
26
+ return "connections"
42
27
  if resource_type == "endpoint":
43
28
  return "endpoints"
44
29
  if resource_type == "sink":
@@ -52,17 +37,16 @@ async def folder_pull(
52
37
  return None
53
38
 
54
39
  async def write_files(
55
- versions: Dict[str, Any],
56
- resources: List[str],
40
+ resources: list[dict[str, Any]],
57
41
  extension: str,
58
42
  get_resource_function: str,
59
43
  progress_bar: bool = False,
60
44
  fmt: bool = False,
61
45
  ):
62
- async def write_resource(k: Dict[str, Any]):
46
+ async def write_resource(k: dict[str, Any]):
63
47
  name = f"{k['name']}.{extension}"
64
48
  try:
65
- resource = await getattr(client, get_resource_function)(k["original_name"])
49
+ resource = await getattr(client, get_resource_function)(k["name"])
66
50
  resource_to_write = resource
67
51
 
68
52
  if fmt:
@@ -76,32 +60,19 @@ async def folder_pull(
76
60
  dest_folder = Path(folder) / "vendor" / k["name"].split(".", 1)[0]
77
61
  name = f"{k['name'].split('.', 1)[1]}.{extension}"
78
62
 
79
- file_folder = get_file_folder(extension, k["type"])
63
+ file_folder = get_file_folder(extension, k.get("type"))
80
64
  f = Path(dest_folder) / file_folder if file_folder is not None else Path(dest_folder)
81
65
 
82
66
  if not f.exists():
83
67
  f.mkdir(parents=True)
84
68
 
85
69
  f = f / name
86
- resource_names = [x.split(".")[-1] for x in resources]
87
70
 
88
71
  if verbose:
89
72
  click.echo(FeedbackManager.info_writing_resource(resource=f))
90
73
  if not f.exists() or force:
91
74
  async with aiofiles.open(f, "w") as fd:
92
- # versions are a client only thing so
93
- # datafiles from the server do not contains information about versions
94
- if k["version"] >= 0:
95
- if fmt:
96
- resource_to_write = "\n" + resource_to_write # fmt strips the first line
97
-
98
- resource_to_write = f"VERSION {k['version']}\n" + resource_to_write
99
75
  if resource_to_write:
100
- matches = re.findall(r"([^\s\.]*__v\d+)", resource_to_write)
101
- for match in set(matches):
102
- m = match.split("__v")[0]
103
- if m in resources or m in resource_names:
104
- resource_to_write = resource_to_write.replace(match, m)
105
76
  await fd.write(resource_to_write)
106
77
  else:
107
78
  if verbose:
@@ -109,32 +80,40 @@ async def folder_pull(
109
80
  except Exception as e:
110
81
  raise click.ClickException(FeedbackManager.error_exception(error=e))
111
82
 
112
- values = versions.values()
113
-
114
83
  if progress_bar:
115
- with click.progressbar(values, label=f"Pulling {extension}s") as values: # type: ignore
116
- for k in values:
84
+ with click.progressbar(resources, label=f"Pulling {extension}s") as resources: # type: ignore
85
+ for k in resources:
117
86
  await write_resource(k)
118
87
  else:
119
- tasks = [write_resource(k) for k in values]
88
+ tasks = [write_resource(k) for k in resources]
120
89
  await _gather_with_concurrency(5, *tasks)
121
90
 
122
91
  try:
123
92
  datasources = await client.datasources()
124
- remote_datasources = sorted([(x["name"], x.get("type", "csv")) for x in datasources], key=lambda x: x[0])
125
- datasources_versions = _get_latest_versions(remote_datasources)
126
-
127
93
  pipes = await client.pipes()
128
- remote_pipes = sorted([(pipe["name"], pipe.get("type", "default")) for pipe in pipes], key=lambda x: x[0])
129
- pipes_versions = _get_latest_versions(remote_pipes)
130
-
131
- resources = list(datasources_versions.keys()) + list(pipes_versions.keys())
94
+ connections = await client.connections(skip_bigquery=True)
132
95
 
133
96
  await write_files(
134
- datasources_versions, resources, "datasource", "datasource_file", progress_bar=progress_bar, fmt=fmt
97
+ resources=datasources,
98
+ extension="datasource",
99
+ get_resource_function="datasource_file",
100
+ progress_bar=progress_bar,
101
+ fmt=fmt,
102
+ )
103
+ await write_files(
104
+ resources=pipes,
105
+ extension="pipe",
106
+ get_resource_function="pipe_file",
107
+ progress_bar=progress_bar,
108
+ fmt=fmt,
109
+ )
110
+ await write_files(
111
+ resources=connections,
112
+ extension="connection",
113
+ get_resource_function="connection_file",
114
+ progress_bar=progress_bar,
115
+ fmt=fmt,
135
116
  )
136
- await write_files(pipes_versions, resources, "pipe", "pipe_file", progress_bar=progress_bar, fmt=fmt)
137
-
138
117
  return
139
118
 
140
119
  except AuthNoTokenException:
@@ -3,6 +3,8 @@
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
7
+
6
8
  import click
7
9
  from click import Context
8
10
 
@@ -24,16 +26,23 @@ def job(ctx: Context) -> None:
24
26
  "-s",
25
27
  "--status",
26
28
  help="Show only jobs with this status",
27
- type=click.Choice(["waiting", "working", "done", "error"], case_sensitive=False),
29
+ type=click.Choice(["waiting", "working", "done", "error", "cancelling", "cancelled"], case_sensitive=False),
30
+ multiple=True,
31
+ default=None,
32
+ )
33
+ @click.option(
34
+ "-k",
35
+ "--kind",
36
+ help="Show only jobs of this kind",
28
37
  multiple=True,
29
38
  default=None,
30
39
  )
31
40
  @click.pass_context
32
41
  @coro
33
- async def jobs_ls(ctx: Context, status: str) -> None:
34
- """List jobs, up to 100 in the last 48h"""
42
+ async def jobs_ls(ctx: Context, status: Tuple[str, ...], kind: Tuple[str, ...]) -> None:
43
+ """List jobs, up to 100"""
35
44
  client: TinyB = ctx.ensure_object(dict)["client"]
36
- jobs = await client.jobs(status=status)
45
+ jobs = await client.jobs(status=status, kind=kind)
37
46
  columns = ["id", "kind", "status", "created at", "updated at", "job url"]
38
47
  click.echo(FeedbackManager.info_jobs())
39
48
  table = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev180
3
+ Version: 0.0.1.dev182
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird