tinybird 0.0.1.dev60__tar.gz → 0.0.1.dev62__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.
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/PKG-INFO +1 -1
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/__cli__.py +2 -2
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/build.py +60 -44
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/cli.py +3 -8
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/config.py +4 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/create.py +2 -9
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/fixture.py +1 -4
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/endpoint.py +115 -19
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/local_common.py +2 -3
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/mock.py +5 -3
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/shell.py +3 -3
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/test.py +5 -15
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird.egg-info/PKG-INFO +1 -1
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/setup.cfg +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/__cli__.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/ch_utils/engine.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/check_pypi.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/client.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/config.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/connectors.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/context.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/datafile.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/datatypes.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/feedback_manager.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/git_settings.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/prompts.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/sql.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/sql_template.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/sql_toolset.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/syncasync.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/cli.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/auth.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/cicd.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/common.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/copy.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/build.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/build_common.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/common.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/diff.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/exceptions.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/format_common.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/parse_datasource.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/parse_pipe.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/pull.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datasource.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/deployment.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/exceptions.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/feedback_manager.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/fmt.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/job.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/llm.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/llm_utils.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/local.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/login.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/materialization.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/pipe.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/project.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/regions.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/table.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/tag.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/telemetry.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/token.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/watch.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/workspace.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/workspace_members.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/common.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/pipe.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tornado_template.py +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird.egg-info/SOURCES.txt +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird.egg-info/dependency_links.txt +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird.egg-info/entry_points.txt +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird.egg-info/requires.txt +0 -0
- {tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird.egg-info/top_level.txt +0 -0
|
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
|
|
|
4
4
|
__url__ = 'https://www.tinybird.co/docs/cli/introduction.html'
|
|
5
5
|
__author__ = 'Tinybird'
|
|
6
6
|
__author_email__ = 'support@tinybird.co'
|
|
7
|
-
__version__ = '0.0.1.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '0.0.1.dev62'
|
|
8
|
+
__revision__ = '472a5f2'
|
|
@@ -31,48 +31,19 @@ def build(ctx: click.Context, watch: bool) -> None:
|
|
|
31
31
|
project: Project = ctx.ensure_object(dict)["project"]
|
|
32
32
|
tb_client: TinyB = ctx.ensure_object(dict)["client"]
|
|
33
33
|
click.echo(FeedbackManager.highlight_building_project())
|
|
34
|
+
process(project=project, tb_client=tb_client, watch=watch)
|
|
35
|
+
if watch:
|
|
36
|
+
run_watch(project=project, tb_client=tb_client)
|
|
34
37
|
|
|
35
|
-
def process(watch: bool, file_changed: Optional[str] = None, diff: Optional[str] = None) -> None:
|
|
36
|
-
time_start = time.time()
|
|
37
|
-
build_failed = False
|
|
38
|
-
if file_changed and file_changed.endswith(".ndjson"):
|
|
39
|
-
rebuild_fixture(project, tb_client, file_changed)
|
|
40
|
-
else:
|
|
41
|
-
try:
|
|
42
|
-
build_project(project, tb_client, file_changed)
|
|
43
|
-
except click.ClickException as e:
|
|
44
|
-
click.echo(e)
|
|
45
|
-
build_failed = True
|
|
46
|
-
try:
|
|
47
|
-
if file_changed:
|
|
48
|
-
asyncio.run(folder_build(project, tb_client, filenames=[file_changed]))
|
|
49
|
-
show_data(tb_client, file_changed, diff)
|
|
50
|
-
except Exception:
|
|
51
|
-
pass
|
|
52
|
-
|
|
53
|
-
time_end = time.time()
|
|
54
|
-
elapsed_time = time_end - time_start
|
|
55
|
-
|
|
56
|
-
rebuild_str = "Rebuild" if watch else "Build"
|
|
57
|
-
if build_failed:
|
|
58
|
-
click.echo(FeedbackManager.error(message=f"\n✗ {rebuild_str} failed"))
|
|
59
|
-
if not watch:
|
|
60
|
-
sys.exit(1)
|
|
61
|
-
else:
|
|
62
|
-
click.echo(FeedbackManager.success(message=f"\n✓ {rebuild_str} completed in {elapsed_time:.1f}s"))
|
|
63
|
-
|
|
64
|
-
process(watch=watch)
|
|
65
38
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
watcher_thread.start()
|
|
75
|
-
shell.run()
|
|
39
|
+
@cli.command("dev", help="Build the project server side and watch for changes")
|
|
40
|
+
@click.pass_context
|
|
41
|
+
def dev(ctx: click.Context) -> None:
|
|
42
|
+
project: Project = ctx.ensure_object(dict)["project"]
|
|
43
|
+
tb_client: TinyB = ctx.ensure_object(dict)["client"]
|
|
44
|
+
click.echo(FeedbackManager.highlight_building_project())
|
|
45
|
+
process(project=project, tb_client=tb_client, watch=True)
|
|
46
|
+
run_watch(project=project, tb_client=tb_client)
|
|
76
47
|
|
|
77
48
|
|
|
78
49
|
def build_project(project: Project, tb_client: TinyB, file_changed: Optional[str] = None) -> None:
|
|
@@ -116,19 +87,20 @@ def build_project(project: Project, tb_client: TinyB, file_changed: Optional[str
|
|
|
116
87
|
|
|
117
88
|
build_result = result.get("result")
|
|
118
89
|
if build_result == "success":
|
|
119
|
-
|
|
120
|
-
|
|
90
|
+
build = result.get("build")
|
|
91
|
+
datasources = build.get("new_datasource_names", [])
|
|
92
|
+
pipes = build.get("new_pipe_names", [])
|
|
121
93
|
if not file_changed:
|
|
122
94
|
for ds in datasources:
|
|
123
95
|
ds_path_str: Optional[str] = next(
|
|
124
|
-
(p for p in project_files if p.endswith(ds
|
|
96
|
+
(p for p in project_files if p.endswith(ds + ".datasource")), None
|
|
125
97
|
)
|
|
126
98
|
if ds_path_str:
|
|
127
99
|
ds_path = Path(ds_path_str)
|
|
128
100
|
ds_path_str = ds_path_str.replace(f"{project.folder}/", "")
|
|
129
101
|
click.echo(FeedbackManager.info(message=f"✓ {ds_path_str} created"))
|
|
130
102
|
for pipe in pipes:
|
|
131
|
-
pipe_name = pipe
|
|
103
|
+
pipe_name = pipe
|
|
132
104
|
pipe_path_str: Optional[str] = next(
|
|
133
105
|
(p for p in project_files if p.endswith(pipe_name + ".pipe")), None
|
|
134
106
|
)
|
|
@@ -227,3 +199,47 @@ def show_data(tb_client: TinyB, filename: str, diff: Optional[str] = None):
|
|
|
227
199
|
|
|
228
200
|
res = asyncio.run(tb_client.query(sql, pipeline=pipeline))
|
|
229
201
|
print_table_formatted(res, table_name)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def process(
|
|
205
|
+
project: Project, tb_client: TinyB, watch: bool, file_changed: Optional[str] = None, diff: Optional[str] = None
|
|
206
|
+
) -> None:
|
|
207
|
+
time_start = time.time()
|
|
208
|
+
build_failed = False
|
|
209
|
+
if file_changed and file_changed.endswith(".ndjson"):
|
|
210
|
+
rebuild_fixture(project, tb_client, file_changed)
|
|
211
|
+
else:
|
|
212
|
+
try:
|
|
213
|
+
build_project(project, tb_client, file_changed)
|
|
214
|
+
except click.ClickException as e:
|
|
215
|
+
click.echo(e)
|
|
216
|
+
build_failed = True
|
|
217
|
+
try:
|
|
218
|
+
if file_changed:
|
|
219
|
+
asyncio.run(folder_build(project, tb_client, filenames=[file_changed]))
|
|
220
|
+
show_data(tb_client, file_changed, diff)
|
|
221
|
+
except Exception:
|
|
222
|
+
pass
|
|
223
|
+
|
|
224
|
+
time_end = time.time()
|
|
225
|
+
elapsed_time = time_end - time_start
|
|
226
|
+
|
|
227
|
+
rebuild_str = "Rebuild" if watch else "Build"
|
|
228
|
+
if build_failed:
|
|
229
|
+
click.echo(FeedbackManager.error(message=f"\n✗ {rebuild_str} failed"))
|
|
230
|
+
if not watch:
|
|
231
|
+
sys.exit(1)
|
|
232
|
+
else:
|
|
233
|
+
click.echo(FeedbackManager.success(message=f"\n✓ {rebuild_str} completed in {elapsed_time:.1f}s"))
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def run_watch(project: Project, tb_client: TinyB) -> None:
|
|
237
|
+
shell = Shell(project=project, tb_client=tb_client)
|
|
238
|
+
click.echo(FeedbackManager.gray(message="\nWatching for changes..."))
|
|
239
|
+
watcher_thread = threading.Thread(
|
|
240
|
+
target=watch_project,
|
|
241
|
+
args=(shell, process, project),
|
|
242
|
+
daemon=True,
|
|
243
|
+
)
|
|
244
|
+
watcher_thread.start()
|
|
245
|
+
shell.run()
|
|
@@ -57,7 +57,6 @@ VERSION = f"{__cli__.__version__} (rev {__cli__.__revision__})"
|
|
|
57
57
|
@click.option("--show-tokens", is_flag=True, default=False, help="Enable the output of tokens")
|
|
58
58
|
@click.option("--cloud/--local", is_flag=True, default=False, help="Run against cloud or local")
|
|
59
59
|
@click.option("--build", is_flag=True, default=False, help="Run against build mode")
|
|
60
|
-
@click.option("--folder", type=str, help="Folder where files will be placed")
|
|
61
60
|
@click.version_option(version=VERSION)
|
|
62
61
|
@click.pass_context
|
|
63
62
|
@coro
|
|
@@ -69,12 +68,11 @@ async def cli(
|
|
|
69
68
|
show_tokens: bool,
|
|
70
69
|
cloud: bool,
|
|
71
70
|
build: bool,
|
|
72
|
-
folder: Optional[str],
|
|
73
71
|
) -> None:
|
|
74
72
|
"""
|
|
75
73
|
Use `OBFUSCATE_REGEX_PATTERN` and `OBFUSCATE_PATTERN_SEPARATOR` environment variables to define a regex pattern and a separator (in case of a single string with multiple regex) to obfuscate secrets in the CLI output.
|
|
76
74
|
"""
|
|
77
|
-
project = Project(folder=
|
|
75
|
+
project = Project(folder=os.getcwd())
|
|
78
76
|
# We need to unpatch for our tests not to break
|
|
79
77
|
if show_tokens or not cloud or ctx.invoked_subcommand == "build" or build:
|
|
80
78
|
__unpatch_click_output()
|
|
@@ -132,18 +130,15 @@ async def cli(
|
|
|
132
130
|
|
|
133
131
|
|
|
134
132
|
@cli.command(hidden=True)
|
|
135
|
-
@click.option(
|
|
136
|
-
"--folder", default=None, type=click.Path(exists=True, file_okay=False), help="Folder where files will be placed"
|
|
137
|
-
)
|
|
138
133
|
@click.option("-f", "--force", is_flag=True, default=False, help="Override existing files")
|
|
139
134
|
@click.option("--fmt", is_flag=True, default=False, help="Format files before saving")
|
|
140
135
|
@click.pass_context
|
|
141
136
|
@coro
|
|
142
|
-
async def pull(ctx: Context,
|
|
137
|
+
async def pull(ctx: Context, force: bool, fmt: bool) -> None:
|
|
143
138
|
"""Retrieve latest versions for project files from Tinybird."""
|
|
144
139
|
|
|
145
140
|
client = ctx.ensure_object(dict)["client"]
|
|
146
|
-
folder =
|
|
141
|
+
folder = getcwd()
|
|
147
142
|
|
|
148
143
|
return await folder_pull(client, folder, force, fmt=fmt)
|
|
149
144
|
|
|
@@ -321,6 +321,10 @@ class CLIConfig:
|
|
|
321
321
|
"""
|
|
322
322
|
working_dir = working_dir or os.getcwd()
|
|
323
323
|
path: str = os.path.join(working_dir, ".tinyb")
|
|
324
|
+
|
|
325
|
+
if not os.path.exists(path):
|
|
326
|
+
path = os.path.join(os.path.dirname(working_dir), ".tinyb")
|
|
327
|
+
|
|
324
328
|
return CLIConfig(path, parent=CLIConfig.get_global_config())
|
|
325
329
|
|
|
326
330
|
@staticmethod
|
|
@@ -33,22 +33,15 @@ from tinybird.tb.modules.project import Project
|
|
|
33
33
|
default=None,
|
|
34
34
|
help="Prompt to be used to create the project",
|
|
35
35
|
)
|
|
36
|
-
@click.option(
|
|
37
|
-
"--folder",
|
|
38
|
-
default="",
|
|
39
|
-
type=click.Path(exists=False, file_okay=False),
|
|
40
|
-
help="Folder where datafiles will be placed",
|
|
41
|
-
)
|
|
42
36
|
@click.option("--rows", type=int, default=10, help="Number of events to send")
|
|
43
37
|
@click.option("--source", type=str, default="tb", help="Source of the command")
|
|
44
|
-
@click.option("--skip", is_flag=True, default=False, help="Skip following up on the generated
|
|
38
|
+
@click.option("--skip", is_flag=True, default=False, help="Skip following up on the generated resources")
|
|
45
39
|
@click.pass_context
|
|
46
40
|
@coro
|
|
47
41
|
async def create(
|
|
48
42
|
ctx: click.Context,
|
|
49
43
|
data: Optional[str],
|
|
50
44
|
prompt: Optional[str],
|
|
51
|
-
folder: Optional[str],
|
|
52
45
|
rows: int,
|
|
53
46
|
source: str,
|
|
54
47
|
skip: bool,
|
|
@@ -56,7 +49,7 @@ async def create(
|
|
|
56
49
|
"""Initialize a new project."""
|
|
57
50
|
project: Project = ctx.ensure_object(dict)["project"]
|
|
58
51
|
local_client: TinyB = ctx.ensure_object(dict)["client"]
|
|
59
|
-
folder =
|
|
52
|
+
folder = getcwd()
|
|
60
53
|
folder_path = Path(folder)
|
|
61
54
|
if not folder_path.exists():
|
|
62
55
|
folder_path.mkdir()
|
|
@@ -5,10 +5,7 @@ from tinybird.tb.modules.common import format_data_to_ndjson
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def get_fixture_dir(folder: str) -> Path:
|
|
8
|
-
|
|
9
|
-
if not fixture_dir.exists():
|
|
10
|
-
fixture_dir.mkdir()
|
|
11
|
-
return fixture_dir
|
|
8
|
+
return Path(folder) / "fixtures"
|
|
12
9
|
|
|
13
10
|
|
|
14
11
|
def persist_fixture(fixture_name: str, data: Union[List[Dict[str, Any]], str], folder: str, format="ndjson") -> Path:
|
|
@@ -10,6 +10,7 @@ from urllib.parse import urlencode
|
|
|
10
10
|
|
|
11
11
|
import click
|
|
12
12
|
import humanfriendly
|
|
13
|
+
import pyperclip
|
|
13
14
|
import requests
|
|
14
15
|
from click import Context
|
|
15
16
|
|
|
@@ -54,7 +55,7 @@ async def endpoint_ls(ctx: Context, match: str, format_: str):
|
|
|
54
55
|
tk = get_name_version(t["name"])
|
|
55
56
|
if pattern and not pattern.search(tk["name"]):
|
|
56
57
|
continue
|
|
57
|
-
token = get_endpoint_token(tokens, tk["name"])
|
|
58
|
+
token = get_endpoint_token(tokens, tk["name"]) or client.token
|
|
58
59
|
endpoint_url = build_endpoint_url(client, tk["name"], token)
|
|
59
60
|
table_human_readable.append((tk["name"], t["updated_at"][:-7], len(t["nodes"]), endpoint_url))
|
|
60
61
|
table_machine_readable.append(
|
|
@@ -151,29 +152,23 @@ async def endpoint_data(ctx: Context, pipe: str, query: str, format_: str):
|
|
|
151
152
|
|
|
152
153
|
@endpoint.command(name="url")
|
|
153
154
|
@click.argument("pipe")
|
|
155
|
+
@click.option(
|
|
156
|
+
"--language",
|
|
157
|
+
default="http",
|
|
158
|
+
help="Language used for sending the request. Options: http, python, curl, javascript, rust, go",
|
|
159
|
+
)
|
|
154
160
|
@click.pass_context
|
|
155
161
|
@coro
|
|
156
|
-
async def endpoint_url(ctx: Context, pipe: str):
|
|
162
|
+
async def endpoint_url(ctx: Context, pipe: str, language: str):
|
|
157
163
|
"""Print the URL of an endpoint"""
|
|
164
|
+
if language != "http":
|
|
165
|
+
click.echo(FeedbackManager.highlight(message=f"\n» Generating snippet for {language} language"))
|
|
158
166
|
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
159
167
|
tokens = await client.tokens()
|
|
160
|
-
token = get_endpoint_token(tokens, pipe)
|
|
161
|
-
click.echo(
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
def build_endpoint_url(tb_client: TinyB, pipe_name: str, token: Optional[str]) -> Optional[str]:
|
|
165
|
-
try:
|
|
166
|
-
token = token or tb_client.token
|
|
167
|
-
example_params = {
|
|
168
|
-
"format": "json",
|
|
169
|
-
"pipe": pipe_name,
|
|
170
|
-
"q": "",
|
|
171
|
-
"token": token,
|
|
172
|
-
}
|
|
173
|
-
response = requests.get(f"{tb_client.host}/examples/query.http?{urlencode(example_params)}")
|
|
174
|
-
return response.text.replace("http://localhost:8001", tb_client.host)
|
|
175
|
-
except Exception:
|
|
176
|
-
return None
|
|
168
|
+
token = get_endpoint_token(tokens, pipe) or client.token
|
|
169
|
+
click.echo(build_endpoint_snippet(client, pipe, token, language))
|
|
170
|
+
if language != "http":
|
|
171
|
+
click.echo(FeedbackManager.success(message="\n✓ Code snippet copied to clipboard!\n"))
|
|
177
172
|
|
|
178
173
|
|
|
179
174
|
def get_endpoint_token(tokens: List[Dict[str, Any]], pipe_name: str) -> Optional[str]:
|
|
@@ -272,3 +267,104 @@ async def endpoint_stats(ctx: click.Context, pipes: Tuple[str, ...], format_: st
|
|
|
272
267
|
click.echo(json.dumps({"pipes": table_machine_readable}, indent=2))
|
|
273
268
|
else:
|
|
274
269
|
echo_safe_humanfriendly_tables_format_smart_table(table_human_readable, column_names=columns)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def build_endpoint_snippet(tb_client: TinyB, pipe_name: str, token: Optional[str], language: str) -> Optional[str]:
|
|
273
|
+
endpoint_url = build_endpoint_url(tb_client, pipe_name, token)
|
|
274
|
+
if language == "http":
|
|
275
|
+
return endpoint_url
|
|
276
|
+
|
|
277
|
+
snippet = None
|
|
278
|
+
if language == "python":
|
|
279
|
+
snippet = build_python_snippet(endpoint_url, token)
|
|
280
|
+
elif language == "curl":
|
|
281
|
+
snippet = build_curl_snippet(endpoint_url)
|
|
282
|
+
elif language == "javascript":
|
|
283
|
+
snippet = build_javascript_snippet(endpoint_url, token)
|
|
284
|
+
elif language == "rust":
|
|
285
|
+
snippet = build_rust_snippet(endpoint_url, token)
|
|
286
|
+
elif language == "go":
|
|
287
|
+
snippet = build_go_snippet(endpoint_url, token)
|
|
288
|
+
|
|
289
|
+
if not snippet:
|
|
290
|
+
raise CLIPipeException(FeedbackManager.error(message=f"Language {language} not supported"))
|
|
291
|
+
|
|
292
|
+
pyperclip.copy(snippet.strip())
|
|
293
|
+
return snippet
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def build_endpoint_url(tb_client: TinyB, pipe_name: str, token: str) -> str:
|
|
297
|
+
example_params = {
|
|
298
|
+
"format": "json",
|
|
299
|
+
"pipe": pipe_name,
|
|
300
|
+
"q": "",
|
|
301
|
+
"token": token,
|
|
302
|
+
}
|
|
303
|
+
response = requests.get(f"{tb_client.host}/examples/query.http?{urlencode(example_params)}")
|
|
304
|
+
return response.text.replace("http://localhost:8001", tb_client.host)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def build_python_snippet(endpoint_url: str, token: str) -> str:
|
|
308
|
+
endpoint_url = endpoint_url.replace(f"token={token}", "token={{token}}")
|
|
309
|
+
return f"""
|
|
310
|
+
import requests
|
|
311
|
+
|
|
312
|
+
token = "{token}"
|
|
313
|
+
url = "{endpoint_url}"
|
|
314
|
+
response = requests.get(url)
|
|
315
|
+
print(response.json())
|
|
316
|
+
"""
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def build_curl_snippet(endpoint_url: str) -> str:
|
|
320
|
+
return f"""
|
|
321
|
+
curl -X GET "{endpoint_url}"
|
|
322
|
+
"""
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def build_javascript_snippet(endpoint_url: str, token: str) -> str:
|
|
326
|
+
endpoint_url = endpoint_url.replace(f"token={token}", "token=${token}")
|
|
327
|
+
return f"""
|
|
328
|
+
const token = "{token}";
|
|
329
|
+
fetch(`{endpoint_url}`)
|
|
330
|
+
.then(response => response.json())
|
|
331
|
+
.then(data => console.log(data));
|
|
332
|
+
"""
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def build_rust_snippet(endpoint_url: str) -> str:
|
|
336
|
+
return f"""
|
|
337
|
+
use reqwest::Client;
|
|
338
|
+
|
|
339
|
+
let client = Client::new();
|
|
340
|
+
let response = client.get("{endpoint_url}").send().await?;
|
|
341
|
+
"""
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def build_go_snippet(endpoint_url: str) -> str:
|
|
345
|
+
return f"""
|
|
346
|
+
package main
|
|
347
|
+
|
|
348
|
+
import (
|
|
349
|
+
"fmt"
|
|
350
|
+
"io"
|
|
351
|
+
"log"
|
|
352
|
+
"net/http"
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
func main() {{
|
|
356
|
+
url := "{endpoint_url}"
|
|
357
|
+
resp, err := http.Get(url)
|
|
358
|
+
if err != nil {{
|
|
359
|
+
log.Fatal(err)
|
|
360
|
+
}}
|
|
361
|
+
defer resp.Body.Close()
|
|
362
|
+
|
|
363
|
+
body, err := io.ReadAll(resp.Body)
|
|
364
|
+
if err != nil {{
|
|
365
|
+
log.Fatal(err)
|
|
366
|
+
}}
|
|
367
|
+
|
|
368
|
+
fmt.Println(string(body))
|
|
369
|
+
}}
|
|
370
|
+
"""
|
|
@@ -5,9 +5,8 @@ from typing import Any, Dict
|
|
|
5
5
|
|
|
6
6
|
import requests
|
|
7
7
|
|
|
8
|
-
from tinybird.client import AuthNoTokenException, TinyB
|
|
8
|
+
from tinybird.client import AuthException, AuthNoTokenException, TinyB
|
|
9
9
|
from tinybird.tb.modules.config import CLIConfig
|
|
10
|
-
from tinybird.tb.modules.exceptions import CLIException
|
|
11
10
|
|
|
12
11
|
TB_IMAGE_NAME = "tinybirdco/tinybird-local:beta"
|
|
13
12
|
TB_CONTAINER_NAME = "tinybird-local"
|
|
@@ -33,7 +32,7 @@ async def get_tinybird_local_config(config_obj: Dict[str, Any], build: bool = Fa
|
|
|
33
32
|
# ruff: noqa: ASYNC210
|
|
34
33
|
tokens = requests.get(f"{TB_LOCAL_HOST}/tokens").json()
|
|
35
34
|
except Exception:
|
|
36
|
-
raise
|
|
35
|
+
raise AuthException("Error: Tinybird local is not running. Please run `tb local start` first.")
|
|
37
36
|
|
|
38
37
|
user_token = tokens["user_token"]
|
|
39
38
|
admin_token = tokens["admin_token"]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import glob
|
|
1
2
|
import logging
|
|
2
3
|
import os
|
|
3
4
|
from pathlib import Path
|
|
@@ -46,11 +47,13 @@ async def mock(ctx: click.Context, datasource: str, rows: int, prompt: str, skip
|
|
|
46
47
|
datasource_name = datasource
|
|
47
48
|
folder = project.folder
|
|
48
49
|
click.echo(FeedbackManager.highlight(message=f"\n» Creating fixture for {datasource_name}..."))
|
|
50
|
+
|
|
49
51
|
if datasource_path.suffix == ".datasource":
|
|
50
52
|
datasource_name = datasource_path.stem
|
|
51
53
|
else:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
datasource_from_glob = glob.glob(f"**/*/{datasource}.datasource")
|
|
55
|
+
if datasource_from_glob:
|
|
56
|
+
datasource_path = Path(datasource_from_glob[0])
|
|
54
57
|
|
|
55
58
|
if not datasource_path.exists():
|
|
56
59
|
raise CLIException(f"Datasource '{datasource_path.stem}' not found")
|
|
@@ -61,7 +64,6 @@ async def mock(ctx: click.Context, datasource: str, rows: int, prompt: str, skip
|
|
|
61
64
|
if prompt_path.exists():
|
|
62
65
|
prompt = prompt_path.read_text()
|
|
63
66
|
else:
|
|
64
|
-
click.echo(FeedbackManager.info(message="* Overriding last prompt..."))
|
|
65
67
|
prompt_path.write_text(prompt)
|
|
66
68
|
|
|
67
69
|
datasource_content = datasource_path.read_text()
|
|
@@ -272,7 +272,7 @@ class Shell:
|
|
|
272
272
|
click.echo(FeedbackManager.error(message=f"'tb {arg}' command is not available in watch mode"))
|
|
273
273
|
|
|
274
274
|
def handle_mock(self, arg):
|
|
275
|
-
subprocess.run(f"tb --build
|
|
275
|
+
subprocess.run(f"tb --build mock {arg} --skip", shell=True, text=True)
|
|
276
276
|
|
|
277
277
|
def handle_tb(self, arg):
|
|
278
278
|
click.echo("")
|
|
@@ -289,7 +289,7 @@ class Shell:
|
|
|
289
289
|
need_skip = ("mock", "test create", "create")
|
|
290
290
|
if any(arg.startswith(cmd) for cmd in need_skip):
|
|
291
291
|
arg = f"{arg} --skip"
|
|
292
|
-
subprocess.run(f"tb --build
|
|
292
|
+
subprocess.run(f"tb --build {arg}", shell=True, text=True)
|
|
293
293
|
|
|
294
294
|
def default(self, argline):
|
|
295
295
|
click.echo("")
|
|
@@ -304,7 +304,7 @@ class Shell:
|
|
|
304
304
|
need_skip = ("mock", "test create", "create")
|
|
305
305
|
if any(arg.startswith(cmd) for cmd in need_skip):
|
|
306
306
|
arg = f"{arg} --skip"
|
|
307
|
-
subprocess.run(f"tb --build
|
|
307
|
+
subprocess.run(f"tb --build {arg}", shell=True, text=True)
|
|
308
308
|
|
|
309
309
|
def run_sql(self, query, rows_limit=20):
|
|
310
310
|
try:
|
|
@@ -193,17 +193,13 @@ async def test_create(ctx: click.Context, name_or_filename: str, prompt: str, sk
|
|
|
193
193
|
help="Update the test expectations for a file or a test.",
|
|
194
194
|
)
|
|
195
195
|
@click.argument("pipe", type=str)
|
|
196
|
-
@click.option(
|
|
197
|
-
"--folder",
|
|
198
|
-
default=".",
|
|
199
|
-
type=click.Path(exists=True, file_okay=False),
|
|
200
|
-
help="Folder where datafiles will be placed",
|
|
201
|
-
)
|
|
202
196
|
@click.pass_context
|
|
203
197
|
@coro
|
|
204
|
-
async def test_update(ctx: click.Context, pipe: str
|
|
198
|
+
async def test_update(ctx: click.Context, pipe: str) -> None:
|
|
205
199
|
try:
|
|
206
200
|
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
201
|
+
project: Project = ctx.ensure_object(dict)["project"]
|
|
202
|
+
folder = project.folder
|
|
207
203
|
pipe_tests_path = Path(pipe)
|
|
208
204
|
pipe_name = pipe
|
|
209
205
|
if pipe_tests_path.suffix == ".yaml":
|
|
@@ -212,7 +208,7 @@ async def test_update(ctx: click.Context, pipe: str, folder: str) -> None:
|
|
|
212
208
|
pipe_tests_path = Path("tests", f"{pipe}.yaml")
|
|
213
209
|
|
|
214
210
|
click.echo(FeedbackManager.highlight(message=f"\n» Updating tests expectations for {pipe_name} endpoint..."))
|
|
215
|
-
pipe_tests_path = Path(folder) / pipe_tests_path
|
|
211
|
+
pipe_tests_path = Path(project.folder) / pipe_tests_path
|
|
216
212
|
pipe_tests_content = yaml.safe_load(pipe_tests_path.read_text())
|
|
217
213
|
for test in pipe_tests_content:
|
|
218
214
|
test_params = test["parameters"].split("?")[1] if "?" in test["parameters"] else test["parameters"]
|
|
@@ -246,15 +242,9 @@ async def test_update(ctx: click.Context, pipe: str, folder: str) -> None:
|
|
|
246
242
|
help="Run the test suite, a file, or a test.",
|
|
247
243
|
)
|
|
248
244
|
@click.argument("name", nargs=-1)
|
|
249
|
-
@click.option(
|
|
250
|
-
"--folder",
|
|
251
|
-
default=".",
|
|
252
|
-
type=click.Path(exists=True, file_okay=False),
|
|
253
|
-
help="Folder where tests will be placed",
|
|
254
|
-
)
|
|
255
245
|
@click.pass_context
|
|
256
246
|
@coro
|
|
257
|
-
async def run_tests(ctx: click.Context, name: Tuple[str, ...]
|
|
247
|
+
async def run_tests(ctx: click.Context, name: Tuple[str, ...]) -> None:
|
|
258
248
|
click.echo(FeedbackManager.highlight(message="\n» Running tests"))
|
|
259
249
|
client: TinyB = ctx.ensure_object(dict)["client"]
|
|
260
250
|
paths = [Path(n) for n in name]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/build_datasource.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/format_datasource.py
RENAMED
|
File without changes
|
|
File without changes
|
{tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb/modules/datafile/parse_datasource.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird-0.0.1.dev60 → tinybird-0.0.1.dev62}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|