tinybird 0.0.1.dev12__tar.gz → 0.0.1.dev14__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 (92) hide show
  1. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/PKG-INFO +1 -1
  2. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/cli.py +1 -0
  3. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/cli.py +2 -9
  4. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/diff.py +2 -2
  5. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/pull.py +17 -21
  6. tinybird-0.0.1.dev14/tinybird/tb/modules/login.py +169 -0
  7. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird.egg-info/PKG-INFO +1 -1
  8. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird.egg-info/SOURCES.txt +1 -0
  9. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/setup.cfg +0 -0
  10. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/__cli__.py +0 -0
  11. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/ch_utils/constants.py +0 -0
  12. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/ch_utils/engine.py +0 -0
  13. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/check_pypi.py +0 -0
  14. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/client.py +0 -0
  15. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/config.py +0 -0
  16. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/connectors.py +0 -0
  17. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/context.py +0 -0
  18. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/datafile.py +0 -0
  19. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/datatypes.py +0 -0
  20. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/feedback_manager.py +0 -0
  21. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/git_settings.py +0 -0
  22. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/sql.py +0 -0
  23. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/sql_template.py +0 -0
  24. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/sql_template_fmt.py +0 -0
  25. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/sql_toolset.py +0 -0
  26. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/syncasync.py +0 -0
  27. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/auth.py +0 -0
  28. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/branch.py +0 -0
  29. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/build.py +0 -0
  30. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/cicd.py +0 -0
  31. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/common.py +0 -0
  32. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/config.py +0 -0
  33. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/connection.py +0 -0
  34. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/create.py +0 -0
  35. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/build.py +0 -0
  36. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/build_common.py +0 -0
  37. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  38. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  39. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/common.py +0 -0
  40. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/exceptions.py +0 -0
  41. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/fixture.py +0 -0
  42. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/format_common.py +0 -0
  43. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  44. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  45. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/parse_datasource.py +0 -0
  46. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/parse_pipe.py +0 -0
  47. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  48. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/datasource.py +0 -0
  49. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/exceptions.py +0 -0
  50. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/fmt.py +0 -0
  51. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/job.py +0 -0
  52. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/llm.py +0 -0
  53. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/local.py +0 -0
  54. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/mock.py +0 -0
  55. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/pipe.py +0 -0
  56. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/prompts.py +0 -0
  57. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/regions.py +0 -0
  58. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/table.py +0 -0
  59. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/tag.py +0 -0
  60. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/telemetry.py +0 -0
  61. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/test.py +0 -0
  62. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  63. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  64. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/token.py +0 -0
  65. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/workspace.py +0 -0
  66. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb/modules/workspace_members.py +0 -0
  67. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli.py +0 -0
  68. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/auth.py +0 -0
  69. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/branch.py +0 -0
  70. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/cicd.py +0 -0
  71. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/cli.py +0 -0
  72. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/common.py +0 -0
  73. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/config.py +0 -0
  74. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/connection.py +0 -0
  75. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/datasource.py +0 -0
  76. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/exceptions.py +0 -0
  77. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/fmt.py +0 -0
  78. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/job.py +0 -0
  79. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/pipe.py +0 -0
  80. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/regions.py +0 -0
  81. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/tag.py +0 -0
  82. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/telemetry.py +0 -0
  83. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/test.py +0 -0
  84. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  85. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  86. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/workspace.py +0 -0
  87. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  88. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird/tornado_template.py +0 -0
  89. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird.egg-info/dependency_links.txt +0 -0
  90. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird.egg-info/entry_points.txt +0 -0
  91. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird.egg-info/requires.txt +0 -0
  92. {tinybird-0.0.1.dev12 → tinybird-0.0.1.dev14}/tinybird.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tinybird
3
- Version: 0.0.1.dev12
3
+ Version: 0.0.1.dev14
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird
@@ -14,6 +14,7 @@ import tinybird.tb.modules.create
14
14
  import tinybird.tb.modules.datasource
15
15
  import tinybird.tb.modules.fmt
16
16
  import tinybird.tb.modules.job
17
+ import tinybird.tb.modules.login
17
18
  import tinybird.tb.modules.mock
18
19
  import tinybird.tb.modules.pipe
19
20
  import tinybird.tb.modules.tag
@@ -565,24 +565,17 @@ async def push(
565
565
  @click.option(
566
566
  "--folder", default=None, type=click.Path(exists=True, file_okay=False), help="Folder where files will be placed"
567
567
  )
568
- @click.option(
569
- "--auto/--no-auto",
570
- is_flag=True,
571
- default=True,
572
- help="Saves datafiles automatically into their default directories (/datasources or /pipes). Default is True",
573
- )
574
- @click.option("--match", default=None, help="Retrieve any resourcing matching the pattern. eg --match _test")
575
568
  @click.option("-f", "--force", is_flag=True, default=False, help="Override existing files")
576
569
  @click.option("--fmt", is_flag=True, default=False, help="Format files before saving")
577
570
  @click.pass_context
578
571
  @coro
579
- async def pull(ctx: Context, folder: str, auto: bool, match: Optional[str], force: bool, fmt: bool) -> None:
572
+ async def pull(ctx: Context, folder: str, force: bool, fmt: bool) -> None:
580
573
  """Retrieve latest versions for project files from Tinybird."""
581
574
 
582
575
  client = ctx.ensure_object(dict)["client"]
583
576
  folder = folder if folder else getcwd()
584
577
 
585
- return await folder_pull(client, folder, auto, match, force, fmt=fmt)
578
+ return await folder_pull(client, folder, force, fmt=fmt)
586
579
 
587
580
 
588
581
  @cli.command()
@@ -121,12 +121,12 @@ async def diff_command(
121
121
  if filenames:
122
122
  if len(filenames) == 1:
123
123
  filenames = [filenames[0], *get_project_filenames(filenames[0])]
124
- await folder_pull(client, target_dir, False, None, True, verbose=False)
124
+ await folder_pull(client, target_dir, True, verbose=False)
125
125
  else:
126
126
  filenames = get_project_filenames(".")
127
127
  if verbose:
128
128
  click.echo("Saving remote resources in .diff_tmp folder.\n")
129
- await folder_pull(client, target_dir, False, None, True, verbose=verbose, progress_bar=progress_bar)
129
+ await folder_pull(client, target_dir, True, verbose=verbose, progress_bar=progress_bar)
130
130
 
131
131
  remote_datasources: List[Dict[str, Any]] = await client.datasources()
132
132
  remote_pipes: List[Dict[str, Any]] = await client.pipes()
@@ -1,7 +1,7 @@
1
1
  import re
2
2
  from asyncio import Semaphore, gather
3
3
  from pathlib import Path
4
- from typing import Any, Dict, List, Optional
4
+ from typing import Any, Dict, List, Optional, Tuple
5
5
 
6
6
  import aiofiles
7
7
  import click
@@ -16,38 +16,39 @@ from tinybird.tb.modules.datafile.format_pipe import format_pipe
16
16
  async def folder_pull(
17
17
  client: TinyB,
18
18
  folder: str,
19
- auto: bool,
20
- match: Optional[str],
21
19
  force: bool,
22
20
  verbose: bool = True,
23
21
  progress_bar: bool = False,
24
22
  fmt: bool = False,
25
23
  ):
26
- pattern = re.compile(match) if match else None
27
-
28
- def _get_latest_versions(resources: List[str]):
24
+ def _get_latest_versions(resources: List[Tuple[str, str]]):
29
25
  versions: Dict[str, Any] = {}
30
26
 
31
- for x in resources:
27
+ for x, resource_type in resources:
32
28
  t = get_name_version(x)
33
29
  t["original_name"] = x
34
30
  if t["version"] is None:
35
31
  t["version"] = -1
36
32
  name = t["name"]
33
+ t["type"] = resource_type
37
34
 
38
35
  if name not in versions or name == x or versions[name]["version"] < t["version"]:
39
36
  versions[name] = t
40
37
  return versions
41
38
 
42
- def get_file_folder(extension: str):
43
- if not auto:
44
- return None
39
+ def get_file_folder(extension: str, resource_type: Optional[str]):
45
40
  if extension == "datasource":
46
41
  return "datasources"
42
+ if resource_type == "endpoint":
43
+ return "endpoints"
44
+ if resource_type == "sink":
45
+ return "sinks"
46
+ if resource_type == "copy":
47
+ return "copies"
48
+ if resource_type == "materialized":
49
+ return "materializations"
47
50
  if extension == "pipe":
48
51
  return "pipes"
49
- if extension == "token":
50
- return "tokens"
51
52
  return None
52
53
 
53
54
  async def write_files(
@@ -61,11 +62,6 @@ async def folder_pull(
61
62
  async def write_resource(k: Dict[str, Any]):
62
63
  name = f"{k['name']}.{extension}"
63
64
  try:
64
- if pattern and not pattern.search(name):
65
- if verbose:
66
- click.echo(FeedbackManager.info_skipping_resource(resource=name))
67
- return
68
-
69
65
  resource = await getattr(client, get_resource_function)(k["original_name"])
70
66
  resource_to_write = resource
71
67
 
@@ -76,11 +72,11 @@ async def folder_pull(
76
72
  resource_to_write = await format_pipe(name, content=resource)
77
73
 
78
74
  dest_folder = folder
79
- if "." in k["name"] and extension != "token":
75
+ if "." in k["name"]:
80
76
  dest_folder = Path(folder) / "vendor" / k["name"].split(".", 1)[0]
81
77
  name = f"{k['name'].split('.', 1)[1]}.{extension}"
82
78
 
83
- file_folder = get_file_folder(extension)
79
+ file_folder = get_file_folder(extension, k["type"])
84
80
  f = Path(dest_folder) / file_folder if file_folder is not None else Path(dest_folder)
85
81
 
86
82
  if not f.exists():
@@ -125,11 +121,11 @@ async def folder_pull(
125
121
 
126
122
  try:
127
123
  datasources = await client.datasources()
128
- remote_datasources = sorted([x["name"] for x in datasources])
124
+ remote_datasources = sorted([(x["name"], x.get("type", "csv")) for x in datasources], key=lambda x: x[0])
129
125
  datasources_versions = _get_latest_versions(remote_datasources)
130
126
 
131
127
  pipes = await client.pipes()
132
- remote_pipes = sorted([x["name"] for x in pipes])
128
+ remote_pipes = sorted([(pipe["name"], pipe.get("type", "default")) for pipe in pipes], key=lambda x: x[0])
133
129
  pipes_versions = _get_latest_versions(remote_pipes)
134
130
 
135
131
  resources = list(datasources_versions.keys()) + list(pipes_versions.keys())
@@ -0,0 +1,169 @@
1
+ import http.server
2
+ import socketserver
3
+ import threading
4
+ import time
5
+ import urllib.parse
6
+ import webbrowser
7
+ from urllib.parse import urlencode
8
+
9
+ import click
10
+ import requests
11
+
12
+ from tinybird.feedback_manager import FeedbackManager
13
+ from tinybird.tb.modules.cli import CLIConfig, cli
14
+
15
+
16
+ class AuthHandler(http.server.SimpleHTTPRequestHandler):
17
+ def do_GET(self):
18
+ # The access_token is in the URL fragment, which is not sent to the server
19
+ # We'll send a small HTML page that extracts the token and sends it back to the server
20
+ self.send_response(200)
21
+ self.send_header("Content-type", "text/html")
22
+ self.end_headers()
23
+ self.wfile.write(b"""
24
+ <html>
25
+ <head>
26
+ <style>
27
+ body {
28
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
29
+ background: #f5f5f5;
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: center;
33
+ height: 100vh;
34
+ margin: 0;
35
+ }
36
+ .message {
37
+ background: white;
38
+ padding: 2rem 3rem;
39
+ border-radius: 8px;
40
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
41
+ text-align: center;
42
+ display: flex;
43
+ flex-direction: column;
44
+ align-items: center;
45
+ }
46
+ h1 {
47
+ color: #25283D;
48
+ font-size: 1.2rem;
49
+ margin: 0;
50
+ font-weight: 500;
51
+ }
52
+ </style>
53
+ </head>
54
+ <body>
55
+ <div class="message">
56
+ <h1>Authenticating...</h1>
57
+ </div>
58
+ <script>
59
+ var hash = window.location.hash.substr(1);
60
+ var access_token = new URLSearchParams(hash).get('access_token');
61
+ window.history.pushState({}, '', '/');
62
+ fetch('/?token=' + access_token, {method: 'POST'})
63
+ .then(() => {
64
+ document.querySelector('.message h1').textContent = 'Authentication successful! You can close this window.';
65
+ });
66
+ </script>
67
+ </body>
68
+ </html>
69
+ """)
70
+
71
+ def do_POST(self):
72
+ parsed_path = urllib.parse.urlparse(self.path)
73
+ query_params = urllib.parse.parse_qs(parsed_path.query)
74
+
75
+ if "token" in query_params:
76
+ token = query_params["token"][0]
77
+ self.server.auth_callback(token)
78
+ self.send_response(200)
79
+ self.end_headers()
80
+ else:
81
+ self.send_error(400, "Missing 'token' parameter")
82
+
83
+ self.server.shutdown()
84
+
85
+ def log_message(self, format, *args):
86
+ # Suppress log messages
87
+ return
88
+
89
+
90
+ AUTH_SERVER_PORT = 49160
91
+
92
+
93
+ class AuthServer(socketserver.TCPServer):
94
+ allow_reuse_address = True
95
+
96
+ def __init__(self, server_address, RequestHandlerClass, auth_callback):
97
+ self.auth_callback = auth_callback
98
+ super().__init__(server_address, RequestHandlerClass)
99
+
100
+
101
+ def start_server(auth_callback):
102
+ with AuthServer(("", AUTH_SERVER_PORT), AuthHandler, auth_callback) as httpd:
103
+ httpd.timeout = 30
104
+ start_time = time.time()
105
+ while time.time() - start_time < 60: # Run for a maximum of 60 seconds
106
+ httpd.handle_request()
107
+
108
+
109
+ @cli.command()
110
+ @click.option(
111
+ "--host",
112
+ help="Set custom host if it's different than https://api.tinybird.co. Check https://www.tinybird.co/docs/api-reference/overview#regions-and-endpoints for the available list of regions",
113
+ )
114
+ @click.option(
115
+ "--workspace",
116
+ help="Set the workspace to authenticate to. If not set, the default workspace will be used.",
117
+ )
118
+ def login(host: str, workspace: str):
119
+ """Authenticate via browser."""
120
+ auth_event = threading.Event()
121
+ auth_code = [None] # Using a list to store the code, as it's mutable
122
+ config = CLIConfig.get_project_config()
123
+ host = host or "https://api.tinybird.co"
124
+
125
+ def auth_callback(code):
126
+ auth_code[0] = code
127
+ auth_event.set()
128
+
129
+ click.echo("Opening browser for authentication...")
130
+
131
+ # Start the local server in a separate thread
132
+ server_thread = threading.Thread(target=start_server, args=(auth_callback,))
133
+ server_thread.daemon = True
134
+ server_thread.start()
135
+
136
+ # Open the browser to the auth page
137
+ client_id = "T6excMo8IKguvUw4vFNYfqlt9pe6msCU"
138
+ callback_url = f"http://localhost:{AUTH_SERVER_PORT}"
139
+ params = {
140
+ "client_id": client_id,
141
+ "redirect_uri": callback_url,
142
+ "response_type": "token",
143
+ "scope": "openid profile email",
144
+ }
145
+ auth_url = f"https://auth.tinybird.co/authorize?{urlencode(params)}"
146
+ webbrowser.open(auth_url)
147
+
148
+ # Wait for the authentication to complete or timeout
149
+ if auth_event.wait(timeout=60): # Wait for up to 60 seconds
150
+ params = {}
151
+ if workspace:
152
+ params["workspace_id"] = workspace
153
+ response = requests.get(
154
+ f"https://api.tinybird.co/v0/user/tokens?{urlencode(params)}",
155
+ headers={"Authorization": f"Bearer {auth_code[0]}"},
156
+ )
157
+ data = response.json()
158
+ cli_config = CLIConfig.get_project_config()
159
+ workspace_token = data["workspace_token"]
160
+ user_token = data["user_token"]
161
+ cli_config.set_token(workspace_token)
162
+ cli_config.set_token_for_host(workspace_token, host)
163
+ cli_config.set_user_token(user_token)
164
+ config.set_host(host)
165
+
166
+ cli_config.persist_to_file()
167
+ click.echo(FeedbackManager.success(message="✓ Authentication successful!"))
168
+ else:
169
+ click.echo(FeedbackManager.error(message="Authentication failed or timed out."))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tinybird
3
- Version: 0.0.1.dev12
3
+ Version: 0.0.1.dev14
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird
@@ -39,6 +39,7 @@ tinybird/tb/modules/fmt.py
39
39
  tinybird/tb/modules/job.py
40
40
  tinybird/tb/modules/llm.py
41
41
  tinybird/tb/modules/local.py
42
+ tinybird/tb/modules/login.py
42
43
  tinybird/tb/modules/mock.py
43
44
  tinybird/tb/modules/pipe.py
44
45
  tinybird/tb/modules/prompts.py
File without changes