tinybird 0.0.1.dev158__py3-none-any.whl → 0.0.1.dev160__py3-none-any.whl
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.
- tinybird/feedback_manager.py +1 -1
- tinybird/tb/__cli__.py +2 -2
- tinybird/tb/cli.py +1 -1
- tinybird/tb/client.py +0 -7
- tinybird/tb/modules/cicd.py +6 -2
- tinybird/tb/modules/cli.py +1 -1
- tinybird/tb/modules/common.py +6 -67
- tinybird/tb/modules/deprecations.py +24 -0
- tinybird/tb/modules/feedback_manager.py +0 -8
- tinybird/tb/modules/info.py +112 -0
- tinybird/tb/modules/local_common.py +6 -6
- tinybird/tb/modules/mock.py +1 -1
- tinybird/tb/modules/workspace.py +2 -11
- {tinybird-0.0.1.dev158.dist-info → tinybird-0.0.1.dev160.dist-info}/METADATA +1 -1
- {tinybird-0.0.1.dev158.dist-info → tinybird-0.0.1.dev160.dist-info}/RECORD +18 -18
- tinybird/tb/modules/auth.py +0 -252
- {tinybird-0.0.1.dev158.dist-info → tinybird-0.0.1.dev160.dist-info}/WHEEL +0 -0
- {tinybird-0.0.1.dev158.dist-info → tinybird-0.0.1.dev160.dist-info}/entry_points.txt +0 -0
- {tinybird-0.0.1.dev158.dist-info → tinybird-0.0.1.dev160.dist-info}/top_level.txt +0 -0
tinybird/feedback_manager.py
CHANGED
|
@@ -491,7 +491,7 @@ Ready? """
|
|
|
491
491
|
"""\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"""
|
|
492
492
|
)
|
|
493
493
|
prompt_s3_iamrole_connection_policy_not_copied = prompt_message(
|
|
494
|
-
"""\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"""
|
|
494
|
+
"""\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 and <table_name> with your table name:\n\n{access_policy}\n\n"""
|
|
495
495
|
)
|
|
496
496
|
prompt_s3_iamrole_connection_role = prompt_message(
|
|
497
497
|
"""\n[3] Go to IAM > Roles. Create a new IAM Role using the following custom trust policy and attach the access policy you just created in the previous step:\n\n{trust_policy}\n\n(The policy has been copied to your clipboard)\n\n"""
|
tinybird/tb/__cli__.py
CHANGED
|
@@ -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.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '0.0.1.dev160'
|
|
8
|
+
__revision__ = '8c1a42a'
|
tinybird/tb/cli.py
CHANGED
|
@@ -4,7 +4,6 @@ import sys
|
|
|
4
4
|
if sys.platform == "win32":
|
|
5
5
|
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
|
6
6
|
|
|
7
|
-
import tinybird.tb.modules.auth
|
|
8
7
|
import tinybird.tb.modules.build
|
|
9
8
|
import tinybird.tb.modules.cli
|
|
10
9
|
import tinybird.tb.modules.common
|
|
@@ -15,6 +14,7 @@ import tinybird.tb.modules.datasource
|
|
|
15
14
|
import tinybird.tb.modules.deployment
|
|
16
15
|
import tinybird.tb.modules.deprecations
|
|
17
16
|
import tinybird.tb.modules.endpoint
|
|
17
|
+
import tinybird.tb.modules.info
|
|
18
18
|
import tinybird.tb.modules.infra
|
|
19
19
|
import tinybird.tb.modules.job
|
|
20
20
|
import tinybird.tb.modules.local
|
tinybird/tb/client.py
CHANGED
|
@@ -235,10 +235,6 @@ class TinyB:
|
|
|
235
235
|
response = await self._req("/v0/tokens")
|
|
236
236
|
return response["tokens"]
|
|
237
237
|
|
|
238
|
-
async def starterkits(self) -> List[Dict[str, Any]]:
|
|
239
|
-
data = await self._req("/v0/templates")
|
|
240
|
-
return data.get("templates", [])
|
|
241
|
-
|
|
242
238
|
async def get_token_by_name(self, name: str):
|
|
243
239
|
tokens = await self.tokens()
|
|
244
240
|
for tk in tokens:
|
|
@@ -741,13 +737,10 @@ class TinyB:
|
|
|
741
737
|
async def create_workspace(
|
|
742
738
|
self,
|
|
743
739
|
name: str,
|
|
744
|
-
template: Optional[str],
|
|
745
740
|
assign_to_organization_id: Optional[str] = None,
|
|
746
741
|
version: str = "v0",
|
|
747
742
|
):
|
|
748
743
|
url = f"/{version}/workspaces?name={name}"
|
|
749
|
-
if template:
|
|
750
|
-
url += f"&starter_kit={template}"
|
|
751
744
|
if assign_to_organization_id:
|
|
752
745
|
url += f"&assign_to_organization_id={assign_to_organization_id}"
|
|
753
746
|
return await self._req(url, method="POST", data=b"")
|
tinybird/tb/modules/cicd.py
CHANGED
|
@@ -111,12 +111,13 @@ tinybird_ci_workflow:
|
|
|
111
111
|
before_script:
|
|
112
112
|
- apt update && apt install -y curl
|
|
113
113
|
- curl https://tinybird.co | sh
|
|
114
|
+
- for i in {1..10}; do curl -s -o /dev/null "http://$TB_LOCAL_HOST" && break; sleep 5; done
|
|
114
115
|
script:
|
|
115
116
|
- export PATH="$HOME/.local/bin:$PATH"
|
|
116
117
|
- cd $CI_PROJECT_DIR/{{ data_project_dir }}
|
|
117
118
|
- tb build
|
|
118
119
|
- tb test run
|
|
119
|
-
- tb --cloud --host $
|
|
120
|
+
- tb --cloud --host "$TINYBIRD_HOST" --token "$TINYBIRD_TOKEN" deploy --check
|
|
120
121
|
services:
|
|
121
122
|
- name: tinybirdco/tinybird-local:latest
|
|
122
123
|
alias: tinybird-local
|
|
@@ -136,10 +137,13 @@ tinybird_cd_workflow:
|
|
|
136
137
|
- .gitlab/tinybird/*{% if data_project_dir != '.' %}
|
|
137
138
|
- {{ data_project_dir }}/*
|
|
138
139
|
- {{ data_project_dir }}/**/*{% end %}
|
|
140
|
+
before_script:
|
|
141
|
+
- apt update && apt install -y curl
|
|
142
|
+
- curl https://tinybird.co | sh
|
|
139
143
|
script:
|
|
140
144
|
- export PATH="$HOME/.local/bin:$PATH"
|
|
141
145
|
- cd $CI_PROJECT_DIR/{{ data_project_dir }}
|
|
142
|
-
- tb --cloud --host $
|
|
146
|
+
- tb --cloud --host "$TINYBIRD_HOST" --token "$TINYBIRD_TOKEN" deploy
|
|
143
147
|
"""
|
|
144
148
|
|
|
145
149
|
|
tinybird/tb/modules/cli.py
CHANGED
|
@@ -317,7 +317,7 @@ def __unpatch_click_output():
|
|
|
317
317
|
|
|
318
318
|
|
|
319
319
|
async def create_ctx_client(ctx: Context, config: Dict[str, Any], cloud: bool, staging: bool):
|
|
320
|
-
commands_without_ctx_client = ["auth", "check", "local", "login", "logout", "update", "upgrade", "create"]
|
|
320
|
+
commands_without_ctx_client = ["auth", "check", "local", "login", "logout", "update", "upgrade", "create", "info"]
|
|
321
321
|
command = ctx.invoked_subcommand
|
|
322
322
|
if command in commands_without_ctx_client:
|
|
323
323
|
return None
|
tinybird/tb/modules/common.py
CHANGED
|
@@ -74,7 +74,6 @@ from tinybird.tb.modules.telemetry import (
|
|
|
74
74
|
add_telemetry_sysinfo_event,
|
|
75
75
|
flush_telemetry,
|
|
76
76
|
init_telemetry,
|
|
77
|
-
is_ci_environment,
|
|
78
77
|
)
|
|
79
78
|
|
|
80
79
|
SUPPORTED_FORMATS = ["csv", "ndjson", "json", "parquet"]
|
|
@@ -116,6 +115,10 @@ async def gather_with_concurrency(n, *tasks):
|
|
|
116
115
|
return await asyncio.gather(*(sem_task(task) for task in tasks))
|
|
117
116
|
|
|
118
117
|
|
|
118
|
+
def format_robust_table(data: Iterable[Any], column_names: List[str]):
|
|
119
|
+
return humanfriendly.tables.format_robust_table(data, column_names=column_names)
|
|
120
|
+
|
|
121
|
+
|
|
119
122
|
def echo_safe_humanfriendly_tables_format_smart_table(data: Iterable[Any], column_names: List[str]) -> None:
|
|
120
123
|
"""
|
|
121
124
|
There is a bug in the humanfriendly library: it breaks to render the small table for small terminals
|
|
@@ -634,56 +637,6 @@ async def check_user_token_with_client(client: TinyB, token: str):
|
|
|
634
637
|
)
|
|
635
638
|
|
|
636
639
|
|
|
637
|
-
async def get_available_starterkits(ctx: Context) -> List[Dict[str, Any]]:
|
|
638
|
-
ctx_dict = ctx.ensure_object(dict)
|
|
639
|
-
available_starterkits = ctx_dict.get("available_starterkits", None)
|
|
640
|
-
if available_starterkits is not None:
|
|
641
|
-
return available_starterkits
|
|
642
|
-
|
|
643
|
-
try:
|
|
644
|
-
client: TinyB = ctx_dict["client"]
|
|
645
|
-
|
|
646
|
-
available_starterkits = await client.starterkits()
|
|
647
|
-
ctx_dict["available_starterkits"] = available_starterkits
|
|
648
|
-
return available_starterkits
|
|
649
|
-
except Exception as ex:
|
|
650
|
-
raise CLIException(FeedbackManager.error_exception(error=ex))
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
async def get_starterkit(ctx: Context, name: str) -> Optional[Dict[str, Any]]:
|
|
654
|
-
available_starterkits = await get_available_starterkits(ctx)
|
|
655
|
-
if not available_starterkits:
|
|
656
|
-
return None
|
|
657
|
-
return next((sk for sk in available_starterkits if sk.get("friendly_name", None) == name), None)
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
async def is_valid_starterkit(ctx: Context, name: str) -> bool:
|
|
661
|
-
return name == "blank" or (await get_starterkit(ctx, name) is not None)
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
async def ask_for_starterkit_interactively(ctx: Context) -> Optional[str]:
|
|
665
|
-
starterkit = [{"friendly_name": "blank", "description": "Empty workspace"}]
|
|
666
|
-
starterkit.extend(await get_available_starterkits(ctx))
|
|
667
|
-
rows = [(index + 1, sk["friendly_name"], sk["description"]) for index, sk in enumerate(starterkit)]
|
|
668
|
-
|
|
669
|
-
echo_safe_humanfriendly_tables_format_smart_table(rows, column_names=["Idx", "Id", "Description"])
|
|
670
|
-
click.echo("")
|
|
671
|
-
click.echo(" [0] to cancel")
|
|
672
|
-
|
|
673
|
-
sk_index = -1
|
|
674
|
-
while sk_index == -1:
|
|
675
|
-
sk_index = click.prompt("\nUse starter kit", default=1)
|
|
676
|
-
if sk_index < 0 or sk_index > len(starterkit):
|
|
677
|
-
click.echo(FeedbackManager.error_starterkit_index(starterkit_index=sk_index))
|
|
678
|
-
sk_index = -1
|
|
679
|
-
|
|
680
|
-
if sk_index == 0:
|
|
681
|
-
click.echo(FeedbackManager.info_cancelled_by_user())
|
|
682
|
-
return None
|
|
683
|
-
|
|
684
|
-
return starterkit[sk_index - 1]["friendly_name"]
|
|
685
|
-
|
|
686
|
-
|
|
687
640
|
async def fork_workspace(client: TinyB, user_client: TinyB, created_workspace):
|
|
688
641
|
config = CLIConfig.get_project_config()
|
|
689
642
|
|
|
@@ -695,22 +648,19 @@ async def fork_workspace(client: TinyB, user_client: TinyB, created_workspace):
|
|
|
695
648
|
async def create_workspace_non_interactive(
|
|
696
649
|
ctx: Context,
|
|
697
650
|
workspace_name: str,
|
|
698
|
-
starterkit: Optional[str],
|
|
699
651
|
user_token: str,
|
|
700
652
|
fork: bool,
|
|
701
653
|
organization_id: Optional[str],
|
|
702
654
|
organization_name: Optional[str],
|
|
703
655
|
):
|
|
704
|
-
"""Creates a workspace using the provided name
|
|
656
|
+
"""Creates a workspace using the provided name"""
|
|
705
657
|
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
706
658
|
|
|
707
659
|
try:
|
|
708
660
|
user_client: TinyB = deepcopy(client)
|
|
709
661
|
user_client.token = user_token
|
|
710
662
|
|
|
711
|
-
created_workspace = await user_client.create_workspace(
|
|
712
|
-
workspace_name, starterkit, organization_id, version="v1"
|
|
713
|
-
)
|
|
663
|
+
created_workspace = await user_client.create_workspace(workspace_name, organization_id, version="v1")
|
|
714
664
|
if organization_id and organization_name:
|
|
715
665
|
click.echo(
|
|
716
666
|
FeedbackManager.success_workspace_created_with_organization(
|
|
@@ -730,21 +680,11 @@ async def create_workspace_non_interactive(
|
|
|
730
680
|
async def create_workspace_interactive(
|
|
731
681
|
ctx: Context,
|
|
732
682
|
workspace_name: Optional[str],
|
|
733
|
-
starterkit: Optional[str],
|
|
734
683
|
user_token: str,
|
|
735
684
|
fork: bool,
|
|
736
685
|
organization_id: Optional[str],
|
|
737
686
|
organization_name: Optional[str],
|
|
738
687
|
):
|
|
739
|
-
if not starterkit and not is_ci_environment():
|
|
740
|
-
click.echo("\n")
|
|
741
|
-
starterkit = await ask_for_starterkit_interactively(ctx)
|
|
742
|
-
if not starterkit: # Cancelled by user
|
|
743
|
-
return
|
|
744
|
-
|
|
745
|
-
if starterkit == "blank": # 'blank' == empty workspace
|
|
746
|
-
starterkit = None
|
|
747
|
-
|
|
748
688
|
if not workspace_name:
|
|
749
689
|
"""Creates a workspace guiding the user"""
|
|
750
690
|
click.echo("\n")
|
|
@@ -758,7 +698,6 @@ async def create_workspace_interactive(
|
|
|
758
698
|
await create_workspace_non_interactive(
|
|
759
699
|
ctx,
|
|
760
700
|
workspace_name,
|
|
761
|
-
starterkit,
|
|
762
701
|
user_token,
|
|
763
702
|
fork,
|
|
764
703
|
organization_id,
|
|
@@ -4,6 +4,30 @@ from tinybird.tb.modules.cli import cli
|
|
|
4
4
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
@cli.command(
|
|
8
|
+
name="auth",
|
|
9
|
+
context_settings=dict(
|
|
10
|
+
ignore_unknown_options=True,
|
|
11
|
+
),
|
|
12
|
+
hidden=True,
|
|
13
|
+
)
|
|
14
|
+
@click.argument("args", nargs=-1, type=click.UNPROCESSED)
|
|
15
|
+
def auth(args) -> None:
|
|
16
|
+
"""
|
|
17
|
+
`tb auth` is deprecated. Use `tb login` instead.
|
|
18
|
+
"""
|
|
19
|
+
is_info_cmd = "info" in args
|
|
20
|
+
message = "This command is deprecated. Use `tb login` instead."
|
|
21
|
+
if is_info_cmd:
|
|
22
|
+
message = "This command is deprecated. Use `tb info` instead."
|
|
23
|
+
else:
|
|
24
|
+
message = "This command is deprecated. Use `tb login` instead."
|
|
25
|
+
click.echo(FeedbackManager.warning(message=message))
|
|
26
|
+
click.echo(
|
|
27
|
+
"You are using Tinybird Forward CLI.\nYou can find more information in the docs at https://www.tinybird.co/docs/forward"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
7
31
|
@cli.command(
|
|
8
32
|
name="branch",
|
|
9
33
|
context_settings=dict(
|
|
@@ -303,11 +303,6 @@ class FeedbackManager:
|
|
|
303
303
|
error_pipe_ls_type = error_message("Invalid Format provided")
|
|
304
304
|
error_token_not_validate_in_any_region = error_message("Token not validated in any region")
|
|
305
305
|
error_not_authenticated = error_message("You are not authenticated, use 'tb auth -i' to authenticate yourself")
|
|
306
|
-
error_checking_templates = error_message("Unable to retrieve list of available starter kits")
|
|
307
|
-
error_starterkit_index = error_message(
|
|
308
|
-
"Error selecting starter kit '{starterkit_index}'. Select a valid index or 0 to cancel"
|
|
309
|
-
)
|
|
310
|
-
error_starterkit_name = error_message("Unknown starter kit '{starterkit_name}'")
|
|
311
306
|
error_missing_url_or_connector = error_message(
|
|
312
307
|
"Missing url, local path or --connector argument for append to datasource '{datasource}'"
|
|
313
308
|
)
|
|
@@ -943,9 +938,6 @@ STEP 3: ADD KEY TO SERVICE ACCOUNT
|
|
|
943
938
|
info_workspace_create_greeting = info_message(
|
|
944
939
|
"Please enter the name for your new workspace. Remember the name you choose must be unique, you can add a suffix in case of collision.\nYou can bypass this step by supplying it after the command."
|
|
945
940
|
)
|
|
946
|
-
info_create_ws_msg_template = info_message(
|
|
947
|
-
"Now let's pick a starter template! 🐣\nStarter template are pre-built data projects for different use cases, that you can use as a starting point and then build on top of that.\nYou can bypass this step by supplying a value for the --starter-kit option."
|
|
948
|
-
)
|
|
949
941
|
info_workspace_branch_create_greeting = info_message(
|
|
950
942
|
"Please enter the name for your new Branch. Remember the name you choose must be unique, you can add a suffix in case of collision.\nYou can bypass this step by supplying a value for the --name option."
|
|
951
943
|
)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Any, Dict, Iterable, List, Optional
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
|
|
6
|
+
from tinybird.tb.client import TinyB
|
|
7
|
+
from tinybird.tb.config import get_display_cloud_host
|
|
8
|
+
from tinybird.tb.modules.cli import CLIConfig, cli
|
|
9
|
+
from tinybird.tb.modules.common import coro, format_robust_table
|
|
10
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
11
|
+
from tinybird.tb.modules.local_common import TB_LOCAL_ADDRESS, get_tinybird_local_config
|
|
12
|
+
from tinybird.tb.modules.project import Project
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@cli.command(name="info")
|
|
16
|
+
@click.pass_context
|
|
17
|
+
@coro
|
|
18
|
+
async def info(ctx: click.Context) -> None:
|
|
19
|
+
"""Get information about the project that is currently being used"""
|
|
20
|
+
ctx_config = ctx.ensure_object(dict)["config"]
|
|
21
|
+
project: Project = ctx.ensure_object(dict)["project"]
|
|
22
|
+
click.echo(FeedbackManager.highlight(message="» Tinybird Cloud:"))
|
|
23
|
+
await get_cloud_info(ctx_config)
|
|
24
|
+
click.echo(FeedbackManager.highlight(message="\n» Tinybird Local:"))
|
|
25
|
+
await get_local_info(ctx_config)
|
|
26
|
+
click.echo(FeedbackManager.highlight(message="\n» Project:"))
|
|
27
|
+
await get_project_info(project.folder)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
async def get_cloud_info(ctx_config: Dict[str, Any]) -> None:
|
|
31
|
+
config = CLIConfig.get_project_config()
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
client = config.get_client()
|
|
35
|
+
token = config.get_token() or "No workspace token found"
|
|
36
|
+
api_host = config.get("host") or "No API host found"
|
|
37
|
+
ui_host = get_display_cloud_host(api_host)
|
|
38
|
+
user_email = config.get("user_email") or "No user email found"
|
|
39
|
+
user_token = config.get_user_token() or "No user token found"
|
|
40
|
+
await get_env_info(client, ctx_config, user_email, token, user_token, api_host, ui_host)
|
|
41
|
+
except Exception:
|
|
42
|
+
click.echo(
|
|
43
|
+
FeedbackManager.warning(
|
|
44
|
+
message="\n⚠ Could not retrieve Tinybird Cloud info. Please run `tb login` first or check that you are located in the correct directory."
|
|
45
|
+
)
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
async def get_local_info(config: Dict[str, Any]) -> None:
|
|
50
|
+
try:
|
|
51
|
+
local_config = await get_tinybird_local_config(config, test=False, silent=False)
|
|
52
|
+
local_client = local_config.get_client(host=TB_LOCAL_ADDRESS, staging=False)
|
|
53
|
+
user_email = local_config.get_user_email() or "No user email found"
|
|
54
|
+
token = local_config.get_token() or "No token found"
|
|
55
|
+
user_token = local_config.get_user_token() or "No user token found"
|
|
56
|
+
api_host = TB_LOCAL_ADDRESS
|
|
57
|
+
ui_host = get_display_cloud_host(api_host)
|
|
58
|
+
await get_env_info(local_client, config, user_email, token, user_token, api_host, ui_host)
|
|
59
|
+
except Exception:
|
|
60
|
+
click.echo(
|
|
61
|
+
FeedbackManager.warning(
|
|
62
|
+
message="\n⚠ Could not retrieve Tinybird Local info. Please run `tb local start` first."
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
async def get_env_info(
|
|
69
|
+
client: TinyB, config: Dict[str, Any], user_email: str, token: str, user_token: str, api_host: str, ui_host: str
|
|
70
|
+
) -> None:
|
|
71
|
+
user_workspaces = await client.user_workspaces(version="v1")
|
|
72
|
+
current_workspace = await client.workspace_info(version="v1")
|
|
73
|
+
|
|
74
|
+
def _get_current_workspace(user_workspaces: Dict[str, Any], current_workspace_id: str) -> Optional[Dict[str, Any]]:
|
|
75
|
+
def get_workspace_by_name(workspaces: List[Dict[str, Any]], name: str) -> Optional[Dict[str, Any]]:
|
|
76
|
+
return next((ws for ws in workspaces if ws["name"] == name), None)
|
|
77
|
+
|
|
78
|
+
workspaces: Optional[List[Dict[str, Any]]] = user_workspaces.get("workspaces")
|
|
79
|
+
if not workspaces:
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
current: Optional[Dict[str, Any]] = get_workspace_by_name(workspaces, current_workspace_id)
|
|
83
|
+
return current
|
|
84
|
+
|
|
85
|
+
current_main_workspace = _get_current_workspace(user_workspaces, config.get("name") or current_workspace["name"])
|
|
86
|
+
|
|
87
|
+
assert isinstance(current_main_workspace, dict)
|
|
88
|
+
|
|
89
|
+
columns = ["user", "workspace_name", "workspace_id", "token", "user_token", "api", "ui"]
|
|
90
|
+
if current_main_workspace["name"]:
|
|
91
|
+
ui_host += f"/{current_main_workspace['name']}"
|
|
92
|
+
table = [
|
|
93
|
+
(user_email, current_main_workspace["name"], current_main_workspace["id"], token, user_token, api_host, ui_host)
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
click.echo(format_robust_table(table, column_names=columns))
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
async def get_project_info(project_path: Optional[str] = None) -> None:
|
|
100
|
+
config = CLIConfig.get_project_config()
|
|
101
|
+
tinyb_path = config.get_tinyb_file()
|
|
102
|
+
current_path = os.getcwd()
|
|
103
|
+
project_path = current_path
|
|
104
|
+
if tinyb_path:
|
|
105
|
+
tinyb_dir = os.path.dirname(tinyb_path)
|
|
106
|
+
project_path = os.path.join(tinyb_dir, project_path)
|
|
107
|
+
else:
|
|
108
|
+
tinyb_path = "Not found"
|
|
109
|
+
|
|
110
|
+
columns = ["current", ".tinyb", "project"]
|
|
111
|
+
table: Iterable[Any] = [(current_path, tinyb_path, project_path)]
|
|
112
|
+
click.echo(format_robust_table(table, column_names=columns))
|
|
@@ -20,14 +20,16 @@ TB_LOCAL_HOST = re.sub(r"^https?://", "", os.getenv("TB_LOCAL_HOST", "localhost"
|
|
|
20
20
|
TB_LOCAL_ADDRESS = f"http://{TB_LOCAL_HOST}:{TB_LOCAL_PORT}"
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
async def get_tinybird_local_client(
|
|
23
|
+
async def get_tinybird_local_client(
|
|
24
|
+
config_obj: Dict[str, Any], test: bool = False, staging: bool = False, silent: bool = False
|
|
25
|
+
) -> TinyB:
|
|
24
26
|
"""Get a Tinybird client connected to the local environment."""
|
|
25
27
|
|
|
26
|
-
config = await get_tinybird_local_config(config_obj, test=test)
|
|
28
|
+
config = await get_tinybird_local_config(config_obj, test=test, silent=silent)
|
|
27
29
|
return config.get_client(host=TB_LOCAL_ADDRESS, staging=staging)
|
|
28
30
|
|
|
29
31
|
|
|
30
|
-
async def get_tinybird_local_config(config_obj: Dict[str, Any], test: bool = False) -> CLIConfig:
|
|
32
|
+
async def get_tinybird_local_config(config_obj: Dict[str, Any], test: bool = False, silent: bool = False) -> CLIConfig:
|
|
31
33
|
"""Craft a client config with a workspace name based on the path of the project files
|
|
32
34
|
|
|
33
35
|
It uses the tokens from tinybird local
|
|
@@ -90,9 +92,7 @@ async def get_tinybird_local_config(config_obj: Dict[str, Any], test: bool = Fal
|
|
|
90
92
|
ws = None
|
|
91
93
|
|
|
92
94
|
if not ws:
|
|
93
|
-
await user_client.create_workspace(
|
|
94
|
-
ws_name, template=None, assign_to_organization_id=user_org_id, version="v1"
|
|
95
|
-
)
|
|
95
|
+
await user_client.create_workspace(ws_name, assign_to_organization_id=user_org_id, version="v1")
|
|
96
96
|
user_workspaces = requests.get(f"{TB_LOCAL_ADDRESS}/v1/user/workspaces?token={admin_token}").json()
|
|
97
97
|
ws = next((ws for ws in user_workspaces["workspaces"] if ws["name"] == ws_name), None)
|
|
98
98
|
if not ws:
|
tinybird/tb/modules/mock.py
CHANGED
|
@@ -62,7 +62,7 @@ async def mock(ctx: click.Context, datasource: str, rows: int, prompt: str, form
|
|
|
62
62
|
datasource_path = Path(datasource_from_glob[0])
|
|
63
63
|
|
|
64
64
|
if not datasource_path.exists():
|
|
65
|
-
raise Exception(f"Datasource '{datasource_path.stem}' not
|
|
65
|
+
raise Exception(f"Datasource '{datasource_path.stem}' not found")
|
|
66
66
|
|
|
67
67
|
datasource_content = datasource_path.read_text()
|
|
68
68
|
config = CLIConfig.get_project_config()
|
tinybird/tb/modules/workspace.py
CHANGED
|
@@ -20,7 +20,6 @@ from tinybird.tb.modules.common import (
|
|
|
20
20
|
get_current_main_workspace,
|
|
21
21
|
get_organizations_by_user,
|
|
22
22
|
get_user_token,
|
|
23
|
-
is_valid_starterkit,
|
|
24
23
|
switch_workspace,
|
|
25
24
|
try_update_config_with_remote,
|
|
26
25
|
)
|
|
@@ -133,8 +132,6 @@ async def workspace_current(ctx: Context):
|
|
|
133
132
|
|
|
134
133
|
@workspace.command(name="create", short_help="Create a new Workspace for your Tinybird user")
|
|
135
134
|
@click.argument("workspace_name", required=False)
|
|
136
|
-
@click.option("--starter_kit", "starter_kit", type=str, required=False, help="Use a Tinybird starter kit as a template")
|
|
137
|
-
@click.option("--starter-kit", "starter_kit", hidden=True)
|
|
138
135
|
@click.option("--user_token", is_flag=False, default=None, help="When passed, tb won't prompt asking for the token")
|
|
139
136
|
@click.option(
|
|
140
137
|
"--fork",
|
|
@@ -154,14 +151,10 @@ async def workspace_current(ctx: Context):
|
|
|
154
151
|
async def create_workspace(
|
|
155
152
|
ctx: Context,
|
|
156
153
|
workspace_name: str,
|
|
157
|
-
starter_kit: str,
|
|
158
154
|
user_token: Optional[str],
|
|
159
155
|
fork: bool,
|
|
160
156
|
organization_id: Optional[str],
|
|
161
157
|
) -> None:
|
|
162
|
-
if starter_kit and not await is_valid_starterkit(ctx, starter_kit):
|
|
163
|
-
raise CLIWorkspaceException(FeedbackManager.error_starterkit_name(starterkit_name=starter_kit))
|
|
164
|
-
|
|
165
158
|
config = CLIConfig.get_project_config()
|
|
166
159
|
|
|
167
160
|
user_token = await get_user_token(config, user_token)
|
|
@@ -177,12 +170,10 @@ async def create_workspace(
|
|
|
177
170
|
# process, creating an empty workspace
|
|
178
171
|
if workspace_name:
|
|
179
172
|
await create_workspace_non_interactive(
|
|
180
|
-
ctx, workspace_name,
|
|
173
|
+
ctx, workspace_name, user_token, fork, organization_id, organization_name
|
|
181
174
|
)
|
|
182
175
|
else:
|
|
183
|
-
await create_workspace_interactive(
|
|
184
|
-
ctx, workspace_name, starter_kit, user_token, fork, organization_id, organization_name
|
|
185
|
-
)
|
|
176
|
+
await create_workspace_interactive(ctx, workspace_name, user_token, fork, organization_id, organization_name)
|
|
186
177
|
|
|
187
178
|
|
|
188
179
|
@workspace.command(name="delete", short_help="Delete a workspace for your Tinybird user")
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
tinybird/connectors.py,sha256=7Gjms7b5MAaBFGi3xytsJurCylprONpFcYrzp4Fw2Rc,15241
|
|
2
2
|
tinybird/context.py,sha256=FfqYfrGX_I7PKGTQo93utaKPDNVYWelg4Hsp3evX5wM,1291
|
|
3
3
|
tinybird/datatypes.py,sha256=r4WCvspmrXTJHiPjjyOTiZyZl31FO3Ynkwq4LQsYm6E,11059
|
|
4
|
-
tinybird/feedback_manager.py,sha256=
|
|
4
|
+
tinybird/feedback_manager.py,sha256=1INQFfRfuMCb9lfB8KNf4r6qC2khW568hoHjtk-wshI,69305
|
|
5
5
|
tinybird/git_settings.py,sha256=Sw_8rGmribEFJ4Z_6idrVytxpFYk7ez8ei0qHULzs3E,3934
|
|
6
6
|
tinybird/prompts.py,sha256=yLXzHB7_P0zjriIvI9UsfnIRwmcwLSEA1tcJMzYJqjw,36456
|
|
7
7
|
tinybird/sql.py,sha256=C_B81wwv3BsqyXGhF5oTk9DcTUkrp7NwIFqSzd3Dmjc,47854
|
|
@@ -12,37 +12,37 @@ tinybird/syncasync.py,sha256=IPnOx6lMbf9SNddN1eBtssg8vCLHMt76SuZ6YNYm-Yk,27761
|
|
|
12
12
|
tinybird/tornado_template.py,sha256=jjNVDMnkYFWXflmT8KU_Ssbo5vR8KQq3EJMk5vYgXRw,41959
|
|
13
13
|
tinybird/ch_utils/constants.py,sha256=aYvg2C_WxYWsnqPdZB1ZFoIr8ZY-XjUXYyHKE9Ansj0,3890
|
|
14
14
|
tinybird/ch_utils/engine.py,sha256=BZuPM7MFS7vaEKK5tOMR2bwSAgJudPrJt27uVEwZmTY,40512
|
|
15
|
-
tinybird/tb/__cli__.py,sha256=
|
|
15
|
+
tinybird/tb/__cli__.py,sha256=s6LSSQKjMUCbqgJA61muv1NTc64EeZdFL1buos31pag,247
|
|
16
16
|
tinybird/tb/check_pypi.py,sha256=rW4QmDRbtgKdUUwJCnBkVjmTjZSZGN-XgZhx7vMkC0w,1009
|
|
17
|
-
tinybird/tb/cli.py,sha256=
|
|
18
|
-
tinybird/tb/client.py,sha256=
|
|
17
|
+
tinybird/tb/cli.py,sha256=u3eGOhX0MHkuT6tiwaZ0_3twqLmqKXDAOxF7yV_Nn9Q,1075
|
|
18
|
+
tinybird/tb/client.py,sha256=CSBl_JRuioPyY0H8Ac96dJ9wQXDXfrvK2lwqlOxKGoY,55715
|
|
19
19
|
tinybird/tb/config.py,sha256=jT9xndpeCY_g0HdB5qE2EquC0TFRRnkPnQFWZWd04jo,3998
|
|
20
|
-
tinybird/tb/modules/auth.py,sha256=_OeYnmTH83lnqCgQEdS6K0bx1KBUeRmZk2M7JnRmWpk,9037
|
|
21
20
|
tinybird/tb/modules/build.py,sha256=sj77FyQRAtAQdifY8sqVzPzeIUKsxUDwPsz17NSRsVA,18517
|
|
22
|
-
tinybird/tb/modules/cicd.py,sha256=
|
|
23
|
-
tinybird/tb/modules/cli.py,sha256=
|
|
24
|
-
tinybird/tb/modules/common.py,sha256=
|
|
21
|
+
tinybird/tb/modules/cicd.py,sha256=MnShTTJzKBYeajswF2jg7p7ZzupaeCgSriAN05MeEdg,7330
|
|
22
|
+
tinybird/tb/modules/cli.py,sha256=jJ7vF05vppwqetaHiEyk_x2YFb6S53PS-PmYlNMRcTc,14274
|
|
23
|
+
tinybird/tb/modules/common.py,sha256=_mNLBzC7zkveYXgJ02aMJ9L3LrxsAELx84GwEYdWNa0,82955
|
|
25
24
|
tinybird/tb/modules/config.py,sha256=ziqW_t_mRVvWOd85VoB4vKyvgMkEfpXDf9H4v38p2xc,11422
|
|
26
25
|
tinybird/tb/modules/connection.py,sha256=7oOR7x4PhBcm1ETFFCH2YJ_3oeGXjAbmx1cnZX9_L70,9014
|
|
27
26
|
tinybird/tb/modules/copy.py,sha256=2Mm4FWKehOG7CoOhiF1m9UZJgJn0W1_cMolqju8ONYg,5805
|
|
28
27
|
tinybird/tb/modules/create.py,sha256=OHUvuHuvP0iecPPGI4eVOHOgR20qy7a_Sw7sbJKuG8g,17411
|
|
29
28
|
tinybird/tb/modules/datasource.py,sha256=V314rkpdVxVMjsp5qcSCTqDlmp4Vu--qM07BoWh-aqs,17783
|
|
30
29
|
tinybird/tb/modules/deployment.py,sha256=a6CZrYqAM-t6WxGKjgg16ZvncpZBta5gBq7YEBPBoQc,25811
|
|
31
|
-
tinybird/tb/modules/deprecations.py,sha256=
|
|
30
|
+
tinybird/tb/modules/deprecations.py,sha256=rrszC1f_JJeJ8mUxGoCxckQTJFBCR8wREf4XXXN-PRc,4507
|
|
32
31
|
tinybird/tb/modules/dev_server.py,sha256=57FCKuWpErwYUYgHspYDkLWEm9F4pbvVOtMrFXX1fVU,10129
|
|
33
32
|
tinybird/tb/modules/endpoint.py,sha256=XySDt3pk66vxOZ0egUfz4bY8bEk3BjOXkv-L0OIJ3sc,12083
|
|
34
33
|
tinybird/tb/modules/exceptions.py,sha256=5jK91w1LPmtqIUfDpHe_Op5OxGz8-p1BPgtLREMIni0,5217
|
|
35
|
-
tinybird/tb/modules/feedback_manager.py,sha256=
|
|
34
|
+
tinybird/tb/modules/feedback_manager.py,sha256=c0ZOpG7IHFq3doodezctX64cTcTquIOhO38w9uPuU8Q,76798
|
|
35
|
+
tinybird/tb/modules/info.py,sha256=AThOatkAjN1HbmARIU0MaQ-N4ZmZlZqoAxN18FQRa6M,4797
|
|
36
36
|
tinybird/tb/modules/infra.py,sha256=fve30Gj3mG9zbquGxS2e4ipcOYOxviWQCpNFfEzJN_Q,33195
|
|
37
37
|
tinybird/tb/modules/job.py,sha256=n4dSSBgnA8NqD7srGahf2xRj6wxkmX9Vl0J-QJ_a2w0,2966
|
|
38
38
|
tinybird/tb/modules/llm.py,sha256=KfsCYmKeW1VQz0iDZhGKCRkQv_Y3kTHh6JuxvofOguE,1076
|
|
39
39
|
tinybird/tb/modules/llm_utils.py,sha256=nS9r4FAElJw8yXtmdYrx-rtI2zXR8qXfi1QqUDCfxvg,3469
|
|
40
40
|
tinybird/tb/modules/local.py,sha256=SUaGWH9TLDFFF9uCw4y7UW4NsKgnXG8uxTcxz1dbkCM,14230
|
|
41
|
-
tinybird/tb/modules/local_common.py,sha256=
|
|
41
|
+
tinybird/tb/modules/local_common.py,sha256=OoBUFrMjXvQ3y8hHscpyVH9wMI7h0m79F7G6EiMSku0,4783
|
|
42
42
|
tinybird/tb/modules/login.py,sha256=fmXPSdvJnKPv03chptGuu3_Fm6LhP6kUsUKhrmT8rJc,8269
|
|
43
43
|
tinybird/tb/modules/logout.py,sha256=ULooy1cDBD02-r7voZmhV7udA0ML5tVuflJyShrh56Y,1022
|
|
44
44
|
tinybird/tb/modules/materialization.py,sha256=QJX5kCPhhm6IXBO1JsalVfbQdypCe_eOUDZ_WHJZWS8,5478
|
|
45
|
-
tinybird/tb/modules/mock.py,sha256=
|
|
45
|
+
tinybird/tb/modules/mock.py,sha256=IyHweMUM6bUH8IhyiX2tTMpdVpTFUeAJ41lZ5P42-HQ,5303
|
|
46
46
|
tinybird/tb/modules/open.py,sha256=OuctINN77oexpSjth9uoIZPCelKO4Li-yyVxeSnk1io,1371
|
|
47
47
|
tinybird/tb/modules/pipe.py,sha256=AQKEDagO6e3psPVjJkS_MDbn8aK-apAiLp26k7jgAV0,2432
|
|
48
48
|
tinybird/tb/modules/project.py,sha256=PwEG8Ob9bW4HZxh1jQq2LyDfIoitqF69Jdu0WsWHMCg,3568
|
|
@@ -54,7 +54,7 @@ tinybird/tb/modules/telemetry.py,sha256=X0p5AVkM8BNsK_Rhdcg4p2eIf6OHimHO_VLldBqH
|
|
|
54
54
|
tinybird/tb/modules/test.py,sha256=Yopg89cRwOQpgRzsb9nvu2Z-UR2as2vBjVa5PF3uiK0,13420
|
|
55
55
|
tinybird/tb/modules/token.py,sha256=2fmKwu10_M0pqs6YmJVeILR9ZQB0ejRAET86agASbKM,13488
|
|
56
56
|
tinybird/tb/modules/watch.py,sha256=_92co0BjTikQuy7MbHr4TDu9A75QdHsrAO8v7DlYLg4,8898
|
|
57
|
-
tinybird/tb/modules/workspace.py,sha256=
|
|
57
|
+
tinybird/tb/modules/workspace.py,sha256=h4Re1_2DahZ9C-yF7vgquMrYiG7Gj62jNfbzkEJR2BY,8066
|
|
58
58
|
tinybird/tb/modules/workspace_members.py,sha256=RYLpyPM1ECCasHRg3uvpckzXplX0_KgNFsSPZn_i6qk,8744
|
|
59
59
|
tinybird/tb/modules/datafile/build.py,sha256=d_h3pRFDPFrDKGhpFx2iejY25GuB2k8yfNouj6s8caw,50973
|
|
60
60
|
tinybird/tb/modules/datafile/build_common.py,sha256=LU24kAQmxDJIyoIapDaYG-SU3P4FrMG9UBf8m9PgVSI,4565
|
|
@@ -80,8 +80,8 @@ tinybird/tb_cli_modules/config.py,sha256=IsgdtFRnUrkY8-Zo32lmk6O7u3bHie1QCxLwgp4
|
|
|
80
80
|
tinybird/tb_cli_modules/exceptions.py,sha256=pmucP4kTF4irIt7dXiG-FcnI-o3mvDusPmch1L8RCWk,3367
|
|
81
81
|
tinybird/tb_cli_modules/regions.py,sha256=QjsL5H6Kg-qr0aYVLrvb1STeJ5Sx_sjvbOYO0LrEGMk,166
|
|
82
82
|
tinybird/tb_cli_modules/telemetry.py,sha256=Hh2Io8ZPROSunbOLuMvuIFU4TqwWPmQTqal4WS09K1A,10449
|
|
83
|
-
tinybird-0.0.1.
|
|
84
|
-
tinybird-0.0.1.
|
|
85
|
-
tinybird-0.0.1.
|
|
86
|
-
tinybird-0.0.1.
|
|
87
|
-
tinybird-0.0.1.
|
|
83
|
+
tinybird-0.0.1.dev160.dist-info/METADATA,sha256=Chpz-yZJB3bxzzpn-NhpeLHWx_lb5E5grl70FLLx618,1607
|
|
84
|
+
tinybird-0.0.1.dev160.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
85
|
+
tinybird-0.0.1.dev160.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
|
|
86
|
+
tinybird-0.0.1.dev160.dist-info/top_level.txt,sha256=VqqqEmkAy7UNaD8-V51FCoMMWXjLUlR0IstvK7tJYVY,54
|
|
87
|
+
tinybird-0.0.1.dev160.dist-info/RECORD,,
|
tinybird/tb/modules/auth.py
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
# This is a command file for our CLI. Please keep it clean.
|
|
2
|
-
#
|
|
3
|
-
# - If it makes sense and only when strictly necessary, you can create utility functions in this file.
|
|
4
|
-
# - But please, **do not** interleave utility functions and command definitions.
|
|
5
|
-
|
|
6
|
-
import os
|
|
7
|
-
from typing import Any, Dict, List, Optional
|
|
8
|
-
|
|
9
|
-
import click
|
|
10
|
-
import humanfriendly.tables
|
|
11
|
-
|
|
12
|
-
from tinybird.tb.config import get_display_cloud_host
|
|
13
|
-
from tinybird.tb.modules.cli import cli
|
|
14
|
-
from tinybird.tb.modules.common import (
|
|
15
|
-
configure_connector,
|
|
16
|
-
coro,
|
|
17
|
-
echo_safe_humanfriendly_tables_format_smart_table,
|
|
18
|
-
get_host_from_region,
|
|
19
|
-
get_regions,
|
|
20
|
-
try_authenticate,
|
|
21
|
-
try_update_config_with_remote,
|
|
22
|
-
)
|
|
23
|
-
from tinybird.tb.modules.config import CLIConfig, ConfigValueOrigin
|
|
24
|
-
from tinybird.tb.modules.exceptions import CLIAuthException
|
|
25
|
-
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
26
|
-
from tinybird.tb.modules.regions import Region
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@cli.group(invoke_without_command=True)
|
|
30
|
-
@click.option("--token", help="Use auth token, defaults to TB_TOKEN envvar, then to the .tinyb file")
|
|
31
|
-
@click.option(
|
|
32
|
-
"--host",
|
|
33
|
-
help="Set custom host if it's different than https://api.tinybird.co. Check https://www.tinybird.co/docs/api-reference#regions-and-endpoints for the available list of regions",
|
|
34
|
-
)
|
|
35
|
-
@click.option(
|
|
36
|
-
"--region", envvar="TB_REGION", help="Set region. Run 'tb auth ls' to show available regions. Overrides host."
|
|
37
|
-
)
|
|
38
|
-
@click.option(
|
|
39
|
-
"--connector",
|
|
40
|
-
type=click.Choice(["bigquery", "snowflake"], case_sensitive=True),
|
|
41
|
-
help="Set credentials for one of the supported connectors",
|
|
42
|
-
)
|
|
43
|
-
@click.option(
|
|
44
|
-
"-i",
|
|
45
|
-
"--interactive",
|
|
46
|
-
is_flag=True,
|
|
47
|
-
default=False,
|
|
48
|
-
help="Show available regions and select where to authenticate to",
|
|
49
|
-
)
|
|
50
|
-
@click.pass_context
|
|
51
|
-
@coro
|
|
52
|
-
async def auth(ctx: click.Context, token: str, host: str, region: str, connector: str, interactive: bool) -> None:
|
|
53
|
-
"""Configure auth."""
|
|
54
|
-
|
|
55
|
-
config: CLIConfig = CLIConfig.get_project_config()
|
|
56
|
-
if token:
|
|
57
|
-
config.set_token(token)
|
|
58
|
-
if host:
|
|
59
|
-
config.set_host(host)
|
|
60
|
-
|
|
61
|
-
if connector:
|
|
62
|
-
await configure_connector(connector)
|
|
63
|
-
return
|
|
64
|
-
|
|
65
|
-
# Only run when doing a bare 'tb auth'
|
|
66
|
-
if ctx.invoked_subcommand:
|
|
67
|
-
return
|
|
68
|
-
|
|
69
|
-
assert isinstance(ctx.parent, click.Context)
|
|
70
|
-
|
|
71
|
-
env_token = os.environ.get("TB_TOKEN", None)
|
|
72
|
-
|
|
73
|
-
# If no token passed, let's clear the current one to
|
|
74
|
-
# do a clean auth
|
|
75
|
-
if not token and not ctx.parent.params.get("token") and not env_token:
|
|
76
|
-
config.set_token(None)
|
|
77
|
-
else:
|
|
78
|
-
if env_token and not token:
|
|
79
|
-
click.echo(FeedbackManager.info_reading_from_env(value="token", envvar="TB_TOKEN"))
|
|
80
|
-
|
|
81
|
-
regions: Optional[List[Region]] = None
|
|
82
|
-
try_all_regions = True
|
|
83
|
-
|
|
84
|
-
if host:
|
|
85
|
-
try_all_regions = False
|
|
86
|
-
|
|
87
|
-
if region:
|
|
88
|
-
regions, host = await get_host_from_region(config, region, config.get_host())
|
|
89
|
-
config.set_host(host)
|
|
90
|
-
if token:
|
|
91
|
-
config.set_token_for_host(token, host)
|
|
92
|
-
try_all_regions = False
|
|
93
|
-
|
|
94
|
-
if not await try_authenticate(config, regions=regions, interactive=interactive, try_all_regions=try_all_regions):
|
|
95
|
-
raise CLIAuthException(FeedbackManager.error_invalid_token_for_host(host=config.get_host()))
|
|
96
|
-
|
|
97
|
-
config.persist_to_file()
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
@auth.command(name="login", hidden=True)
|
|
101
|
-
@click.option(
|
|
102
|
-
"--host",
|
|
103
|
-
help="Set custom host if it's different than https://api.tinybird.co. Use `tb auth ls` or check https://docs.tinybird.co/cli.html for the available list of regions.",
|
|
104
|
-
)
|
|
105
|
-
@click.argument("token", required=False)
|
|
106
|
-
@coro
|
|
107
|
-
async def auth_login(host: Optional[str], token: Optional[str]) -> None:
|
|
108
|
-
"""Authenticate with a Tinybird host.
|
|
109
|
-
|
|
110
|
-
The authentication mode is token based. After completion, the authentication token
|
|
111
|
-
will be stored internally.
|
|
112
|
-
|
|
113
|
-
You need your User Token to log into Tinybird. Please, check the docs at
|
|
114
|
-
https://www.tinybird.co/docs/concepts/auth-tokens.html for more info.
|
|
115
|
-
|
|
116
|
-
Alternatively, tb will use the authentication token found in the environment
|
|
117
|
-
variable TB_USER_TOKEN. This method is most suitable for "headless" use of tb
|
|
118
|
-
such as in automations or in a CI environment."""
|
|
119
|
-
config = CLIConfig.get_project_config()
|
|
120
|
-
|
|
121
|
-
if host:
|
|
122
|
-
config.set_host(host)
|
|
123
|
-
|
|
124
|
-
if not token:
|
|
125
|
-
click.echo(FeedbackManager.info_pre_prompt_auth_login_user_token(host=config.get_host()))
|
|
126
|
-
token = click.prompt(FeedbackManager.prompt_auth_login_user_token(), type=str, hide_input=True)
|
|
127
|
-
if not token:
|
|
128
|
-
raise CLIAuthException(FeedbackManager.error_auth_login_token_expected())
|
|
129
|
-
config.set_user_token(token)
|
|
130
|
-
|
|
131
|
-
auth_info: Dict[str, Any] = await config.get_user_client().check_auth_login()
|
|
132
|
-
if not auth_info.get("is_valid", False):
|
|
133
|
-
raise CLIAuthException(FeedbackManager.error_auth_login_not_valid(host=config.get_host()))
|
|
134
|
-
|
|
135
|
-
if not auth_info.get("is_user", False):
|
|
136
|
-
raise CLIAuthException(FeedbackManager.error_auth_login_not_user(host=config.get_host()))
|
|
137
|
-
|
|
138
|
-
config.persist_to_file()
|
|
139
|
-
|
|
140
|
-
# No more output needed as per "The art of UNIX programming"
|
|
141
|
-
# http://www.catb.org/~esr/writings/taoup/html/ch11s09.html
|
|
142
|
-
# > be chatty only about things that deviate from what's normally expected.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
@auth.command(name="logout", hidden=True)
|
|
146
|
-
@coro
|
|
147
|
-
async def auth_logout() -> None:
|
|
148
|
-
"""Remove authentication from Tinybird."""
|
|
149
|
-
conf = CLIConfig.get_project_config()
|
|
150
|
-
conf.set_user_token(None)
|
|
151
|
-
conf.persist_to_file()
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
@auth.command(name="info")
|
|
155
|
-
@coro
|
|
156
|
-
async def auth_info() -> None:
|
|
157
|
-
"""Get information about the authentication that is currently being used"""
|
|
158
|
-
|
|
159
|
-
config = CLIConfig.get_project_config()
|
|
160
|
-
_ = await try_update_config_with_remote(config, raise_on_errors=False)
|
|
161
|
-
|
|
162
|
-
if "id" in config:
|
|
163
|
-
table = []
|
|
164
|
-
user_email = config.get("user_email", "No user")
|
|
165
|
-
|
|
166
|
-
ORIGINS: Dict[ConfigValueOrigin, str] = {
|
|
167
|
-
ConfigValueOrigin.CONFIG: ".tinyb",
|
|
168
|
-
ConfigValueOrigin.DEFAULT: ".tinyb",
|
|
169
|
-
ConfigValueOrigin.ENVIRONMENT: "env",
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
token_origin = ORIGINS.get(config.get_value_origin("token"), "")
|
|
173
|
-
token = f"{config.get_token()} ({token_origin})"
|
|
174
|
-
|
|
175
|
-
host = config.get("host") or ""
|
|
176
|
-
ui_host = get_display_cloud_host(host)
|
|
177
|
-
|
|
178
|
-
if config.get_user_token():
|
|
179
|
-
user_token_origin = ORIGINS.get(config.get_value_origin("user_token"), "")
|
|
180
|
-
user_token = f"{config.get_user_token()} ({user_token_origin})"
|
|
181
|
-
columns = ["user", "user_token", "token", "host", "ui", "workspace_name", "workspace_id"]
|
|
182
|
-
table.append([user_email, user_token, token, host, ui_host, config["name"], config["id"]])
|
|
183
|
-
else:
|
|
184
|
-
columns = ["user", "token", "host", "ui", "workspace_name", "workspace_id"]
|
|
185
|
-
table.append([user_email, token, host, ui_host, config["name"], config["id"]])
|
|
186
|
-
|
|
187
|
-
click.echo(humanfriendly.tables.format_robust_table(table, column_names=columns))
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
@auth.command(name="ls")
|
|
191
|
-
@coro
|
|
192
|
-
async def auth_ls() -> None:
|
|
193
|
-
"""List available regions to authenticate."""
|
|
194
|
-
|
|
195
|
-
click.echo(FeedbackManager.info_available_regions())
|
|
196
|
-
|
|
197
|
-
config = CLIConfig.get_project_config()
|
|
198
|
-
_ = await try_update_config_with_remote(config, raise_on_errors=False)
|
|
199
|
-
|
|
200
|
-
table: List[List[Any]] = []
|
|
201
|
-
regions: List[Region] = await get_regions(config)
|
|
202
|
-
if regions:
|
|
203
|
-
|
|
204
|
-
def is_current(region: Region) -> bool:
|
|
205
|
-
return region["host"] == config.get("host") or region["api_host"] == config.get("host")
|
|
206
|
-
|
|
207
|
-
for index, region in enumerate(regions):
|
|
208
|
-
table.append(
|
|
209
|
-
[
|
|
210
|
-
index + 1,
|
|
211
|
-
region["name"].lower(),
|
|
212
|
-
region.get("provider") or "",
|
|
213
|
-
region["host"],
|
|
214
|
-
region["api_host"],
|
|
215
|
-
is_current(region),
|
|
216
|
-
]
|
|
217
|
-
)
|
|
218
|
-
else:
|
|
219
|
-
table.append([1, "default", "", config["host"], True])
|
|
220
|
-
|
|
221
|
-
columns: List[str] = ["idx", "region", "provider", "ui", "host", "current"]
|
|
222
|
-
echo_safe_humanfriendly_tables_format_smart_table(table, column_names=columns)
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
@auth.command(name="use")
|
|
226
|
-
@click.argument("region_name_or_host_or_id")
|
|
227
|
-
@coro
|
|
228
|
-
async def auth_use(region_name_or_host_or_id: str) -> None:
|
|
229
|
-
"""Switch to a different region.
|
|
230
|
-
You can pass the region name, the region host url, or the region index
|
|
231
|
-
after listing available regions with 'tb auth ls'
|
|
232
|
-
|
|
233
|
-
\b
|
|
234
|
-
Example usage:
|
|
235
|
-
\b
|
|
236
|
-
$ tb auth use us-east
|
|
237
|
-
$ tb auth use 1
|
|
238
|
-
$ tb auth use https://ui.us-east.tinybird.co
|
|
239
|
-
"""
|
|
240
|
-
|
|
241
|
-
config = CLIConfig.get_project_config()
|
|
242
|
-
_ = await try_update_config_with_remote(config, raise_on_errors=False)
|
|
243
|
-
|
|
244
|
-
regions, host = await get_host_from_region(config, region_name_or_host_or_id, config.get_host())
|
|
245
|
-
config.set_host(host)
|
|
246
|
-
|
|
247
|
-
if not await try_authenticate(config, regions):
|
|
248
|
-
msg = FeedbackManager.error_wrong_config_file(config_file=config._path)
|
|
249
|
-
raise CLIAuthException(msg)
|
|
250
|
-
|
|
251
|
-
config.persist_to_file()
|
|
252
|
-
click.echo(FeedbackManager.success_now_using_config(name=config["name"], id=config["id"]))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|