tinybird 0.0.1.dev6__py3-none-any.whl → 0.0.1.dev7__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.

Files changed (30) hide show
  1. tinybird/tb/modules/branch.py +0 -21
  2. tinybird/tb/modules/build.py +7 -18
  3. tinybird/tb/modules/cli.py +11 -131
  4. tinybird/tb/modules/common.py +14 -2
  5. tinybird/tb/modules/create.py +10 -14
  6. tinybird/tb/modules/datafile/build.py +2103 -0
  7. tinybird/tb/modules/datafile/build_common.py +118 -0
  8. tinybird/tb/modules/datafile/build_datasource.py +403 -0
  9. tinybird/tb/modules/datafile/build_pipe.py +648 -0
  10. tinybird/tb/modules/datafile/common.py +897 -0
  11. tinybird/tb/modules/datafile/diff.py +197 -0
  12. tinybird/tb/modules/datafile/exceptions.py +23 -0
  13. tinybird/tb/modules/datafile/format_common.py +66 -0
  14. tinybird/tb/modules/datafile/format_datasource.py +160 -0
  15. tinybird/tb/modules/datafile/format_pipe.py +195 -0
  16. tinybird/tb/modules/datafile/parse_datasource.py +41 -0
  17. tinybird/tb/modules/datafile/parse_pipe.py +69 -0
  18. tinybird/tb/modules/datafile/pipe_checker.py +560 -0
  19. tinybird/tb/modules/datafile/pull.py +157 -0
  20. tinybird/tb/modules/datasource.py +1 -1
  21. tinybird/tb/modules/fmt.py +4 -1
  22. tinybird/tb/modules/pipe.py +8 -2
  23. tinybird/tb/modules/prompts.py +1 -1
  24. tinybird/tb/modules/workspace.py +1 -1
  25. {tinybird-0.0.1.dev6.dist-info → tinybird-0.0.1.dev7.dist-info}/METADATA +1 -1
  26. {tinybird-0.0.1.dev6.dist-info → tinybird-0.0.1.dev7.dist-info}/RECORD +29 -16
  27. tinybird/tb/modules/datafile.py +0 -6122
  28. {tinybird-0.0.1.dev6.dist-info → tinybird-0.0.1.dev7.dist-info}/WHEEL +0 -0
  29. {tinybird-0.0.1.dev6.dist-info → tinybird-0.0.1.dev7.dist-info}/entry_points.txt +0 -0
  30. {tinybird-0.0.1.dev6.dist-info → tinybird-0.0.1.dev7.dist-info}/top_level.txt +0 -0
@@ -4,7 +4,6 @@
4
4
  # - But please, **do not** interleave utility functions and command definitions.
5
5
 
6
6
  import os
7
- from os import getcwd
8
7
  from typing import List, Optional, Tuple
9
8
 
10
9
  import aiofiles
@@ -37,7 +36,6 @@ from tinybird.tb.modules.common import (
37
36
  wait_job,
38
37
  )
39
38
  from tinybird.tb.modules.config import CLIConfig
40
- from tinybird.tb.modules.datafile import create_release
41
39
  from tinybird.tb.modules.exceptions import CLIBranchException, CLIException, CLIReleaseException
42
40
 
43
41
 
@@ -130,25 +128,6 @@ set -euxo pipefail
130
128
  click.echo(FeedbackManager.info_release_generated(semver=semver))
131
129
 
132
130
 
133
- @release.command(name="create", short_help="Create a new Release in deploying status")
134
- @click.option(
135
- "--semver",
136
- is_flag=False,
137
- required=True,
138
- type=str,
139
- help="Semver of the new Release. Example: 1.0.0",
140
- )
141
- @coro
142
- async def release_create(semver: str) -> None:
143
- click.echo(FeedbackManager.warning_deprecated_releases())
144
- config = CLIConfig.get_project_config()
145
- _ = await try_update_config_with_remote(config, only_if_needed=True)
146
-
147
- client = config.get_client()
148
- folder = getcwd()
149
- await create_release(client, config, semver, folder)
150
-
151
-
152
131
  @release.command(name="promote", short_help="Promotes to live status a preview Release")
153
132
  @click.option(
154
133
  "--semver", required=True, type=str, help="Semver of a preview Release to promote to live. Example: 1.0.0"
@@ -3,7 +3,7 @@ import os
3
3
  import random
4
4
  import time
5
5
  from pathlib import Path
6
- from typing import Any, Awaitable, Callable, Dict, List, Union
6
+ from typing import Any, Awaitable, Callable, List, Union
7
7
 
8
8
  import click
9
9
  import humanfriendly
@@ -18,17 +18,12 @@ from tinybird.tb.modules.cli import cli
18
18
  from tinybird.tb.modules.common import (
19
19
  coro,
20
20
  )
21
- from tinybird.tb.modules.datafile import (
22
- ParseException,
23
- folder_build,
24
- get_project_filenames,
25
- has_internal_datafiles,
26
- parse_datasource,
27
- parse_pipe,
28
- )
29
- from tinybird.tb.modules.local import (
30
- get_tinybird_local_client,
31
- )
21
+ from tinybird.tb.modules.datafile.build import folder_build
22
+ from tinybird.tb.modules.datafile.common import get_project_filenames, has_internal_datafiles
23
+ from tinybird.tb.modules.datafile.exceptions import ParseException
24
+ from tinybird.tb.modules.datafile.parse_datasource import parse_datasource
25
+ from tinybird.tb.modules.datafile.parse_pipe import parse_pipe
26
+ from tinybird.tb.modules.local import get_tinybird_local_client
32
27
  from tinybird.tb.modules.table import format_table
33
28
 
34
29
 
@@ -116,9 +111,6 @@ async def build(
116
111
  context.disable_template_security_validation.set(True)
117
112
  is_internal = has_internal_datafiles(folder)
118
113
  tb_client = get_tinybird_local_client()
119
- workspaces: List[Dict[str, Any]] = (await tb_client.user_workspaces_and_branches()).get("workspaces", [])
120
- datasources: List[Dict[str, Any]] = await tb_client.datasources()
121
- pipes: List[Dict[str, Any]] = await tb_client.pipes(dependencies=True)
122
114
 
123
115
  def check_filenames(filenames: List[str]):
124
116
  parser_matrix = {".pipe": parse_pipe, ".datasource": parse_datasource}
@@ -142,9 +134,6 @@ async def build(
142
134
  check_filenames(filenames=filenames)
143
135
  await folder_build(
144
136
  tb_client,
145
- workspaces,
146
- datasources,
147
- pipes,
148
137
  filenames,
149
138
  ignore_sql_errors=ignore_sql_errors,
150
139
  is_internal=is_internal,
@@ -24,12 +24,10 @@ from tinybird.client import (
24
24
  AuthException,
25
25
  AuthNoTokenException,
26
26
  DoesNotExistException,
27
- OperationCanNotBePerformed,
28
27
  TinyB,
29
28
  )
30
29
  from tinybird.config import CURRENT_VERSION, SUPPORTED_CONNECTORS, VERSION, FeatureFlags, get_config
31
30
  from tinybird.feedback_manager import FeedbackManager
32
- from tinybird.tb.modules.cicd import check_cicd_exists, init_cicd
33
31
  from tinybird.tb.modules.common import (
34
32
  OLDEST_ROLLBACK,
35
33
  CatchAuthExceptions,
@@ -49,24 +47,21 @@ from tinybird.tb.modules.common import (
49
47
  wait_job,
50
48
  )
51
49
  from tinybird.tb.modules.config import CLIConfig
52
- from tinybird.tb.modules.datafile import (
53
- AlreadyExistsException,
54
- CLIGitRelease,
55
- CLIGitReleaseException,
50
+ from tinybird.tb.modules.datafile.build import build_graph, folder_push
51
+ from tinybird.tb.modules.datafile.common import (
56
52
  Datafile,
57
- ParseException,
58
- build_graph,
59
- create_release,
60
- diff_command,
61
- folder_pull,
62
- folder_push,
63
53
  get_project_filenames,
64
54
  get_resource_versions,
65
55
  has_internal_datafiles,
66
- parse_datasource,
67
- parse_pipe,
68
- parse_token,
69
56
  )
57
+ from tinybird.tb.modules.datafile.diff import diff_command
58
+ from tinybird.tb.modules.datafile.exceptions import (
59
+ AlreadyExistsException,
60
+ ParseException,
61
+ )
62
+ from tinybird.tb.modules.datafile.parse_datasource import parse_datasource
63
+ from tinybird.tb.modules.datafile.parse_pipe import parse_pipe
64
+ from tinybird.tb.modules.datafile.pull import folder_pull
70
65
  from tinybird.tb.modules.telemetry import add_telemetry_event
71
66
 
72
67
  __old_click_echo = click.echo
@@ -323,118 +318,8 @@ async def init(
323
318
 
324
319
  await folder_init(client, folder, generate_datasources, generate_releases=True, force=force)
325
320
 
326
- if not (git or override_commit or cicd):
327
- return
328
-
329
- sync_git = git or override_commit
330
- cli_git_release = None
331
321
  error = False
332
322
  final_response = None
333
- try:
334
- cli_git_release = CLIGitRelease(path=folder)
335
- except CLIGitReleaseException:
336
- raise CLIGitReleaseException(FeedbackManager.error_no_git_repo_for_init(repo_path=folder))
337
-
338
- if sync_git:
339
- if not cli_git_release.is_main_branch() and not override_commit:
340
- raise CLIGitReleaseException(FeedbackManager.error_no_git_main_branch())
341
-
342
- if not cli_git_release.is_dottinyb_ignored():
343
- raise CLIGitReleaseException(
344
- FeedbackManager.error_dottinyb_not_ignored(git_working_dir=f"{cli_git_release.working_dir()}/")
345
- )
346
- else:
347
- click.echo(FeedbackManager.info_dottinyb_already_ignored())
348
-
349
- if (
350
- os.path.exists(f"{cli_git_release.working_dir()}/.diff_tmp")
351
- and not cli_git_release.is_dotdifftemp_ignored()
352
- ):
353
- raise CLIGitReleaseException(
354
- FeedbackManager.error_dotdiff_not_ignored(git_working_dir=f"{cli_git_release.working_dir()}/")
355
- )
356
- else:
357
- click.echo(FeedbackManager.info_dotdifftemp_already_ignored())
358
-
359
- if "release" not in current_ws:
360
- raise CLIGitReleaseException(FeedbackManager.error_no_correct_token_for_init())
361
-
362
- # If we have a release and we are not overriding the commit, we check if we have a release already
363
- elif current_ws.get("release") and not override_commit:
364
- final_response = FeedbackManager.error_release_already_set(
365
- workspace=current_ws["name"], commit=current_ws["release"]["commit"]
366
- )
367
- error = True
368
-
369
- elif override_commit:
370
- if click.confirm(
371
- FeedbackManager.prompt_init_git_release_force(
372
- current_commit=current_ws["release"]["commit"], new_commit=override_commit
373
- )
374
- ):
375
- try:
376
- release = await cli_git_release.update_release(client, current_ws, override_commit)
377
- except Exception as exc:
378
- raise CLIGitReleaseException(FeedbackManager.error_exception(error=str(exc)))
379
-
380
- final_response = FeedbackManager.success_init_git_release(
381
- workspace_name=current_ws["name"], release_commit=release["commit"]
382
- )
383
- else:
384
- return
385
-
386
- else:
387
- click.echo(FeedbackManager.info_no_git_release_yet(workspace=current_ws["name"]))
388
- click.echo(FeedbackManager.info_diff_resources_for_git_init())
389
- changed = await diff_command(
390
- [], True, client, with_print=False, verbose=False, clean_up=True, progress_bar=True
391
- )
392
- changed = {
393
- k: v
394
- for k, v in changed.items()
395
- if v is not None and (not ignore_remote or v not in ["remote", "shared"])
396
- }
397
- if changed:
398
- tb_pull_command = "tb pull --force"
399
- click.echo(FeedbackManager.warning_git_release_init_with_diffs())
400
- if click.confirm(FeedbackManager.prompt_init_git_release_pull(pull_command=tb_pull_command)):
401
- await folder_pull(client, folder, auto=True, match=None, force=True)
402
-
403
- else:
404
- raise CLIGitReleaseException(
405
- FeedbackManager.error_diff_resources_for_git_init(
406
- workspace=current_ws["name"], pull_command=tb_pull_command
407
- )
408
- )
409
- else:
410
- click.echo(FeedbackManager.info_git_release_init_without_diffs(workspace=current_ws["name"]))
411
- if cli_git_release.is_dirty_to_init():
412
- raise CLIGitReleaseException(
413
- FeedbackManager.error_commit_changes_to_init_release(
414
- path=cli_git_release.path, git_output=cli_git_release.status()
415
- )
416
- )
417
- try:
418
- release = await cli_git_release.update_release(client, current_ws)
419
- except Exception as exc:
420
- raise CLIGitReleaseException(FeedbackManager.error_exception(error=str(exc)))
421
-
422
- final_response = FeedbackManager.success_init_git_release(
423
- workspace_name=current_ws["name"], release_commit=release["commit"]
424
- )
425
-
426
- if not override_commit:
427
- cicd_provider = await check_cicd_exists(cli_git_release.working_dir())
428
- if not force and cicd_provider:
429
- if cicd:
430
- final_response = FeedbackManager.error_cicd_already_exists(provider=cicd_provider.name)
431
- error = True
432
- else:
433
- click.echo(FeedbackManager.info_cicd_already_exists(provider=cicd_provider.name))
434
- else:
435
- if cicd:
436
- data_project_dir = os.path.relpath(folder, cli_git_release.working_dir())
437
- await init_cicd(client, path=cli_git_release.working_dir(), data_project_dir=data_project_dir)
438
323
 
439
324
  if final_response:
440
325
  if error:
@@ -452,7 +337,7 @@ def check(filenames: List[str], debug: bool) -> None:
452
337
  filenames = get_project_filenames(".")
453
338
 
454
339
  def process(filenames: Iterable):
455
- parser_matrix = {".pipe": parse_pipe, ".datasource": parse_datasource, ".token": parse_token}
340
+ parser_matrix = {".pipe": parse_pipe, ".datasource": parse_datasource}
456
341
  incl_suffix = ".incl"
457
342
  try:
458
343
  for filename in filenames:
@@ -1473,11 +1358,6 @@ async def deploy(
1473
1358
  new_release = True
1474
1359
 
1475
1360
  if new_release:
1476
- if not dry_run:
1477
- try:
1478
- await create_release(client, config, semver)
1479
- except OperationCanNotBePerformed as e:
1480
- raise CLIException(FeedbackManager.error_exception(error=str(e)))
1481
1361
  release_created = True
1482
1362
  fork_downstream = True
1483
1363
  # allows TB_CHECK_BACKFILL_REQUIRED=0 so it is not checked
@@ -27,6 +27,7 @@ import click.formatting
27
27
  import humanfriendly
28
28
  import humanfriendly.tables
29
29
  import pyperclip
30
+ import requests
30
31
  from click import Context
31
32
  from click._termui_impl import ProgressBar
32
33
  from humanfriendly.tables import format_pretty_table
@@ -60,7 +61,7 @@ if TYPE_CHECKING:
60
61
 
61
62
  from tinybird.feedback_manager import FeedbackManager, warning_message
62
63
  from tinybird.git_settings import DEFAULT_TINYENV_FILE
63
- from tinybird.syncasync import async_to_sync
64
+ from tinybird.syncasync import async_to_sync, sync_to_async
64
65
  from tinybird.tb.modules.cicd import APPEND_FIXTURES_SH, DEFAULT_REQUIREMENTS_FILE, EXEC_TEST_SH
65
66
  from tinybird.tb.modules.config import CLIConfig
66
67
  from tinybird.tb.modules.exceptions import (
@@ -160,10 +161,17 @@ def normalize_datasource_name(s: str) -> str:
160
161
 
161
162
 
162
163
  def generate_datafile(
163
- datafile: str, filename: str, data: Optional[bytes], force: Optional[bool] = False, _format: Optional[str] = "csv"
164
+ datafile: str,
165
+ filename: str,
166
+ data: Optional[bytes],
167
+ force: Optional[bool] = False,
168
+ _format: Optional[str] = "csv",
169
+ parent_dir: Optional[str] = None,
164
170
  ):
165
171
  p = Path(filename)
166
172
  base = Path("datasources")
173
+ if parent_dir:
174
+ base = Path(parent_dir) / base
167
175
  datasource_name = normalize_datasource_name(p.stem)
168
176
  if not base.exists():
169
177
  base = Path()
@@ -2096,3 +2104,7 @@ def get_ca_pem_content(ca_pem: Optional[str], filename: Optional[str] = None) ->
2096
2104
  raise CLIConnectionException(FeedbackManager.error_connection_invalid_ca_pem())
2097
2105
 
2098
2106
  return ca_pem_content
2107
+
2108
+
2109
+ requests_get = sync_to_async(requests.get, thread_sensitive=False)
2110
+ requests_delete = sync_to_async(requests.delete, thread_sensitive=False)
@@ -1,7 +1,7 @@
1
1
  import os
2
2
  from os import getcwd
3
3
  from pathlib import Path
4
- from typing import Any, Dict, List, Optional
4
+ from typing import Optional
5
5
 
6
6
  import click
7
7
  from click import Context
@@ -12,7 +12,7 @@ from tinybird.tb.modules.cicd import init_cicd
12
12
  from tinybird.tb.modules.cli import cli
13
13
  from tinybird.tb.modules.common import _generate_datafile, coro, generate_datafile, push_data
14
14
  from tinybird.tb.modules.config import CLIConfig
15
- from tinybird.tb.modules.datafile import folder_build
15
+ from tinybird.tb.modules.datafile.build import folder_build
16
16
  from tinybird.tb.modules.exceptions import CLIDatasourceException
17
17
  from tinybird.tb.modules.llm import LLM
18
18
  from tinybird.tb.modules.local import (
@@ -55,15 +55,7 @@ async def create(
55
55
  click.echo(FeedbackManager.gray(message="Creating new project structure..."))
56
56
  await project_create(tb_client, data, prompt, folder)
57
57
  click.echo(FeedbackManager.success(message="✓ Scaffolding completed!\n"))
58
- workspaces: List[Dict[str, Any]] = (await tb_client.user_workspaces()).get("workspaces", [])
59
- datasources = await tb_client.datasources()
60
- pipes = await tb_client.pipes(dependencies=True)
61
- await folder_build(
62
- tb_client,
63
- workspaces,
64
- datasources,
65
- pipes,
66
- )
58
+ await folder_build(tb_client, folder=folder)
67
59
 
68
60
  await init_cicd(data_project_dir=os.path.relpath(folder))
69
61
 
@@ -102,8 +94,10 @@ async def project_create(
102
94
  except FileExistsError:
103
95
  click.echo(FeedbackManager.info_path_created(path=x))
104
96
 
105
- def generate_pipe_file(name: str, content: str):
97
+ def generate_pipe_file(name: str, content: str, parent_dir: Optional[str] = None):
106
98
  base = Path("endpoints")
99
+ if parent_dir:
100
+ base = Path(parent_dir) / base
107
101
  if not base.exists():
108
102
  base = Path()
109
103
  f = base / (f"{name}.pipe")
@@ -168,8 +162,10 @@ SQL >
168
162
  LIMIT 5
169
163
  TYPE ENDPOINT
170
164
  """
171
- generate_datafile(events_ds, filename="events.datasource", data=None, _format="ndjson", force=force)
172
- generate_pipe_file("top_airlines", top_airlines)
165
+ generate_datafile(
166
+ events_ds, filename="events.datasource", data=None, _format="ndjson", force=force, parent_dir=folder
167
+ )
168
+ generate_pipe_file("top_airlines", top_airlines, parent_dir=folder)
173
169
 
174
170
 
175
171
  async def append_datasource(