tinybird 0.0.1.dev265__py3-none-any.whl → 0.0.1.dev267__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 +2 -2
- tinybird/tb/client.py +15 -3
- tinybird/tb/modules/agent/agent.py +46 -29
- tinybird/tb/modules/agent/banner.py +8 -25
- tinybird/tb/modules/agent/models.py +8 -0
- tinybird/tb/modules/cli.py +2 -4
- tinybird/tb/modules/deployment_common.py +4 -1
- tinybird/tb/modules/token.py +33 -12
- {tinybird-0.0.1.dev265.dist-info → tinybird-0.0.1.dev267.dist-info}/METADATA +1 -1
- {tinybird-0.0.1.dev265.dist-info → tinybird-0.0.1.dev267.dist-info}/RECORD +13 -13
- {tinybird-0.0.1.dev265.dist-info → tinybird-0.0.1.dev267.dist-info}/WHEEL +0 -0
- {tinybird-0.0.1.dev265.dist-info → tinybird-0.0.1.dev267.dist-info}/entry_points.txt +0 -0
- {tinybird-0.0.1.dev265.dist-info → tinybird-0.0.1.dev267.dist-info}/top_level.txt +0 -0
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.dev267'
|
|
8
|
+
__revision__ = '8c3d4f6'
|
tinybird/tb/client.py
CHANGED
|
@@ -870,9 +870,15 @@ class TinyB:
|
|
|
870
870
|
data={"operation": "change_role", "users": users, "new_role": role},
|
|
871
871
|
)
|
|
872
872
|
|
|
873
|
-
def workspace(
|
|
874
|
-
|
|
875
|
-
|
|
873
|
+
def workspace(
|
|
874
|
+
self, workspace_id: str, with_token: bool = False, with_organization: bool = False, version: str = "v0"
|
|
875
|
+
):
|
|
876
|
+
params = {}
|
|
877
|
+
if with_token:
|
|
878
|
+
params["with_token"] = "true"
|
|
879
|
+
if with_organization:
|
|
880
|
+
params["with_organization"] = "true"
|
|
881
|
+
return self._req(f"/{version}/workspaces/{workspace_id}?{urlencode(params)}")
|
|
876
882
|
|
|
877
883
|
def workspace_info(self, version: str = "v0") -> Dict[str, Any]:
|
|
878
884
|
return self._req(f"/{version}/workspace")
|
|
@@ -880,6 +886,12 @@ class TinyB:
|
|
|
880
886
|
def organization(self, organization_id: str):
|
|
881
887
|
return self._req(f"/v0/organizations/{organization_id}")
|
|
882
888
|
|
|
889
|
+
def organization_limits(self, organization_id: str):
|
|
890
|
+
return self._req(f"/v1/billing/{organization_id}/limits")
|
|
891
|
+
|
|
892
|
+
def organization_subscription(self, organization_id: str):
|
|
893
|
+
return self._req(f"/v1/billing/{organization_id}/subscription")
|
|
894
|
+
|
|
883
895
|
def create_organization(
|
|
884
896
|
self,
|
|
885
897
|
name: str,
|
|
@@ -3,6 +3,7 @@ import shlex
|
|
|
3
3
|
import subprocess
|
|
4
4
|
import sys
|
|
5
5
|
import urllib.parse
|
|
6
|
+
import uuid
|
|
6
7
|
from functools import partial
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from typing import Any, Optional
|
|
@@ -10,7 +11,6 @@ from typing import Any, Optional
|
|
|
10
11
|
import click
|
|
11
12
|
import humanfriendly
|
|
12
13
|
from pydantic_ai import Agent, RunContext, Tool
|
|
13
|
-
from pydantic_ai.agent import AgentRunResult
|
|
14
14
|
from pydantic_ai.messages import ModelMessage, ModelRequest, UserPromptPart
|
|
15
15
|
from requests import Response
|
|
16
16
|
|
|
@@ -19,7 +19,7 @@ from tinybird.tb.modules.agent.animations import ThinkingAnimation
|
|
|
19
19
|
from tinybird.tb.modules.agent.banner import display_banner
|
|
20
20
|
from tinybird.tb.modules.agent.command_agent import CommandAgent
|
|
21
21
|
from tinybird.tb.modules.agent.memory import clear_history, clear_messages, load_messages, save_messages
|
|
22
|
-
from tinybird.tb.modules.agent.models import create_model
|
|
22
|
+
from tinybird.tb.modules.agent.models import create_model
|
|
23
23
|
from tinybird.tb.modules.agent.prompts import agent_system_prompt, load_custom_project_rules, resources_prompt
|
|
24
24
|
from tinybird.tb.modules.agent.testing_agent import TestingAgent
|
|
25
25
|
from tinybird.tb.modules.agent.tools.analyze import analyze_file, analyze_url
|
|
@@ -254,14 +254,14 @@ class TinybirdAgent:
|
|
|
254
254
|
save_messages(new_messages)
|
|
255
255
|
self.thinking_animation.stop()
|
|
256
256
|
click.echo(result.output)
|
|
257
|
-
self.
|
|
257
|
+
self.echo_usage(config)
|
|
258
258
|
|
|
259
|
-
async def run_iter(self, user_prompt: str, config: dict[str, Any]) -> None:
|
|
259
|
+
async def run_iter(self, user_prompt: str, config: dict[str, Any], model: Any) -> None:
|
|
260
260
|
user_prompt = f"{user_prompt}\n\n{load_custom_project_rules(self.project.folder)}"
|
|
261
261
|
self.thinking_animation.start()
|
|
262
262
|
deps = self._build_agent_deps(config)
|
|
263
263
|
|
|
264
|
-
async with self.agent.iter(user_prompt, deps=deps, message_history=self.messages) as agent_run:
|
|
264
|
+
async with self.agent.iter(user_prompt, deps=deps, message_history=self.messages, model=model) as agent_run:
|
|
265
265
|
async for node in agent_run:
|
|
266
266
|
if hasattr(node, "model_response"):
|
|
267
267
|
for _i, part in enumerate(node.model_response.parts):
|
|
@@ -278,22 +278,32 @@ class TinybirdAgent:
|
|
|
278
278
|
self.messages.extend(new_messages)
|
|
279
279
|
save_messages(new_messages)
|
|
280
280
|
self.thinking_animation.stop()
|
|
281
|
-
self.
|
|
282
|
-
|
|
283
|
-
def
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
281
|
+
self.echo_usage(config)
|
|
282
|
+
|
|
283
|
+
def echo_usage(self, config: dict[str, Any]) -> None:
|
|
284
|
+
try:
|
|
285
|
+
client = _get_tb_client(config["user_token"], config["host"])
|
|
286
|
+
workspace_id = config.get("id", "")
|
|
287
|
+
workspace = client.workspace(workspace_id, with_organization=True, version="v1")
|
|
288
|
+
limits_data = client.organization_limits(workspace["organization"]["id"])
|
|
289
|
+
ai_requests_limits = limits_data.get("limits", {}).get("ai_requests", {})
|
|
290
|
+
current_ai_requests = ai_requests_limits.get("quantity") or 0
|
|
291
|
+
max_ai_requests = ai_requests_limits.get("max") or 0
|
|
292
|
+
remaining_requests = max(max_ai_requests - current_ai_requests, 0)
|
|
293
|
+
current_ai_requests = min(max_ai_requests, current_ai_requests)
|
|
294
|
+
if not max_ai_requests:
|
|
295
|
+
return
|
|
296
|
+
warning_threshold = max_ai_requests * 0.8
|
|
297
|
+
message_color = (
|
|
298
|
+
FeedbackManager.warning if current_ai_requests >= warning_threshold else FeedbackManager.gray
|
|
299
|
+
)
|
|
300
|
+
click.echo(
|
|
301
|
+
message_color(
|
|
302
|
+
message=f"{remaining_requests} requests left ({current_ai_requests}/{max_ai_requests}). You can continue using Tinybird Code. Limits will be enforced soon."
|
|
303
|
+
)
|
|
292
304
|
)
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
click.echo(f"Total tokens: {total_tokens}")
|
|
296
|
-
click.echo(f"Cost: ${cost:.6f}")
|
|
305
|
+
except Exception:
|
|
306
|
+
pass
|
|
297
307
|
|
|
298
308
|
|
|
299
309
|
def run_agent(
|
|
@@ -325,7 +335,7 @@ def run_agent(
|
|
|
325
335
|
workspace_id = cli_config.get("id", "")
|
|
326
336
|
workspace_name = cli_config.get("name", "")
|
|
327
337
|
|
|
328
|
-
if not token or not host or not user_token:
|
|
338
|
+
if not token or not host or not user_token or not workspace_id:
|
|
329
339
|
click.echo(
|
|
330
340
|
FeedbackManager.error(message="Tinybird Code requires authentication. Run 'tb login' first.")
|
|
331
341
|
)
|
|
@@ -369,8 +379,17 @@ def run_agent(
|
|
|
369
379
|
|
|
370
380
|
# Interactive mode: show banner and enter interactive loop
|
|
371
381
|
display_banner()
|
|
372
|
-
click.echo(
|
|
373
|
-
|
|
382
|
+
click.echo(
|
|
383
|
+
FeedbackManager.info(
|
|
384
|
+
message="""Tips for getting started:
|
|
385
|
+
- Describe what you want to build or ask for specific resources.
|
|
386
|
+
- Run tb commands directly without leaving interactive mode.
|
|
387
|
+
- Create a TINYBIRD.md file to customize your interactions.
|
|
388
|
+
"""
|
|
389
|
+
)
|
|
390
|
+
)
|
|
391
|
+
agent.echo_usage(config)
|
|
392
|
+
click.echo()
|
|
374
393
|
|
|
375
394
|
except Exception as e:
|
|
376
395
|
click.echo(FeedbackManager.error(message=f"Failed to initialize agent: {e}"))
|
|
@@ -417,16 +436,14 @@ def run_agent(
|
|
|
417
436
|
|
|
418
437
|
continue
|
|
419
438
|
elif user_input.lower() == "/help":
|
|
420
|
-
|
|
421
|
-
click.echo("• Ask for specific resources: 'Create a pipe to aggregate daily clicks'")
|
|
422
|
-
click.echo("• Connect to external services: 'Set up a Kafka connection for events'")
|
|
423
|
-
click.echo("• Type '/exit' or '/quit' to leave")
|
|
424
|
-
|
|
439
|
+
subprocess.run(["tb", "--help"], check=True)
|
|
425
440
|
continue
|
|
426
441
|
elif user_input.strip() == "":
|
|
427
442
|
continue
|
|
428
443
|
else:
|
|
429
|
-
|
|
444
|
+
run_id = str(uuid.uuid4())
|
|
445
|
+
model = create_model(user_token, host, workspace_id, run_id=run_id)
|
|
446
|
+
asyncio.run(agent.run_iter(user_input, config, model))
|
|
430
447
|
except AgentRunCancelled:
|
|
431
448
|
click.echo(FeedbackManager.info(message="User cancelled the operation"))
|
|
432
449
|
agent.add_message(
|
|
@@ -41,31 +41,14 @@ def display_banner():
|
|
|
41
41
|
|
|
42
42
|
click.echo("\n")
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
" ██║ ██║██║ ╚████║ ██║ ██████╔╝██║██║ ██║██████╔╝ ╚██████╗╚██████╔╝██████╔╝███████╗",
|
|
53
|
-
" ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═════╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝",
|
|
54
|
-
]
|
|
55
|
-
else:
|
|
56
|
-
# ASCII fallback banner
|
|
57
|
-
banner = [
|
|
58
|
-
" ████████T██I███N ██N██ ██Y██████B ██I██████B ██████B ██████C ██████O ██████D ███████E",
|
|
59
|
-
" ╚══██╔══╝██║████╗ ██║╚██╗ ██╔╝██╔══██╗██║██╔══██╗██╔══██╗ ██╔════╝██╔═══██╗██╔══██╗██╔════╝",
|
|
60
|
-
" ██║ ██║██╔██╗ ██║ ╚████╔╝ ██████╔╝██║██████╔╝██║ ██║ ██║ ██║ ██║██║ ██║█████╗ ",
|
|
61
|
-
" ██║ ██║██║╚██╗██║ ╚██╔╝ ██╔══██╗██║██╔══██╗██║ ██║ ██║ ██║ ██║██║ ██║██╔══╝ ",
|
|
62
|
-
" ██║ ██║██║ ╚████║ ██║ ██████╔╝██║██║ ██║██████╔╝ ╚██████╗╚██████╔╝██████╔╝███████╗",
|
|
63
|
-
" ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═════╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝",
|
|
64
|
-
]
|
|
65
|
-
|
|
66
|
-
def interpolate_color(start_rgb, end_rgb, factor):
|
|
67
|
-
"""Interpolate between two RGB colors"""
|
|
68
|
-
return [int(start_rgb[i] + (end_rgb[i] - start_rgb[i]) * factor) for i in range(3)]
|
|
44
|
+
banner = [
|
|
45
|
+
" ████████╗██╗███╗ ██╗██╗ ██╗██████╗ ██╗██████╗ ██████╗ ██████╗ ██████╗ ██████╗ ███████╗",
|
|
46
|
+
" ╚══██╔══╝██║████╗ ██║╚██╗ ██╔╝██╔══██╗██║██╔══██╗██╔══██╗ ██╔════╝██╔═══██╗██╔══██╗██╔════╝",
|
|
47
|
+
" ██║ ██║██╔██╗ ██║ ╚████╔╝ ██████╔╝██║██████╔╝██║ ██║ ██║ ██║ ██║██║ ██║█████╗ ",
|
|
48
|
+
" ██║ ██║██║╚██╗██║ ╚██╔╝ ██╔══██╗██║██╔══██╗██║ ██║ ██║ ██║ ██║██║ ██║██╔══╝ ",
|
|
49
|
+
" ██║ ██║██║ ╚████║ ██║ ██████╔╝██║██║ ██║██████╔╝ ╚██████╗╚██████╔╝██████╔╝███████╗",
|
|
50
|
+
" ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═════╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝",
|
|
51
|
+
]
|
|
69
52
|
|
|
70
53
|
def rgb_to_ansi(r: int, g: int, b: int, use_truecolor: bool):
|
|
71
54
|
"""Convert RGB values to ANSI escape code"""
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
1
3
|
from anthropic import AsyncAnthropic
|
|
2
4
|
from httpx import AsyncClient
|
|
3
5
|
from pydantic_ai.models.anthropic import AnthropicModel, AnthropicModelName
|
|
@@ -9,11 +11,17 @@ def create_model(
|
|
|
9
11
|
base_url: str,
|
|
10
12
|
workspace_id: str,
|
|
11
13
|
model: AnthropicModelName = "claude-4-sonnet-20250514",
|
|
14
|
+
run_id: Optional[str] = None,
|
|
12
15
|
):
|
|
16
|
+
default_headers = {}
|
|
17
|
+
if run_id:
|
|
18
|
+
default_headers["X-Run-Id"] = run_id
|
|
19
|
+
|
|
13
20
|
client = AsyncAnthropic(
|
|
14
21
|
base_url=base_url,
|
|
15
22
|
http_client=AsyncClient(params={"token": token, "workspace_id": workspace_id}),
|
|
16
23
|
auth_token=token,
|
|
24
|
+
default_headers=default_headers,
|
|
17
25
|
)
|
|
18
26
|
return AnthropicModel(
|
|
19
27
|
model_name=model,
|
tinybird/tb/modules/cli.py
CHANGED
|
@@ -47,8 +47,6 @@ DEFAULT_PATTERNS: List[Tuple[str, Union[str, Callable[[str], str]]]] = [
|
|
|
47
47
|
]
|
|
48
48
|
VERSION = f"{__cli__.__version__} (rev {__cli__.__revision__})"
|
|
49
49
|
|
|
50
|
-
agent_mode_flag = os.environ.get("TB_AGENT_MODE", "false") == "true"
|
|
51
|
-
|
|
52
50
|
|
|
53
51
|
@click.group(
|
|
54
52
|
cls=CatchAuthExceptions,
|
|
@@ -56,7 +54,7 @@ agent_mode_flag = os.environ.get("TB_AGENT_MODE", "false") == "true"
|
|
|
56
54
|
"help_option_names": ["-h", "--help"],
|
|
57
55
|
"max_content_width": shutil.get_terminal_size().columns - 10,
|
|
58
56
|
},
|
|
59
|
-
invoke_without_command=
|
|
57
|
+
invoke_without_command=True,
|
|
60
58
|
)
|
|
61
59
|
@click.option(
|
|
62
60
|
"--debug/--no-debug",
|
|
@@ -208,7 +206,7 @@ def cli(
|
|
|
208
206
|
ctx.ensure_object(dict)["env"] = get_target_env(cloud)
|
|
209
207
|
ctx.ensure_object(dict)["output"] = output
|
|
210
208
|
|
|
211
|
-
is_agent_mode =
|
|
209
|
+
is_agent_mode = ctx.invoked_subcommand is None
|
|
212
210
|
is_prompt_mode = prompt is not None
|
|
213
211
|
|
|
214
212
|
if is_agent_mode or is_prompt_mode:
|
|
@@ -254,9 +254,12 @@ def create_deployment(
|
|
|
254
254
|
elif verbose and f.get("level", "").upper() == "INFO":
|
|
255
255
|
feedback_func = FeedbackManager.info
|
|
256
256
|
feedback_icon = ""
|
|
257
|
+
else:
|
|
258
|
+
feedback_func = None
|
|
257
259
|
resource = f.get("resource")
|
|
258
260
|
resource_bit = f"{resource}: " if resource else ""
|
|
259
|
-
|
|
261
|
+
if feedback_func is not None:
|
|
262
|
+
click.echo(feedback_func(message=f"{feedback_icon}{f.get('level')}: {resource_bit}{f.get('message')}"))
|
|
260
263
|
|
|
261
264
|
deploy_errors = deployment.get("errors")
|
|
262
265
|
for deploy_error in deploy_errors:
|
tinybird/tb/modules/token.py
CHANGED
|
@@ -163,7 +163,7 @@ def create(ctx: Context) -> None:
|
|
|
163
163
|
|
|
164
164
|
* Static Tokens do not have a TTL and can have any valid scope (ADMIN, TOKENS, or ORG_DATASOURCES:READ).
|
|
165
165
|
|
|
166
|
-
* JWT tokens have a TTL and can
|
|
166
|
+
* JWT tokens have a TTL and can have PIPES:READ and DATASOURCES:READ scopes. Their main use case is allow your users to call your endpoints or read datasources without exposing your API key.
|
|
167
167
|
|
|
168
168
|
|
|
169
169
|
Examples:
|
|
@@ -173,6 +173,8 @@ def create(ctx: Context) -> None:
|
|
|
173
173
|
tb token create static my_static_token --scope TOKENS
|
|
174
174
|
|
|
175
175
|
tb token create jwt my_jwt_token --ttl 1h --scope PIPES:READ --resource my_pipe
|
|
176
|
+
|
|
177
|
+
tb token create jwt my_jwt_token --ttl 1h --scope DATASOURCES:READ --resource my_datasource --filter "column = 'value'"
|
|
176
178
|
"""
|
|
177
179
|
|
|
178
180
|
|
|
@@ -182,16 +184,21 @@ def create(ctx: Context) -> None:
|
|
|
182
184
|
@click.option(
|
|
183
185
|
"--scope",
|
|
184
186
|
multiple=True,
|
|
185
|
-
type=click.Choice(["PIPES:READ"]),
|
|
187
|
+
type=click.Choice(["PIPES:READ", "DATASOURCES:READ"]),
|
|
186
188
|
required=True,
|
|
187
|
-
help="Scope of the token (only PIPES:READ
|
|
189
|
+
help="Scope of the token (only PIPES:READ and DATASOURCES:READ are allowed for JWT tokens)",
|
|
188
190
|
)
|
|
189
191
|
@click.option("--resource", multiple=True, required=True, help="Resource associated with the scope")
|
|
190
192
|
@click.option(
|
|
191
193
|
"--fixed-params", multiple=True, help="Fixed parameters in key=value format, multiple values separated by commas"
|
|
192
194
|
)
|
|
195
|
+
@click.option(
|
|
196
|
+
"--filter",
|
|
197
|
+
multiple=True,
|
|
198
|
+
help="SQL filter to apply when reading a datasource (only applicable for DATASOURCES:READ scope)",
|
|
199
|
+
)
|
|
193
200
|
@click.pass_context
|
|
194
|
-
def create_jwt_token(ctx: Context, name: str, ttl: timedelta, scope, resource, fixed_params) -> None:
|
|
201
|
+
def create_jwt_token(ctx: Context, name: str, ttl: timedelta, scope, resource, fixed_params, filter) -> None:
|
|
195
202
|
"""Create a JWT token with a TTL specify."""
|
|
196
203
|
|
|
197
204
|
obj: Dict[str, Any] = ctx.ensure_object(dict)
|
|
@@ -205,6 +212,10 @@ def create_jwt_token(ctx: Context, name: str, ttl: timedelta, scope, resource, f
|
|
|
205
212
|
if fixed_params and len(fixed_params) > len(scope):
|
|
206
213
|
raise CLITokenException(FeedbackManager.error_number_of_fixed_params_and_resources_mismatch())
|
|
207
214
|
|
|
215
|
+
# Ensure the number of filters does not exceed the number of scope/resource pairs
|
|
216
|
+
if filter and len(filter) > len(scope):
|
|
217
|
+
raise CLITokenException("The number of SQL filters must match the number of scopes")
|
|
218
|
+
|
|
208
219
|
# Parse fixed params
|
|
209
220
|
parsed_fixed_params = parse_fixed_params(fixed_params) if fixed_params else []
|
|
210
221
|
|
|
@@ -213,15 +224,24 @@ def create_jwt_token(ctx: Context, name: str, ttl: timedelta, scope, resource, f
|
|
|
213
224
|
for i, params in enumerate(parsed_fixed_params):
|
|
214
225
|
fixed_params_list[i] = params
|
|
215
226
|
|
|
227
|
+
# Create a list of filters for each scope/resource pair, defaulting to None if not provided
|
|
228
|
+
filters_list: List[Optional[str]] = [None] * len(scope)
|
|
229
|
+
for i, f in enumerate(filter):
|
|
230
|
+
filters_list[i] = f
|
|
231
|
+
|
|
216
232
|
scopes = []
|
|
217
|
-
for sc, res, fparams in zip(scope, resource, fixed_params_list):
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
233
|
+
for sc, res, fparams, filter in zip(scope, resource, fixed_params_list, filters_list):
|
|
234
|
+
scope_data = {
|
|
235
|
+
"type": sc,
|
|
236
|
+
"resource": res,
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if sc == "PIPES:READ" and fparams:
|
|
240
|
+
scope_data["fixed_params"] = fparams
|
|
241
|
+
elif sc == "DATASOURCES:READ" and filter:
|
|
242
|
+
scope_data["filter"] = filter
|
|
243
|
+
|
|
244
|
+
scopes.append(scope_data)
|
|
225
245
|
|
|
226
246
|
try:
|
|
227
247
|
response = client.create_jwt_token(name, expiration_time, scopes)
|
|
@@ -258,6 +278,7 @@ class DynamicOptionsCommand(click.Command):
|
|
|
258
278
|
# Options
|
|
259
279
|
dynamic_options_help += "Options:\n"
|
|
260
280
|
dynamic_options_help += f" --scope [{','.join(valid_scopes)}] Scope for the token [Required]\n"
|
|
281
|
+
dynamic_options_help += " --resource TEXT Resource you want to associate the scope with\n"
|
|
261
282
|
dynamic_options_help += " -h, --help Show this message and exit.\n"
|
|
262
283
|
|
|
263
284
|
return dynamic_options_help
|
|
@@ -17,15 +17,15 @@ tinybird/datafile/exceptions.py,sha256=8rw2umdZjtby85QbuRKFO5ETz_eRHwUY5l7eHsy1w
|
|
|
17
17
|
tinybird/datafile/parse_connection.py,sha256=tRyn2Rpr1TeWet5BXmMoQgaotbGdYep1qiTak_OqC5E,1825
|
|
18
18
|
tinybird/datafile/parse_datasource.py,sha256=ssW8QeFSgglVFi3sDZj_HgkJiTJ2069v2JgqnH3CkDE,1825
|
|
19
19
|
tinybird/datafile/parse_pipe.py,sha256=xf4m0Tw44QWJzHzAm7Z7FwUoUUtr7noMYjU1NiWnX0k,3880
|
|
20
|
-
tinybird/tb/__cli__.py,sha256=
|
|
20
|
+
tinybird/tb/__cli__.py,sha256=V9cRl0xsyU-hm_0lGu2QorOI9Mdck-XRwVjBngDbFZ8,247
|
|
21
21
|
tinybird/tb/check_pypi.py,sha256=Gp0HkHHDFMSDL6nxKlOY51z7z1Uv-2LRexNTZSHHGmM,552
|
|
22
22
|
tinybird/tb/cli.py,sha256=FdDFEIayjmsZEVsVSSvRiVYn_FHOVg_zWQzchnzfWho,1008
|
|
23
|
-
tinybird/tb/client.py,sha256=
|
|
23
|
+
tinybird/tb/client.py,sha256=OVNlCXI16kpD-Ph8BDhkyKbR68TdZcR_j4ng91Iiybg,54706
|
|
24
24
|
tinybird/tb/config.py,sha256=mhMTGnMB5KcxGoh3dewIr2Jjsa6pHE183gCPAQWyp6o,3973
|
|
25
25
|
tinybird/tb/modules/build.py,sha256=efD-vamK1NPaDo9R86Hn8be2DYoW0Hh5bZiH7knK5dk,7790
|
|
26
26
|
tinybird/tb/modules/build_common.py,sha256=dthlaDn_CuwZnedQcUi7iIdDoHWfSbbbGQwiDgNcmC0,13062
|
|
27
27
|
tinybird/tb/modules/cicd.py,sha256=0KLKccha9IP749QvlXBmzdWv1On3mFwMY4DUcJlBxiE,7326
|
|
28
|
-
tinybird/tb/modules/cli.py,sha256=
|
|
28
|
+
tinybird/tb/modules/cli.py,sha256=2sw4W3sQyhAo474Mnq3hUN2QZUpEb9cU1NYnVB0qHl0,16877
|
|
29
29
|
tinybird/tb/modules/common.py,sha256=tj6DR2yOqMMQ0PILwFGXmMogxdrbQCgj36HdSM611rs,82657
|
|
30
30
|
tinybird/tb/modules/config.py,sha256=gK7rgaWTDd4ZKCrNEg_Uemr26EQjqWt6TjyQKujxOws,11462
|
|
31
31
|
tinybird/tb/modules/connection.py,sha256=-MY56NUAai6EMC4-wpi7bT0_nz_SA8QzTmHkV7HB1IQ,17810
|
|
@@ -33,7 +33,7 @@ tinybird/tb/modules/copy.py,sha256=dPZkcIDvxjJrlQUIvToO0vsEEEs4EYumbNV77-BzNoU,4
|
|
|
33
33
|
tinybird/tb/modules/create.py,sha256=pJxHXG69c9Z_21s-7VuJ3RZOF_nJU51LEwiAkvI3dZY,23251
|
|
34
34
|
tinybird/tb/modules/datasource.py,sha256=pae-ENeHYIF1HHYRSOziFC-2FPLUFa0KS60YpdlKCS8,41725
|
|
35
35
|
tinybird/tb/modules/deployment.py,sha256=EDEVOqFk5fp0fvvs2jV0mT5POFd-i_8uZIUREwzAbEk,13199
|
|
36
|
-
tinybird/tb/modules/deployment_common.py,sha256=
|
|
36
|
+
tinybird/tb/modules/deployment_common.py,sha256=6Ws3YTtEyVl9Id7gyxXkEhe0GJpUJeibS-XGTtTA9DI,19076
|
|
37
37
|
tinybird/tb/modules/deprecations.py,sha256=rrszC1f_JJeJ8mUxGoCxckQTJFBCR8wREf4XXXN-PRc,4507
|
|
38
38
|
tinybird/tb/modules/dev_server.py,sha256=57FCKuWpErwYUYgHspYDkLWEm9F4pbvVOtMrFXX1fVU,10129
|
|
39
39
|
tinybird/tb/modules/endpoint.py,sha256=ksRj6mfDb9Xv63PhTkV_uKSosgysHElqagg3RTt21Do,11958
|
|
@@ -64,17 +64,17 @@ tinybird/tb/modules/table.py,sha256=4XrtjM-N0zfNtxVkbvLDQQazno1EPXnxTyo7llivfXk,
|
|
|
64
64
|
tinybird/tb/modules/telemetry.py,sha256=T9gtsQffWqG_4hRBaUJPzOfMkPwz7mH-R6Bn1XRYViA,11482
|
|
65
65
|
tinybird/tb/modules/test.py,sha256=O2-mS4uMU6nPi7yWPpWzshAgOlYKiGS-tkM12pXQGMI,1906
|
|
66
66
|
tinybird/tb/modules/test_common.py,sha256=YZwAdSfYVXdvArfTc9tH-2QBOhb_XbnJ3eKvyXTJuEM,12717
|
|
67
|
-
tinybird/tb/modules/token.py,sha256=
|
|
67
|
+
tinybird/tb/modules/token.py,sha256=ZhW_o7XCr90wJRhMN6816vyo_TVfnzPXyIhrhzQ7oZ0,13807
|
|
68
68
|
tinybird/tb/modules/watch.py,sha256=No0bK1M1_3CYuMaIgylxf7vYFJ72lTJe3brz6xQ-mJo,8819
|
|
69
69
|
tinybird/tb/modules/workspace.py,sha256=Q_8HcxMsNg8QG9aBlwcWS2umrDP5IkTIHqqz3sfmGuc,11341
|
|
70
70
|
tinybird/tb/modules/workspace_members.py,sha256=5JdkJgfuEwbq-t6vxkBhYwgsiTDxF790wsa6Xfif9nk,8608
|
|
71
71
|
tinybird/tb/modules/agent/__init__.py,sha256=i3oe3vDIWWPaicdCM0zs7D7BJ1W0k7th93ooskHAV00,54
|
|
72
|
-
tinybird/tb/modules/agent/agent.py,sha256=
|
|
72
|
+
tinybird/tb/modules/agent/agent.py,sha256=vr2a5lSAhmJer1702gVmECUjbrjg2_MUYMlEy5o0iE4,28773
|
|
73
73
|
tinybird/tb/modules/agent/animations.py,sha256=4WOC5_2BracttmMCrV0H91tXfWcUzQHBUaIJc5FA7tE,3490
|
|
74
|
-
tinybird/tb/modules/agent/banner.py,sha256=
|
|
74
|
+
tinybird/tb/modules/agent/banner.py,sha256=l6cO5Fi7lbVKp-GsBP8jf3IkjOWxg2jpAt9NBCy0WR8,4085
|
|
75
75
|
tinybird/tb/modules/agent/command_agent.py,sha256=Q4M5qV9j3aETrXswoWZ02ZWQZhJm42HGHO1ymJrfDnw,2665
|
|
76
76
|
tinybird/tb/modules/agent/memory.py,sha256=O6Kumn9AyKxcTkhI45yjAUZ3ZIAibLOcNWoiEuLYeqY,3245
|
|
77
|
-
tinybird/tb/modules/agent/models.py,sha256=
|
|
77
|
+
tinybird/tb/modules/agent/models.py,sha256=IAxqlnHy8c2OeSnDrrSp2Mg38W9_r0GsDM87Wv-YNfM,925
|
|
78
78
|
tinybird/tb/modules/agent/prompts.py,sha256=NEIk3OK0xXm3QS1Iox4T1MMo19hLhfaICMEwzqVGW7E,31069
|
|
79
79
|
tinybird/tb/modules/agent/testing_agent.py,sha256=mH7ccuWeTnkpENCmwym9ubDFncMXQoSo0jq2pRxJVDY,2553
|
|
80
80
|
tinybird/tb/modules/agent/utils.py,sha256=Tv9NwPYPwkdWMfxfrDolVVglrBWnMUViQFE2nxaQMdg,29613
|
|
@@ -116,8 +116,8 @@ tinybird/tb_cli_modules/config.py,sha256=IsgdtFRnUrkY8-Zo32lmk6O7u3bHie1QCxLwgp4
|
|
|
116
116
|
tinybird/tb_cli_modules/exceptions.py,sha256=pmucP4kTF4irIt7dXiG-FcnI-o3mvDusPmch1L8RCWk,3367
|
|
117
117
|
tinybird/tb_cli_modules/regions.py,sha256=QjsL5H6Kg-qr0aYVLrvb1STeJ5Sx_sjvbOYO0LrEGMk,166
|
|
118
118
|
tinybird/tb_cli_modules/telemetry.py,sha256=Hh2Io8ZPROSunbOLuMvuIFU4TqwWPmQTqal4WS09K1A,10449
|
|
119
|
-
tinybird-0.0.1.
|
|
120
|
-
tinybird-0.0.1.
|
|
121
|
-
tinybird-0.0.1.
|
|
122
|
-
tinybird-0.0.1.
|
|
123
|
-
tinybird-0.0.1.
|
|
119
|
+
tinybird-0.0.1.dev267.dist-info/METADATA,sha256=EzrJCbpmOzBD7DT9HjC9ggTCcuXx-mSoyrJodo0JTRk,1733
|
|
120
|
+
tinybird-0.0.1.dev267.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
121
|
+
tinybird-0.0.1.dev267.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
|
|
122
|
+
tinybird-0.0.1.dev267.dist-info/top_level.txt,sha256=VqqqEmkAy7UNaD8-V51FCoMMWXjLUlR0IstvK7tJYVY,54
|
|
123
|
+
tinybird-0.0.1.dev267.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|