tinybird 0.0.1.dev111__tar.gz → 0.0.1.dev112__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 (108) hide show
  1. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/PKG-INFO +1 -1
  2. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/__cli__.py +2 -2
  3. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/cli.py +8 -1
  4. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/common.py +60 -86
  5. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/connection.py +42 -0
  6. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/create.py +11 -0
  7. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/feedback_manager.py +1 -1
  8. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird.egg-info/PKG-INFO +1 -1
  9. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/setup.cfg +0 -0
  10. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/__cli__.py +0 -0
  11. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/ch_utils/constants.py +0 -0
  12. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/ch_utils/engine.py +0 -0
  13. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/check_pypi.py +0 -0
  14. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/client.py +0 -0
  15. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/config.py +0 -0
  16. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/connectors.py +0 -0
  17. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/context.py +0 -0
  18. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/datafile.py +0 -0
  19. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/datatypes.py +0 -0
  20. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/feedback_manager.py +0 -0
  21. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/git_settings.py +0 -0
  22. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/prompts.py +0 -0
  23. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/sql.py +0 -0
  24. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/sql_template.py +0 -0
  25. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/sql_template_fmt.py +0 -0
  26. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/sql_toolset.py +0 -0
  27. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/syncasync.py +0 -0
  28. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/cli.py +0 -0
  29. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/auth.py +0 -0
  30. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/build.py +0 -0
  31. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/cicd.py +0 -0
  32. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/config.py +0 -0
  33. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/copy.py +0 -0
  34. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/build.py +0 -0
  35. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/build_common.py +0 -0
  36. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  37. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  38. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/common.py +0 -0
  39. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/diff.py +0 -0
  40. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/exceptions.py +0 -0
  41. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/fixture.py +0 -0
  42. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/format_common.py +0 -0
  43. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  44. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  45. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/parse_datasource.py +0 -0
  46. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/parse_pipe.py +0 -0
  47. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  48. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/playground.py +0 -0
  49. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datafile/pull.py +0 -0
  50. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/datasource.py +0 -0
  51. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/deployment.py +0 -0
  52. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/endpoint.py +0 -0
  53. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/exceptions.py +0 -0
  54. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/fmt.py +0 -0
  55. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/infra.py +0 -0
  56. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/job.py +0 -0
  57. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/llm.py +0 -0
  58. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/llm_utils.py +0 -0
  59. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/local.py +0 -0
  60. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/local_common.py +0 -0
  61. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/login.py +0 -0
  62. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/logout.py +0 -0
  63. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/materialization.py +0 -0
  64. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/mock.py +0 -0
  65. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/open.py +0 -0
  66. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/pipe.py +0 -0
  67. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/playground.py +0 -0
  68. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/project.py +0 -0
  69. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/regions.py +0 -0
  70. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/secret.py +0 -0
  71. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/shell.py +0 -0
  72. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/table.py +0 -0
  73. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/tag.py +0 -0
  74. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/telemetry.py +0 -0
  75. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/test.py +0 -0
  76. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  77. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  78. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/token.py +0 -0
  79. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/watch.py +0 -0
  80. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/workspace.py +0 -0
  81. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb/modules/workspace_members.py +0 -0
  82. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli.py +0 -0
  83. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/auth.py +0 -0
  84. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/branch.py +0 -0
  85. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/cicd.py +0 -0
  86. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/cli.py +0 -0
  87. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/common.py +0 -0
  88. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/config.py +0 -0
  89. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/connection.py +0 -0
  90. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/datasource.py +0 -0
  91. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/exceptions.py +0 -0
  92. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/fmt.py +0 -0
  93. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/job.py +0 -0
  94. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/pipe.py +0 -0
  95. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/regions.py +0 -0
  96. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/tag.py +0 -0
  97. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/telemetry.py +0 -0
  98. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/test.py +0 -0
  99. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  100. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  101. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/workspace.py +0 -0
  102. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  103. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird/tornado_template.py +0 -0
  104. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird.egg-info/SOURCES.txt +0 -0
  105. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird.egg-info/dependency_links.txt +0 -0
  106. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird.egg-info/entry_points.txt +0 -0
  107. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/tinybird.egg-info/requires.txt +0 -0
  108. {tinybird-0.0.1.dev111 → tinybird-0.0.1.dev112}/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.dev111
3
+ Version: 0.0.1.dev112
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.dev111'
8
- __revision__ = '621864a'
7
+ __version__ = '0.0.1.dev112'
8
+ __revision__ = 'eb9e376'
@@ -6,6 +6,7 @@
6
6
  import json
7
7
  import logging
8
8
  import os
9
+ import shutil
9
10
  import sys
10
11
  from os import getcwd
11
12
  from pathlib import Path
@@ -48,7 +49,13 @@ DEFAULT_PATTERNS: List[Tuple[str, Union[str, Callable[[str], str]]]] = [
48
49
  VERSION = f"{__cli__.__version__} (rev {__cli__.__revision__})"
49
50
 
50
51
 
51
- @click.group(cls=CatchAuthExceptions, context_settings={"help_option_names": ["-h", "--help"]})
52
+ @click.group(
53
+ cls=CatchAuthExceptions,
54
+ context_settings={
55
+ "help_option_names": ["-h", "--help"],
56
+ "max_content_width": shutil.get_terminal_size().columns - 10,
57
+ },
58
+ )
52
59
  @click.option(
53
60
  "--debug/--no-debug",
54
61
  default=False,
@@ -1751,90 +1751,69 @@ async def remove_release(
1751
1751
  click.echo(FeedbackManager.info_no_release_deleted())
1752
1752
 
1753
1753
 
1754
- async def validate_aws_iamrole_integration(
1754
+ async def run_aws_iamrole_connection_flow(
1755
1755
  client: TinyB,
1756
1756
  service: str,
1757
- role_arn: Optional[str],
1758
- region: Optional[str],
1759
- policy: str = "write",
1760
- no_validate: Optional[bool] = False,
1757
+ policy: str = "read",
1761
1758
  ):
1762
- if no_validate is False:
1763
- access_policy, trust_policy, external_id = await get_aws_iamrole_policies(
1764
- client, service=service, policy=policy
1765
- )
1759
+ if service == DataConnectorType.AMAZON_DYNAMODB:
1760
+ raise NotImplementedError("DynamoDB is not supported yet")
1766
1761
 
1767
- if not role_arn:
1768
- if not click.confirm(
1769
- FeedbackManager.prompt_s3_iamrole_connection_login_aws(),
1770
- show_default=False,
1771
- prompt_suffix="Press y to continue:",
1772
- ):
1773
- sys.exit(1)
1762
+ resource_type = "table" if service == DataConnectorType.AMAZON_DYNAMODB else "bucket"
1763
+ resource_name = click.prompt(f"Enter the name of the {resource_type}")
1764
+ validate_string_connector_param(resource_type.capitalize(), resource_name)
1774
1765
 
1775
- access_policy_copied = True
1776
- try:
1777
- pyperclip.copy(access_policy)
1778
- except Exception:
1779
- access_policy_copied = False
1766
+ resource_region = click.prompt(f"Enter the region where the {resource_type} is located")
1767
+ validate_string_connector_param("Region", resource_region)
1780
1768
 
1781
- replacements_dict = {
1782
- "<bucket>": "<bucket> with your bucket name",
1783
- "<table_name>": "<table_name> with your DynamoDB table name",
1784
- }
1769
+ access_policy, trust_policy, external_id = await get_aws_iamrole_policies(client, service=service, policy=policy)
1770
+ access_policy = access_policy.replace("<bucket>", resource_name)
1785
1771
 
1786
- replacements = [
1787
- replacements_dict.get(replacement, "")
1788
- for replacement in replacements_dict.keys()
1789
- if replacement in access_policy
1790
- ]
1772
+ if not click.confirm(
1773
+ FeedbackManager.prompt_s3_iamrole_connection_login_aws(),
1774
+ show_default=False,
1775
+ prompt_suffix="Press y to continue:",
1776
+ ):
1777
+ sys.exit(1)
1791
1778
 
1792
- if not click.confirm(
1793
- (
1794
- FeedbackManager.prompt_s3_iamrole_connection_policy(
1795
- access_policy=access_policy, replacements=", ".join(replacements)
1796
- )
1797
- if access_policy_copied
1798
- else FeedbackManager.prompt_s3_iamrole_connection_policy_not_copied(access_policy=access_policy)
1799
- ),
1800
- show_default=False,
1801
- prompt_suffix="Press y to continue:",
1802
- ):
1803
- sys.exit(1)
1804
-
1805
- trust_policy_copied = True
1806
- try:
1807
- pyperclip.copy(trust_policy)
1808
- except Exception:
1809
- trust_policy_copied = False
1810
-
1811
- if not click.confirm(
1812
- (
1813
- FeedbackManager.prompt_s3_iamrole_connection_role(trust_policy=trust_policy)
1814
- if trust_policy_copied
1815
- else FeedbackManager.prompt_s3_iamrole_connection_role_not_copied(trust_policy=trust_policy)
1816
- ),
1817
- show_default=False,
1818
- prompt_suffix="Press y to continue:",
1819
- ):
1820
- sys.exit(1)
1821
- else:
1822
- try:
1823
- trust_policy = await client.get_trust_policy(service)
1824
- external_id = trust_policy["Statement"][0]["Condition"]["StringEquals"]["sts:ExternalId"]
1825
- except Exception:
1826
- external_id = ""
1779
+ access_policy_copied = True
1780
+ try:
1781
+ pyperclip.copy(access_policy)
1782
+ except Exception:
1783
+ access_policy_copied = False
1827
1784
 
1828
- if not role_arn:
1829
- role_arn = click.prompt("Enter the ARN of the role you just created")
1830
- validate_string_connector_param("Role ARN", role_arn)
1785
+ if not click.confirm(
1786
+ (
1787
+ FeedbackManager.prompt_s3_iamrole_connection_policy(access_policy=access_policy)
1788
+ if access_policy_copied
1789
+ else FeedbackManager.prompt_s3_iamrole_connection_policy_not_copied(access_policy=access_policy)
1790
+ ),
1791
+ show_default=False,
1792
+ prompt_suffix="Press y to continue:",
1793
+ ):
1794
+ sys.exit(1)
1831
1795
 
1832
- if not region:
1833
- region_resource = "table" if service == DataConnectorType.AMAZON_DYNAMODB else "bucket"
1834
- region = click.prompt(f"Enter the region where the {region_resource} is located")
1835
- validate_string_connector_param("Region", region)
1796
+ trust_policy_copied = True
1797
+ try:
1798
+ pyperclip.copy(trust_policy)
1799
+ except Exception:
1800
+ trust_policy_copied = False
1836
1801
 
1837
- return role_arn, region, external_id
1802
+ if not click.confirm(
1803
+ (
1804
+ FeedbackManager.prompt_s3_iamrole_connection_role(trust_policy=trust_policy)
1805
+ if trust_policy_copied
1806
+ else FeedbackManager.prompt_s3_iamrole_connection_role_not_copied(trust_policy=trust_policy)
1807
+ ),
1808
+ show_default=False,
1809
+ prompt_suffix="Press y to continue:",
1810
+ ):
1811
+ sys.exit(1)
1812
+
1813
+ role_arn = click.prompt("Enter the ARN of the role you just created")
1814
+ validate_string_connector_param("Role ARN", role_arn)
1815
+
1816
+ return role_arn, resource_region, external_id
1838
1817
 
1839
1818
 
1840
1819
  async def get_aws_iamrole_policies(client: TinyB, service: str, policy: str = "write"):
@@ -1867,20 +1846,15 @@ async def get_aws_iamrole_policies(client: TinyB, service: str, policy: str = "w
1867
1846
  return json.dumps(access_policy, indent=4), json.dumps(trust_policy, indent=4), external_id
1868
1847
 
1869
1848
 
1870
- async def validate_aws_iamrole_connection_name(
1871
- client: TinyB, connection_name: Optional[str], no_validate: Optional[bool] = False
1872
- ) -> str:
1873
- if connection_name and no_validate is False:
1874
- if await client.get_connector(connection_name, skip_bigquery=True) is not None:
1875
- raise CLIConnectionException(FeedbackManager.info_connection_already_exists(name=connection_name))
1876
- else:
1877
- while not connection_name:
1878
- connection_name = click.prompt("Enter the name for this connection", default=None, show_default=False)
1879
- assert isinstance(connection_name, str)
1849
+ async def validate_aws_iamrole_connection_name(client: TinyB) -> str:
1850
+ connection_name = None
1851
+ while not connection_name:
1852
+ connection_name = click.prompt("Enter the name for this connection", default=None, show_default=False)
1853
+ assert isinstance(connection_name, str)
1880
1854
 
1881
- if no_validate is False and await client.get_connector(connection_name) is not None:
1882
- click.echo(FeedbackManager.info_connection_already_exists(name=connection_name))
1883
- connection_name = None
1855
+ if await client.get_connector(connection_name) is not None:
1856
+ click.echo(FeedbackManager.info_connection_already_exists(name=connection_name))
1857
+ connection_name = None
1884
1858
  assert isinstance(connection_name, str)
1885
1859
  return connection_name
1886
1860
 
@@ -15,8 +15,12 @@ from tinybird.tb.modules.common import (
15
15
  _get_setting_value,
16
16
  coro,
17
17
  echo_safe_humanfriendly_tables_format_smart_table,
18
+ run_aws_iamrole_connection_flow,
19
+ validate_aws_iamrole_connection_name,
18
20
  )
21
+ from tinybird.tb.modules.create import generate_aws_iamrole_connection_file
19
22
  from tinybird.tb.modules.feedback_manager import FeedbackManager
23
+ from tinybird.tb.modules.project import Project
20
24
 
21
25
  DATA_CONNECTOR_SETTINGS: Dict[DataConnectorType, List[str]] = {
22
26
  DataConnectorType.KAFKA: [
@@ -123,3 +127,41 @@ async def connection_ls(ctx: Context, service: Optional[DataConnectorType] = Non
123
127
  column_names = [c.replace("kafka_", "") for c in columns]
124
128
  echo_safe_humanfriendly_tables_format_smart_table(table, column_names=column_names)
125
129
  click.echo("\n")
130
+
131
+
132
+ @connection.group(name="create")
133
+ @click.pass_context
134
+ def connection_create(ctx: Context) -> None:
135
+ """Create a connection."""
136
+
137
+
138
+ @connection_create.command(name="s3", short_help="Creates a AWS S3 connection.")
139
+ @click.pass_context
140
+ @coro
141
+ async def connection_create_s3(ctx: Context) -> None:
142
+ """
143
+ Creates a AWS S3 connection.
144
+
145
+ \b
146
+ $ tb connection create s3
147
+ """
148
+ project: Project = ctx.ensure_object(dict)["project"]
149
+ obj: Dict[str, Any] = ctx.ensure_object(dict)
150
+ client: TinyB = obj["client"]
151
+ service = DataConnectorType.AMAZON_S3
152
+ connection_name = await validate_aws_iamrole_connection_name(client)
153
+ role_arn, region, external_id = await run_aws_iamrole_connection_flow(
154
+ client,
155
+ service=service,
156
+ policy="read", # For now only read since we only support import from S3
157
+ )
158
+
159
+ await generate_aws_iamrole_connection_file(
160
+ name=connection_name, service=service, role_arn=role_arn, region=region, folder=project.folder
161
+ )
162
+ if external_id:
163
+ click.echo(
164
+ FeedbackManager.success_s3_iam_connection_created(
165
+ connection_name=connection_name, external_id=external_id, role_arn=role_arn
166
+ )
167
+ )
@@ -353,6 +353,17 @@ def generate_connection_file(name: str, content: str, folder: str) -> Path:
353
353
  return f.relative_to(folder)
354
354
 
355
355
 
356
+ async def generate_aws_iamrole_connection_file(
357
+ name: str, service: str, role_arn: str, region: str, folder: str
358
+ ) -> None:
359
+ content = f"""TYPE {service}
360
+
361
+ S3_ARN {role_arn}
362
+ S3_REGION {region}
363
+ """
364
+ generate_connection_file(name, content, folder)
365
+
366
+
356
367
  def create_rules(folder: str, source: str, agent: str):
357
368
  if agent == "cursor":
358
369
  extension = ".cursorrules"
@@ -498,7 +498,7 @@ Ready? """
498
498
 
499
499
  prompt_s3_iamrole_connection_login_aws = prompt_message("""[1] Log into your AWS Console\n\n""")
500
500
  prompt_s3_iamrole_connection_policy = prompt_message(
501
- """\n[2] Go to IAM > Policies. Create a new policy with the following permissions. Please, replace {replacements}:\n\n{access_policy}\n\n(The policy has been copied to your clipboard)\n\n"""
501
+ """\n[2] Go to IAM > Policies. Create a new policy with the following permissions:\n\n{access_policy}\n\n(The policy has been copied to your clipboard)\n\n"""
502
502
  )
503
503
  prompt_s3_iamrole_connection_policy_not_copied = prompt_message(
504
504
  """\n[2] Go to IAM > Policies. Create a new policy with the following permissions. Please, copy this policy and replace <bucket> with your bucket name:\n\n{access_policy}\n\n"""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev111
3
+ Version: 0.0.1.dev112
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird