tinybird 0.0.1.dev11__py3-none-any.whl → 0.0.1.dev13__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/tb/cli.py CHANGED
@@ -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
@@ -80,19 +80,12 @@ class FileChangeHandler(FileSystemEventHandler):
80
80
  except Exception as e:
81
81
  click.echo(FeedbackManager.error_exception(error=e))
82
82
 
83
- def on_created(self, event: Any) -> None:
84
- if not event.is_directory and any(event.src_path.endswith(ext) for ext in [".datasource", ".pipe", ".ndjson"]):
85
- click.echo(FeedbackManager.highlight(message=f"\n\n⟲ Changes detected in {event.src_path}\n"))
86
- try:
87
- self.process([event.src_path])
88
- except Exception as e:
89
- click.echo(FeedbackManager.error_exception(error=e))
90
-
91
83
 
92
84
  def watch_files(
93
85
  filenames: List[str],
94
86
  process: Union[Callable[[List[str]], None], Callable[[List[str]], Awaitable[None]]],
95
87
  shell: BuildShell,
88
+ folder: str,
96
89
  ) -> None:
97
90
  # Handle both sync and async process functions
98
91
  async def process_wrapper(files: List[str]) -> None:
@@ -113,10 +106,7 @@ def watch_files(
113
106
  event_handler = FileChangeHandler(filenames, lambda f: asyncio.run(process_wrapper(f)))
114
107
  observer = Observer()
115
108
 
116
- # Watch each provided path
117
- for filename in filenames:
118
- path = filename if os.path.isdir(filename) else os.path.dirname(filename)
119
- observer.schedule(event_handler, path=path, recursive=True)
109
+ observer.schedule(event_handler, path=folder, recursive=True)
120
110
 
121
111
  observer.start()
122
112
 
@@ -238,7 +228,7 @@ async def build(
238
228
  if watch:
239
229
  shell = BuildShell(folder=folder)
240
230
  click.echo(FeedbackManager.highlight(message="◎ Watching for changes..."))
241
- watcher_thread = threading.Thread(target=watch_files, args=(filenames, process, shell), daemon=True)
231
+ watcher_thread = threading.Thread(target=watch_files, args=(filenames, process, shell, folder), daemon=True)
242
232
  watcher_thread.start()
243
233
  shell.cmdloop()
244
234
 
@@ -0,0 +1,166 @@
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
+ class AuthServer(socketserver.TCPServer):
91
+ allow_reuse_address = True
92
+
93
+ def __init__(self, server_address, RequestHandlerClass, auth_callback):
94
+ self.auth_callback = auth_callback
95
+ super().__init__(server_address, RequestHandlerClass)
96
+
97
+
98
+ def start_server(auth_callback):
99
+ with AuthServer(("", 3000), AuthHandler, auth_callback) as httpd:
100
+ httpd.timeout = 30
101
+ start_time = time.time()
102
+ while time.time() - start_time < 60: # Run for a maximum of 60 seconds
103
+ httpd.handle_request()
104
+
105
+
106
+ @cli.command()
107
+ @click.option(
108
+ "--host",
109
+ 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",
110
+ )
111
+ @click.option(
112
+ "--workspace",
113
+ help="Set the workspace to authenticate to. If not set, the default workspace will be used.",
114
+ )
115
+ def login(host: str, workspace: str):
116
+ """Authenticate via browser."""
117
+ auth_event = threading.Event()
118
+ auth_code = [None] # Using a list to store the code, as it's mutable
119
+ config = CLIConfig.get_project_config()
120
+ host = host or "https://api.tinybird.co"
121
+
122
+ def auth_callback(code):
123
+ auth_code[0] = code
124
+ auth_event.set()
125
+
126
+ click.echo("Opening browser for authentication...")
127
+
128
+ # Start the local server in a separate thread
129
+ server_thread = threading.Thread(target=start_server, args=(auth_callback,))
130
+ server_thread.daemon = True
131
+ server_thread.start()
132
+
133
+ # Open the browser to the auth page
134
+ client_id = "T6excMo8IKguvUw4vFNYfqlt9pe6msCU"
135
+ callback_url = "http://localhost:3000"
136
+ params = {
137
+ "client_id": client_id,
138
+ "redirect_uri": callback_url,
139
+ "response_type": "token",
140
+ "scope": "openid profile email",
141
+ }
142
+ auth_url = f"https://auth.tinybird.co/authorize?{urlencode(params)}"
143
+ webbrowser.open(auth_url)
144
+
145
+ # Wait for the authentication to complete or timeout
146
+ if auth_event.wait(timeout=60): # Wait for up to 60 seconds
147
+ params = {}
148
+ if workspace:
149
+ params["workspace_id"] = workspace
150
+ response = requests.get(
151
+ f"https://api.tinybird.co/v0/user/tokens?{urlencode(params)}",
152
+ headers={"Authorization": f"Bearer {auth_code[0]}"},
153
+ )
154
+ data = response.json()
155
+ cli_config = CLIConfig.get_project_config()
156
+ workspace_token = data["workspace_token"]
157
+ user_token = data["user_token"]
158
+ cli_config.set_token(workspace_token)
159
+ cli_config.set_token_for_host(workspace_token, host)
160
+ cli_config.set_user_token(user_token)
161
+ config.set_host(host)
162
+
163
+ cli_config.persist_to_file()
164
+ click.echo(FeedbackManager.success(message="✓ Authentication successful!"))
165
+ else:
166
+ 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.dev11
3
+ Version: 0.0.1.dev13
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird
@@ -15,10 +15,10 @@ tinybird/syncasync.py,sha256=fAvq0qkRgqXqXMKwbY2iJNYqLT_r6mDsh1MRpGKrdRU,27763
15
15
  tinybird/tornado_template.py,sha256=o2HguxrL1Evnt8o3IvrsI8Zm6JtRQ3zhLJKf1XyR3SQ,41965
16
16
  tinybird/ch_utils/constants.py,sha256=aYvg2C_WxYWsnqPdZB1ZFoIr8ZY-XjUXYyHKE9Ansj0,3890
17
17
  tinybird/ch_utils/engine.py,sha256=OXkBhlzGjZotjD0vaT-rFIbSGV4tpiHxE8qO_ip0SyQ,40454
18
- tinybird/tb/cli.py,sha256=6Lu3wsCNepAxjJCWy4c6RhVPArBtm8TlUcSxX--TsBo,783
18
+ tinybird/tb/cli.py,sha256=-ritrHugOxQCW7qtV1hSIW8xEHKWDILawEwlcP9AVyI,816
19
19
  tinybird/tb/modules/auth.py,sha256=hynZ-Temot8YBsySUWKSFzZlYadtFPxG3o6lCSu1n6E,9018
20
20
  tinybird/tb/modules/branch.py,sha256=R1tTUBGyI0p_dt2IAWbuyNOvemhjCIPwYxEmOxL3zOg,38468
21
- tinybird/tb/modules/build.py,sha256=aqVmey7jkb-ZDRaxl5h66u3g9bmI46_j-u3hXEPPVho,11746
21
+ tinybird/tb/modules/build.py,sha256=_kiloHo4cGdyQyp7TgCmXGHtmPP0cCL1gq1m-YcwNHQ,11181
22
22
  tinybird/tb/modules/cicd.py,sha256=KCFfywFfvGRh24GZwqrhICiTK_arHelPs_X4EB-pXIw,7331
23
23
  tinybird/tb/modules/cli.py,sha256=c-XNRu-idb2Hz43IT9ejd-QjsZy-xPQ3rnrdVIz0wxM,56568
24
24
  tinybird/tb/modules/common.py,sha256=Vubc2AIR8BfEupnT5e1Y8OYGEyvNoIcjo8th-SaUflw,80111
@@ -31,6 +31,7 @@ tinybird/tb/modules/fmt.py,sha256=UszEQO15fdzQ49QEj7Unhu68IKwSuKPsOrKhk2p2TAg,35
31
31
  tinybird/tb/modules/job.py,sha256=eoBVyA24lYIPonU88Jn7FF9hBKz1kScy9_w_oWreuc4,2952
32
32
  tinybird/tb/modules/llm.py,sha256=TvJJ9BlKISAb1SVI-pnHp_PcHcxGfTyjxOE_qAz90Ck,2441
33
33
  tinybird/tb/modules/local.py,sha256=sImiZwUMsvJRGBVZovOGBqxXo0SBWYwpZ7b8zVG_QNc,6943
34
+ tinybird/tb/modules/login.py,sha256=a96yvh9stVQXL-JGTBf8NKMrIkp3nu2oT8TymVeDz9o,5796
34
35
  tinybird/tb/modules/mock.py,sha256=RohmEhNfudVryn2pJrI4fASE74inovNxzN0ew85Y830,2747
35
36
  tinybird/tb/modules/pipe.py,sha256=9wnfKbp2FkmLiJgVk3qbra76ktwsUTXghu6j9cCEahQ,31058
36
37
  tinybird/tb/modules/prompts.py,sha256=g0cBW2ePzuftib02wV82VIcAZd59buAAusnirAbzqVE,8662
@@ -65,8 +66,8 @@ tinybird/tb_cli_modules/config.py,sha256=6NTgIdwf0X132A1j6G_YrdPep87ymZ9b5pABabK
65
66
  tinybird/tb_cli_modules/exceptions.py,sha256=pmucP4kTF4irIt7dXiG-FcnI-o3mvDusPmch1L8RCWk,3367
66
67
  tinybird/tb_cli_modules/regions.py,sha256=QjsL5H6Kg-qr0aYVLrvb1STeJ5Sx_sjvbOYO0LrEGMk,166
67
68
  tinybird/tb_cli_modules/telemetry.py,sha256=iEGnMuCuNhvF6ln__j6X9MSTwL_0Hm-GgFHHHvhfknk,10466
68
- tinybird-0.0.1.dev11.dist-info/METADATA,sha256=F7NlFSAcq7ZbchPPjfnBdz5R-QohYQSy_MwXY3YWroI,2405
69
- tinybird-0.0.1.dev11.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
70
- tinybird-0.0.1.dev11.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
71
- tinybird-0.0.1.dev11.dist-info/top_level.txt,sha256=pgw6AzERHBcW3YTi2PW4arjxLkulk2msOz_SomfOEuc,45
72
- tinybird-0.0.1.dev11.dist-info/RECORD,,
69
+ tinybird-0.0.1.dev13.dist-info/METADATA,sha256=j-z3lZinpg9H9UK5iqH4nKMe9A0KjGt3etk9EPFq94M,2405
70
+ tinybird-0.0.1.dev13.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
71
+ tinybird-0.0.1.dev13.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
72
+ tinybird-0.0.1.dev13.dist-info/top_level.txt,sha256=pgw6AzERHBcW3YTi2PW4arjxLkulk2msOz_SomfOEuc,45
73
+ tinybird-0.0.1.dev13.dist-info/RECORD,,