tinybird 0.0.1.dev120__tar.gz → 0.0.1.dev122__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 (109) hide show
  1. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/PKG-INFO +1 -1
  2. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/__cli__.py +2 -2
  3. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/client.py +15 -6
  4. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/build.py +1 -1
  5. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/common.py +18 -31
  6. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/connection.py +7 -1
  7. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/build.py +2 -2
  8. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/common.py +44 -15
  9. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/format_datasource.py +3 -1
  10. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/format_pipe.py +2 -2
  11. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/parse_datasource.py +4 -4
  12. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/parse_pipe.py +4 -4
  13. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/playground.py +2 -2
  14. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/open.py +3 -2
  15. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/project.py +2 -2
  16. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/shell.py +8 -3
  17. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird.egg-info/PKG-INFO +1 -1
  18. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/setup.cfg +0 -0
  19. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/__cli__.py +0 -0
  20. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/ch_utils/constants.py +0 -0
  21. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/ch_utils/engine.py +0 -0
  22. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/check_pypi.py +0 -0
  23. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/client.py +0 -0
  24. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/config.py +0 -0
  25. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/connectors.py +0 -0
  26. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/context.py +0 -0
  27. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/datafile.py +0 -0
  28. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/datatypes.py +0 -0
  29. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/feedback_manager.py +0 -0
  30. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/git_settings.py +0 -0
  31. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/prompts.py +0 -0
  32. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/sql.py +0 -0
  33. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/sql_template.py +0 -0
  34. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/sql_template_fmt.py +0 -0
  35. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/sql_toolset.py +0 -0
  36. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/syncasync.py +0 -0
  37. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/cli.py +0 -0
  38. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/config.py +0 -0
  39. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/auth.py +0 -0
  40. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/cicd.py +0 -0
  41. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/cli.py +0 -0
  42. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/config.py +0 -0
  43. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/copy.py +0 -0
  44. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/create.py +0 -0
  45. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/build_common.py +0 -0
  46. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  47. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  48. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/diff.py +0 -0
  49. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/exceptions.py +0 -0
  50. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/fixture.py +0 -0
  51. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/format_common.py +0 -0
  52. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  53. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datafile/pull.py +0 -0
  54. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/datasource.py +0 -0
  55. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/deployment.py +0 -0
  56. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/endpoint.py +0 -0
  57. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/exceptions.py +0 -0
  58. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/feedback_manager.py +0 -0
  59. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/fmt.py +0 -0
  60. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/infra.py +0 -0
  61. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/job.py +0 -0
  62. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/llm.py +0 -0
  63. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/llm_utils.py +0 -0
  64. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/local.py +0 -0
  65. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/local_common.py +0 -0
  66. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/login.py +0 -0
  67. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/logout.py +0 -0
  68. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/materialization.py +0 -0
  69. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/mock.py +0 -0
  70. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/pipe.py +0 -0
  71. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/regions.py +0 -0
  72. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/secret.py +0 -0
  73. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/table.py +0 -0
  74. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/tag.py +0 -0
  75. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/telemetry.py +0 -0
  76. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/test.py +0 -0
  77. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  78. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  79. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/token.py +0 -0
  80. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/watch.py +0 -0
  81. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/workspace.py +0 -0
  82. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb/modules/workspace_members.py +0 -0
  83. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli.py +0 -0
  84. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/auth.py +0 -0
  85. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/branch.py +0 -0
  86. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/cicd.py +0 -0
  87. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/cli.py +0 -0
  88. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/common.py +0 -0
  89. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/config.py +0 -0
  90. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/connection.py +0 -0
  91. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/datasource.py +0 -0
  92. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/exceptions.py +0 -0
  93. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/fmt.py +0 -0
  94. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/job.py +0 -0
  95. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/pipe.py +0 -0
  96. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/regions.py +0 -0
  97. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/tag.py +0 -0
  98. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/telemetry.py +0 -0
  99. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/test.py +0 -0
  100. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  101. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  102. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/workspace.py +0 -0
  103. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  104. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird/tornado_template.py +0 -0
  105. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird.egg-info/SOURCES.txt +0 -0
  106. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird.egg-info/dependency_links.txt +0 -0
  107. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird.egg-info/entry_points.txt +0 -0
  108. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/tinybird.egg-info/requires.txt +0 -0
  109. {tinybird-0.0.1.dev120 → tinybird-0.0.1.dev122}/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.dev120
3
+ Version: 0.0.1.dev122
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird
@@ -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__ = '0.0.1.dev120'
8
- __revision__ = 'a558f0d'
7
+ __version__ = '0.0.1.dev122'
8
+ __revision__ = '2212d5c'
@@ -1177,14 +1177,23 @@ class TinyB:
1177
1177
  except Exception:
1178
1178
  return False
1179
1179
 
1180
- async def get_trust_policy(self, service: str) -> Dict[str, Any]:
1181
- return await self._req(f"/v0/integrations/{service}/policies/trust-policy")
1180
+ async def get_trust_policy(self, service: str, external_id_seed: Optional[str] = None) -> Dict[str, Any]:
1181
+ params = {}
1182
+ if external_id_seed:
1183
+ params["external_id_seed"] = external_id_seed
1184
+ return await self._req(f"/v0/integrations/{service}/policies/trust-policy?{urlencode(params)}")
1182
1185
 
1183
- async def get_access_write_policy(self, service: str) -> Dict[str, Any]:
1184
- return await self._req(f"/v0/integrations/{service}/policies/write-access-policy")
1186
+ async def get_access_write_policy(self, service: str, bucket: Optional[str] = None) -> Dict[str, Any]:
1187
+ params = {}
1188
+ if bucket:
1189
+ params["bucket"] = bucket
1190
+ return await self._req(f"/v0/integrations/{service}/policies/write-access-policy?{urlencode(params)}")
1185
1191
 
1186
- async def get_access_read_policy(self, service: str) -> Dict[str, Any]:
1187
- return await self._req(f"/v0/integrations/{service}/policies/read-access-policy")
1192
+ async def get_access_read_policy(self, service: str, bucket: Optional[str] = None) -> Dict[str, Any]:
1193
+ params = {}
1194
+ if bucket:
1195
+ params["bucket"] = bucket
1196
+ return await self._req(f"/v0/integrations/{service}/policies/read-access-policy?{urlencode(params)}")
1188
1197
 
1189
1198
  async def sql_get_format(self, sql: str, with_clickhouse_format: bool = False) -> str:
1190
1199
  try:
@@ -150,7 +150,7 @@ def build_project(project: Project, tb_client: TinyB, file_changed: Optional[str
150
150
  except Exception as e:
151
151
  click.echo(FeedbackManager.error_exception(error=f"Error appending fixtures for '{ds_name}': {e}"))
152
152
 
153
- feedback = result.get("feedback", [])
153
+ feedback = build.get("feedback", [])
154
154
  for f in feedback:
155
155
  click.echo(
156
156
  FeedbackManager.warning(message=f"△ {f.get('level')}: {f.get('resource')}: {f.get('message')}")
@@ -1758,6 +1758,7 @@ async def run_aws_iamrole_connection_flow(
1758
1758
  client: TinyB,
1759
1759
  service: str,
1760
1760
  environment: str,
1761
+ connection_name: str,
1761
1762
  ) -> Tuple[str, str, str]:
1762
1763
  if service == DataConnectorType.AMAZON_DYNAMODB:
1763
1764
  raise NotImplementedError("DynamoDB is not supported")
@@ -1771,8 +1772,9 @@ async def run_aws_iamrole_connection_flow(
1771
1772
  region = click.prompt("🌐 Region (the region where the bucket is located, e.g. 'us-east-1')", prompt_suffix="\n> ")
1772
1773
  validate_string_connector_param("Region", region)
1773
1774
 
1774
- access_policy, trust_policy, _ = await get_aws_iamrole_policies(client, service=service, policy="read")
1775
- access_policy = access_policy.replace("<bucket>", bucket_name)
1775
+ access_policy, trust_policy, _ = await get_aws_iamrole_policies(
1776
+ client, service=service, policy="read", bucket=bucket_name, external_id_seed=connection_name
1777
+ )
1776
1778
 
1777
1779
  click.echo(FeedbackManager.prompt_s3_iamrole_connection_login_aws())
1778
1780
  click.echo(FeedbackManager.click_enter_to_continue())
@@ -1834,8 +1836,11 @@ async def production_aws_iamrole_only(
1834
1836
  region: str,
1835
1837
  bucket_name: str,
1836
1838
  environment: str,
1839
+ connection_name: str,
1837
1840
  ) -> Tuple[str, str, str]:
1838
- _, trust_policy, external_id = await get_aws_iamrole_policies(prod_client, service=service, policy="read")
1841
+ _, trust_policy, external_id = await get_aws_iamrole_policies(
1842
+ prod_client, service=service, policy="read", bucket=bucket_name, external_id_seed=connection_name
1843
+ )
1839
1844
 
1840
1845
  trust_policy_copied = True
1841
1846
  try:
@@ -1868,15 +1873,21 @@ async def production_aws_iamrole_only(
1868
1873
  return role_arn, region, external_id
1869
1874
 
1870
1875
 
1871
- async def get_aws_iamrole_policies(client: TinyB, service: str, policy: str = "write"):
1876
+ async def get_aws_iamrole_policies(
1877
+ client: TinyB,
1878
+ service: str,
1879
+ policy: str = "write",
1880
+ bucket: Optional[str] = None,
1881
+ external_id_seed: Optional[str] = None,
1882
+ ):
1872
1883
  access_policy: Dict[str, Any] = {}
1873
1884
  if service == DataConnectorType.AMAZON_S3_IAMROLE:
1874
1885
  service = DataConnectorType.AMAZON_S3
1875
1886
  try:
1876
1887
  if policy == "write":
1877
- access_policy = await client.get_access_write_policy(service)
1888
+ access_policy = await client.get_access_write_policy(service, bucket)
1878
1889
  elif policy == "read":
1879
- access_policy = await client.get_access_read_policy(service)
1890
+ access_policy = await client.get_access_read_policy(service, bucket)
1880
1891
  else:
1881
1892
  raise Exception(f"Access policy {policy} not supported. Choose from 'read' or 'write'")
1882
1893
  if not len(access_policy) > 0:
@@ -1886,7 +1897,7 @@ async def get_aws_iamrole_policies(client: TinyB, service: str, policy: str = "w
1886
1897
 
1887
1898
  trust_policy: Dict[str, Any] = {}
1888
1899
  try:
1889
- trust_policy = await client.get_trust_policy(service)
1900
+ trust_policy = await client.get_trust_policy(service, external_id_seed)
1890
1901
  if not len(trust_policy) > 0:
1891
1902
  raise Exception(f"{service.upper()} Integration not supported in this region")
1892
1903
  except Exception as e:
@@ -2187,30 +2198,6 @@ async def get_user_token(config: CLIConfig, user_token: Optional[str] = None) ->
2187
2198
  return user_token
2188
2199
 
2189
2200
 
2190
- def get_ui_url(api_host: str) -> str:
2191
- """Transforms API URLs into their corresponding UI URLs.
2192
- Examples:
2193
- >>> get_ui_url("http://localhost:8000")
2194
- 'https://cloud.tinybird.co/local/8000'
2195
- >>> get_ui_url("https://api.europe-west2.gcp.tinybird.co")
2196
- 'https://cloud.tinybird.co/gcp/europe-west2'
2197
- >>> get_ui_url("https://other-domain.com")
2198
- 'https://other-domain.com'
2199
- """
2200
- if "//localhost" in api_host:
2201
- port = api_host.split(":")[-1] or "80"
2202
- return f"https://cloud.tinybird.co/local/{port}"
2203
-
2204
- if api_host.endswith("tinybird.co") and "api." in api_host:
2205
- parts = api_host.split(".")
2206
- if len(parts) >= 4:
2207
- region = parts[1] or "europe-west2"
2208
- cloud = parts[2] or "gcp"
2209
- return f"https://cloud.tinybird.co/{cloud}/{region}"
2210
-
2211
- return api_host
2212
-
2213
-
2214
2201
  async def ask_for_organization(
2215
2202
  organizations: Optional[List[Dict[str, Any]]],
2216
2203
  organization_id: Optional[str] = None,
@@ -167,6 +167,7 @@ async def connection_create_s3(ctx: Context) -> None:
167
167
  client,
168
168
  service=service,
169
169
  environment=obj["env"],
170
+ connection_name=connection_name,
170
171
  )
171
172
  unique_suffix = uuid.uuid4().hex[:8] # Use first 8 chars of a UUID for brevity
172
173
  secret_name = f"s3_role_arn_{connection_name}_{unique_suffix}"
@@ -188,7 +189,12 @@ async def connection_create_s3(ctx: Context) -> None:
188
189
  staging=False,
189
190
  )
190
191
  prod_role_arn, _, _ = await production_aws_iamrole_only(
191
- prod_client, service=service, region=region, bucket_name=bucket_name, environment="cloud"
192
+ prod_client,
193
+ service=service,
194
+ region=region,
195
+ bucket_name=bucket_name,
196
+ environment="cloud",
197
+ connection_name=connection_name,
192
198
  )
193
199
  await prod_client.create_secret(name=secret_name, value=prod_role_arn)
194
200
 
@@ -934,7 +934,7 @@ async def process_file(
934
934
  return params
935
935
 
936
936
  if DataFileExtensions.DATASOURCE in filename:
937
- doc = parse_datasource(filename)
937
+ doc = parse_datasource(filename).datafile
938
938
  node = doc.nodes[0]
939
939
  deps: List[str] = []
940
940
  # reemplace tables on materialized columns
@@ -1094,7 +1094,7 @@ async def process_file(
1094
1094
  return resources
1095
1095
 
1096
1096
  elif DataFileExtensions.PIPE in filename:
1097
- doc = parse_pipe(filename)
1097
+ doc = parse_pipe(filename).datafile
1098
1098
  version = f"__v{doc.version}" if doc.version is not None else ""
1099
1099
  name = os.path.basename(filename).split(".")[0]
1100
1100
  description = doc.description if doc.description is not None else ""
@@ -17,7 +17,7 @@ from enum import Enum
17
17
  from io import StringIO
18
18
  from pathlib import Path
19
19
  from string import Template
20
- from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, cast
20
+ from typing import Any, Callable, Dict, Iterable, List, Literal, NamedTuple, Optional, Tuple, cast
21
21
 
22
22
  import click
23
23
  from croniter import croniter
@@ -1163,6 +1163,19 @@ def parse_table_structure(schema: str) -> List[Dict[str, Any]]:
1163
1163
  return _parse_table_structure(schema)
1164
1164
 
1165
1165
 
1166
+ @dataclass
1167
+ class DatafileParseWarning:
1168
+ message: str
1169
+
1170
+ def __str__(self) -> str:
1171
+ return self.message
1172
+
1173
+
1174
+ class ParseResult(NamedTuple):
1175
+ datafile: Datafile
1176
+ warnings: list[DatafileParseWarning]
1177
+
1178
+
1166
1179
  def parse(
1167
1180
  s: str,
1168
1181
  default_node: Optional[str] = None,
@@ -1170,10 +1183,10 @@ def parse(
1170
1183
  replace_includes: bool = True,
1171
1184
  skip_eval: bool = False,
1172
1185
  kind: Optional[DatafileKind] = None,
1173
- ) -> Datafile:
1186
+ ) -> ParseResult:
1174
1187
  """
1175
1188
  Parses `s` string into a document
1176
- >>> d = 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")
1189
+ >>> 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")
1177
1190
  >>> len(d.nodes)
1178
1191
  2
1179
1192
  >>> d.nodes[0]
@@ -1184,6 +1197,8 @@ def parse(
1184
1197
  lines = list(StringIO(s, newline=None))
1185
1198
 
1186
1199
  doc = Datafile()
1200
+ warnings: List[DatafileParseWarning] = []
1201
+
1187
1202
  if kind is not None:
1188
1203
  doc.set_kind(kind)
1189
1204
  doc.raw = list(StringIO(s, newline=None))
@@ -1212,16 +1227,30 @@ def parse(
1212
1227
 
1213
1228
  return error_if_multiline
1214
1229
 
1215
- def deprecated(func: Callable[..., Any]) -> Callable[..., Any]:
1216
- @functools.wraps(func)
1217
- def raise_deprecation_error(*args: Any, **kwargs: Any) -> Any:
1218
- raise DatafileSyntaxError(
1219
- f"{kwargs['cmd'].upper()} has been deprecated",
1220
- lineno=kwargs["lineno"],
1221
- pos=1,
1222
- )
1230
+ def deprecated(severity: Literal["error", "warning"]) -> Callable[..., Any]:
1231
+ def inner(func: Callable[..., Any]) -> Callable[..., Any]:
1232
+ @functools.wraps(func)
1233
+ def raise_deprecation_error(*args: Any, **kwargs: Any) -> Any:
1234
+ raise DatafileSyntaxError(
1235
+ f"{kwargs['cmd'].upper()} has been deprecated",
1236
+ lineno=kwargs["lineno"],
1237
+ pos=1,
1238
+ )
1223
1239
 
1224
- return raise_deprecation_error
1240
+ @functools.wraps(func)
1241
+ def add_deprecation_warning(*args: Any, **kwargs: Any) -> Any:
1242
+ warnings.append(
1243
+ DatafileParseWarning(
1244
+ message=f"{kwargs['cmd'].upper()} has been deprecated and will be ignored.",
1245
+ )
1246
+ )
1247
+
1248
+ if severity == "error":
1249
+ return raise_deprecation_error
1250
+ elif severity == "warning":
1251
+ return add_deprecation_warning
1252
+
1253
+ return inner
1225
1254
 
1226
1255
  def not_supported_yet(extra_message: str = "") -> Callable[..., Any]:
1227
1256
  def inner(func: Callable[..., Any]) -> Callable[..., Any]:
@@ -1288,7 +1317,7 @@ def parse(
1288
1317
  pos=1,
1289
1318
  )
1290
1319
 
1291
- @deprecated
1320
+ @deprecated(severity="error")
1292
1321
  def sources(x: str, **kwargs: Any) -> None:
1293
1322
  pass # Deprecated
1294
1323
 
@@ -1423,7 +1452,7 @@ def parse(
1423
1452
  except FileNotFoundError:
1424
1453
  raise IncludeFileNotFoundException(f, lineno)
1425
1454
 
1426
- @deprecated
1455
+ @deprecated(severity="warning")
1427
1456
  def version(*args: str, **kwargs: Any) -> None:
1428
1457
  pass # whatever, it's deprecated
1429
1458
 
@@ -1634,7 +1663,7 @@ def parse(
1634
1663
  traceback.print_tb(e.__traceback__)
1635
1664
  raise ParseException(f"Unexpected error: {e}", lineno=lineno)
1636
1665
 
1637
- return doc
1666
+ return ParseResult(datafile=doc, warnings=warnings)
1638
1667
 
1639
1668
 
1640
1669
  class ImportReplacements:
@@ -29,7 +29,9 @@ async def format_datasource(
29
29
  if datafile:
30
30
  doc = datafile
31
31
  else:
32
- doc = parse_datasource(filename, replace_includes=replace_includes, skip_eval=skip_eval, content=content)
32
+ doc = parse_datasource(
33
+ filename, replace_includes=replace_includes, skip_eval=skip_eval, content=content
34
+ ).datafile
33
35
 
34
36
  file_parts: List[str] = []
35
37
  if for_diff:
@@ -136,7 +136,7 @@ async def format_pipe(
136
136
  if datafile:
137
137
  doc = datafile
138
138
  else:
139
- doc = parse_pipe(filename, replace_includes=replace_includes, skip_eval=skip_eval, content=content)
139
+ doc = parse_pipe(filename, replace_includes=replace_includes, skip_eval=skip_eval, content=content).datafile
140
140
 
141
141
  file_parts: List[str] = []
142
142
  format_maintainer(file_parts, doc)
@@ -162,7 +162,7 @@ async def format_pipe(
162
162
  if "." in include_file
163
163
  else eval_var(include_file)
164
164
  )
165
- included_pipe = parse_pipe(include_file, skip_eval=skip_eval)
165
+ included_pipe = parse_pipe(include_file, skip_eval=skip_eval).datafile
166
166
  pipe_nodes = doc.nodes.copy()
167
167
  for included_node in included_pipe.nodes.copy():
168
168
  unrolled_included_node = next(
@@ -5,9 +5,9 @@ import click
5
5
 
6
6
  from tinybird.sql_template import render_template_with_secrets
7
7
  from tinybird.tb.modules.datafile.common import (
8
- Datafile,
9
8
  DatafileKind,
10
9
  DatafileSyntaxError,
10
+ ParseResult,
11
11
  format_filename,
12
12
  parse,
13
13
  )
@@ -23,7 +23,7 @@ def parse_datasource(
23
23
  hide_folders: bool = False,
24
24
  add_context_to_datafile_syntax_errors: bool = True,
25
25
  secrets: Optional[Dict[str, str]] = None,
26
- ) -> Datafile:
26
+ ) -> ParseResult:
27
27
  basepath = ""
28
28
  if not content:
29
29
  with open(filename) as file:
@@ -35,7 +35,7 @@ def parse_datasource(
35
35
  s = render_template_with_secrets(filename, s, secrets=secrets or {})
36
36
  filename = format_filename(filename, hide_folders)
37
37
  try:
38
- doc = parse(
38
+ doc, warnings = parse(
39
39
  s, "default", basepath, replace_includes=replace_includes, skip_eval=skip_eval, kind=DatafileKind.datasource
40
40
  )
41
41
  doc.validate()
@@ -52,4 +52,4 @@ def parse_datasource(
52
52
  FeedbackManager.error_parsing_file(filename=filename, lineno=e.lineno, error=e)
53
53
  ) from None
54
54
 
55
- return doc
55
+ return ParseResult(datafile=doc, warnings=warnings)
@@ -5,9 +5,9 @@ import click
5
5
 
6
6
  from tinybird.sql_template import get_template_and_variables, render_sql_template
7
7
  from tinybird.tb.modules.datafile.common import (
8
- Datafile,
9
8
  DatafileKind,
10
9
  DatafileSyntaxError,
10
+ ParseResult,
11
11
  format_filename,
12
12
  parse,
13
13
  )
@@ -24,7 +24,7 @@ def parse_pipe(
24
24
  hide_folders: bool = False,
25
25
  add_context_to_datafile_syntax_errors: bool = True,
26
26
  secrets: Optional[Dict[str, str]] = None,
27
- ) -> Datafile:
27
+ ) -> ParseResult:
28
28
  basepath = ""
29
29
  if not content:
30
30
  with open(filename) as file:
@@ -37,7 +37,7 @@ def parse_pipe(
37
37
  try:
38
38
  sql = ""
39
39
  try:
40
- doc = parse(
40
+ doc, warnings = parse(
41
41
  s, basepath=basepath, replace_includes=replace_includes, skip_eval=skip_eval, kind=DatafileKind.pipe
42
42
  )
43
43
  doc.validate()
@@ -86,4 +86,4 @@ def parse_pipe(
86
86
  raise click.ClickException(FeedbackManager.error_not_found_include(filename=e, lineno=e.lineno))
87
87
  except ModuleNotFoundError:
88
88
  pass
89
- return doc
89
+ return ParseResult(datafile=doc, warnings=warnings)
@@ -1091,7 +1091,7 @@ async def process_file(
1091
1091
  return params
1092
1092
 
1093
1093
  if DataFileExtensions.DATASOURCE in filename:
1094
- doc = parse_datasource(filename)
1094
+ doc, warnings = parse_datasource(filename)
1095
1095
  node = doc.nodes[0]
1096
1096
  deps: List[str] = []
1097
1097
  # reemplace tables on materialized columns
@@ -1251,7 +1251,7 @@ async def process_file(
1251
1251
  return resources
1252
1252
 
1253
1253
  elif DataFileExtensions.PIPE in filename:
1254
- doc = parse_pipe(filename)
1254
+ doc, warnings = parse_pipe(filename)
1255
1255
  version = f"__v{doc.version}" if doc.version is not None else ""
1256
1256
  name = os.path.basename(filename).split(".")[0]
1257
1257
  description = doc.description if doc.description is not None else ""
@@ -3,8 +3,9 @@ import webbrowser
3
3
  import click
4
4
  from click import Context
5
5
 
6
+ from tinybird.tb.config import get_display_cloud_host
6
7
  from tinybird.tb.modules.cli import cli
7
- from tinybird.tb.modules.common import coro, get_ui_url
8
+ from tinybird.tb.modules.common import coro
8
9
  from tinybird.tb.modules.exceptions import CLIException
9
10
  from tinybird.tb.modules.feedback_manager import FeedbackManager
10
11
  from tinybird.tb.modules.local_common import get_build_workspace_name
@@ -24,7 +25,7 @@ async def open(ctx: Context, workspace: str):
24
25
  client = ctx.ensure_object(dict)["client"]
25
26
  env = ctx.ensure_object(dict)["env"]
26
27
 
27
- url_host = get_ui_url(client.host)
28
+ url_host = get_display_cloud_host(client.host)
28
29
 
29
30
  if not workspace:
30
31
  workspace = get_build_workspace_name(config.get("path")) if env == "build" else config.get("name")
@@ -57,13 +57,13 @@ class Project:
57
57
 
58
58
  def get_pipe_datafile(self, filename: str) -> Optional[Datafile]:
59
59
  try:
60
- return parse_pipe(filename)
60
+ return parse_pipe(filename).datafile
61
61
  except Exception:
62
62
  return None
63
63
 
64
64
  def get_datasource_datafile(self, filename: str) -> Optional[Datafile]:
65
65
  try:
66
- return parse_datasource(filename)
66
+ return parse_datasource(filename).datafile
67
67
  except Exception:
68
68
  return None
69
69
 
@@ -247,6 +247,8 @@ class Shell:
247
247
  self.handle_auth()
248
248
  elif cmd == "workspace":
249
249
  self.handle_workspace()
250
+ elif cmd == "deploy":
251
+ self.handle_deploy()
250
252
  elif cmd == "mock":
251
253
  self.handle_mock(arg)
252
254
  elif cmd == "tb":
@@ -256,13 +258,16 @@ class Shell:
256
258
  self.default(line)
257
259
 
258
260
  def handle_build(self):
259
- click.echo(FeedbackManager.error(message="'tb build' command is not available in watch mode"))
261
+ click.echo(FeedbackManager.error(message="'tb build' is not available in the dev shell"))
260
262
 
261
263
  def handle_auth(self):
262
- click.echo(FeedbackManager.error(message="'tb auth' command is not available in watch mode"))
264
+ click.echo(FeedbackManager.error(message="'tb auth' is not available in the dev shell"))
263
265
 
264
266
  def handle_workspace(self):
265
- click.echo(FeedbackManager.error(message="'tb workspace' command is not available in watch mode"))
267
+ click.echo(FeedbackManager.error(message="'tb workspace' is not available in the dev shell"))
268
+
269
+ def handle_deploy(self):
270
+ click.echo(FeedbackManager.error(message="'tb deploy' is not available in the dev shell"))
266
271
 
267
272
  def handle_mock(self, arg):
268
273
  if "mock" in arg.strip().lower():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev120
3
+ Version: 0.0.1.dev122
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird