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 +1 -0
- tinybird/tb/modules/build.py +3 -13
- tinybird/tb/modules/login.py +166 -0
- {tinybird-0.0.1.dev11.dist-info → tinybird-0.0.1.dev13.dist-info}/METADATA +1 -1
- {tinybird-0.0.1.dev11.dist-info → tinybird-0.0.1.dev13.dist-info}/RECORD +8 -7
- {tinybird-0.0.1.dev11.dist-info → tinybird-0.0.1.dev13.dist-info}/WHEEL +0 -0
- {tinybird-0.0.1.dev11.dist-info → tinybird-0.0.1.dev13.dist-info}/entry_points.txt +0 -0
- {tinybird-0.0.1.dev11.dist-info → tinybird-0.0.1.dev13.dist-info}/top_level.txt +0 -0
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
|
tinybird/tb/modules/build.py
CHANGED
|
@@ -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
|
-
|
|
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."))
|
|
@@ -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
|
|
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=
|
|
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.
|
|
69
|
-
tinybird-0.0.1.
|
|
70
|
-
tinybird-0.0.1.
|
|
71
|
-
tinybird-0.0.1.
|
|
72
|
-
tinybird-0.0.1.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|