tinybird 0.0.1.dev17__py3-none-any.whl → 0.0.1.dev18__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.
@@ -6,7 +6,6 @@ from pathlib import Path
6
6
  from typing import Any, Awaitable, Callable, List, Union
7
7
 
8
8
  import click
9
- from click import Context
10
9
  from watchdog.events import FileSystemEventHandler
11
10
  from watchdog.observers import Observer
12
11
 
@@ -16,7 +15,7 @@ from tinybird.config import FeatureFlags
16
15
  from tinybird.feedback_manager import FeedbackManager
17
16
  from tinybird.tb.modules.build_shell import BuildShell, print_table_formatted
18
17
  from tinybird.tb.modules.cli import cli
19
- from tinybird.tb.modules.common import coro, push_data
18
+ from tinybird.tb.modules.common import push_data
20
19
  from tinybird.tb.modules.datafile.build import folder_build
21
20
  from tinybird.tb.modules.datafile.common import get_project_filenames, get_project_fixtures, has_internal_datafiles
22
21
  from tinybird.tb.modules.datafile.exceptions import ParseException
@@ -101,10 +100,7 @@ def watch_files(
101
100
  is_flag=True,
102
101
  help="Watch for changes in the files and re-check them.",
103
102
  )
104
- @click.pass_context
105
- @coro
106
- async def build(
107
- ctx: Context,
103
+ def build(
108
104
  folder: str,
109
105
  watch: bool,
110
106
  ) -> None:
@@ -115,7 +111,7 @@ async def build(
115
111
  context.disable_template_security_validation.set(True)
116
112
  is_internal = has_internal_datafiles(folder)
117
113
  folder_path = os.path.abspath(folder)
118
- tb_client = await get_tinybird_local_client(folder_path)
114
+ tb_client = asyncio.run(get_tinybird_local_client(folder_path))
119
115
 
120
116
  def check_filenames(filenames: List[str]):
121
117
  parser_matrix = {".pipe": parse_pipe, ".datasource": parse_datasource}
@@ -191,16 +187,28 @@ async def build(
191
187
  ok = False
192
188
  return ok
193
189
 
194
- build_ok = await build_once(filenames)
190
+ build_ok = asyncio.run(build_once(filenames))
195
191
 
196
192
  if watch:
197
- shell = BuildShell(folder=folder, client=tb_client)
193
+ paths = [Path(f) for f in get_project_filenames(folder, with_vendor=True)]
194
+
195
+ def is_vendor(f: Path) -> bool:
196
+ return "vendor/" in f.parts
197
+
198
+ def get_vendor_workspace(f: Path) -> str:
199
+ return f.parts[1]
200
+
201
+ datasource_paths = [f for f in paths if f.suffix == ".datasource"]
202
+ datasources = [f.stem for f in datasource_paths if not is_vendor(f)]
203
+ shared_datasources = [f"{get_vendor_workspace(f)}.{f.stem}" for f in datasource_paths if is_vendor(f)]
204
+ pipes = [f.stem for f in paths if f.suffix == ".pipe" and not is_vendor(f)]
205
+ shell = BuildShell(folder=folder, client=tb_client, datasources=datasources + shared_datasources, pipes=pipes)
198
206
  click.echo(FeedbackManager.highlight(message="◎ Watching for changes..."))
199
207
  watcher_thread = threading.Thread(
200
208
  target=watch_files, args=(filenames, process, shell, folder, build_ok), daemon=True
201
209
  )
202
210
  watcher_thread.start()
203
- shell.cmdloop()
211
+ shell.run_shell()
204
212
 
205
213
 
206
214
  async def build_and_print_resource(tb_client: TinyB, filename: str):
@@ -1,11 +1,19 @@
1
1
  import asyncio
2
- import cmd
2
+ import concurrent.futures
3
+ import os
3
4
  import random
4
5
  import subprocess
5
6
  import sys
7
+ from typing import List
6
8
 
7
9
  import click
8
10
  import humanfriendly
11
+ from prompt_toolkit import PromptSession
12
+ from prompt_toolkit.completion import Completer, Completion
13
+ from prompt_toolkit.history import FileHistory
14
+ from prompt_toolkit.key_binding import KeyBindings
15
+ from prompt_toolkit.shortcuts import CompleteStyle
16
+ from prompt_toolkit.styles import Style
9
17
 
10
18
  from tinybird.client import TinyB
11
19
  from tinybird.feedback_manager import FeedbackManager, bcolors
@@ -13,43 +21,217 @@ from tinybird.tb.modules.exceptions import CLIException
13
21
  from tinybird.tb.modules.table import format_table
14
22
 
15
23
 
16
- class BuildShell(cmd.Cmd):
17
- prompt = "\n\001\033[1;32m\002tb > \001\033[0m\002"
24
+ class DynamicCompleter(Completer):
25
+ def __init__(self, datasources: List[str], pipes: List[str]):
26
+ self.datasources = datasources
27
+ self.pipes = pipes
28
+ self.static_commands = ["create", "mock", "test", "select"]
29
+ self.mock_flags = ["--prompt", "--rows"]
30
+ self.common_rows = ["10", "50", "100", "500", "1000"]
31
+ self.sql_keywords = ["select", "from", "where", "group by", "order by", "limit"]
18
32
 
19
- def __init__(self, folder: str, client: TinyB):
20
- super().__init__()
33
+ def get_completions(self, document, complete_event):
34
+ text = document.text_before_cursor.strip()
35
+ words = text.split()
36
+
37
+ # Normalize command by removing 'tb' prefix if present
38
+ if words and words[0] == "tb":
39
+ words = words[1:]
40
+
41
+ if not words:
42
+ # Show all available commands when no input
43
+ yield from self._yield_static_commands("")
44
+ return
45
+
46
+ command = words[0].lower()
47
+
48
+ if command == "mock":
49
+ yield from self._handle_mock_completions(words)
50
+ elif command == "select" or self._is_sql_query(text.lower()):
51
+ yield from self._handle_sql_completions(text)
52
+ else:
53
+ # Handle general command completions
54
+ yield from self._yield_static_commands(words[-1])
55
+
56
+ def _is_sql_query(self, text: str) -> bool:
57
+ """Check if the input looks like a SQL query."""
58
+ sql_starters = ["select", "with"]
59
+ return any(text.startswith(starter) for starter in sql_starters)
60
+
61
+ def _handle_sql_completions(self, text: str):
62
+ """Handle completions for SQL queries."""
63
+ text_lower = text.lower()
64
+
65
+ # Find the last complete word
66
+ words = text_lower.split()
67
+ if not words:
68
+ return
69
+
70
+ # If we just typed 'from' or there's a space after 'from', suggest datasources
71
+ if words[-1] == "from" or (
72
+ "from" in words and len(words) > words.index("from") + 1 and text_lower.endswith(" ")
73
+ ):
74
+ for x in self.datasources:
75
+ yield Completion(x, start_position=0, display=x, style="class:completion.datasource")
76
+ for x in self.pipes:
77
+ yield Completion(x, start_position=0, display=x, style="class:completion.pipe")
78
+ return
79
+
80
+ # If we're starting a query, suggest SQL keywords
81
+ if len(words) <= 2:
82
+ for keyword in self.sql_keywords:
83
+ if keyword.lower().startswith(words[-1]):
84
+ yield Completion(
85
+ keyword, start_position=-len(words[-1]), display=keyword, style="class:completion.keyword"
86
+ )
87
+
88
+ def _handle_mock_completions(self, words: List[str]):
89
+ if len(words) == 1:
90
+ # After 'mock', show datasources
91
+ for ds in self.datasources:
92
+ yield Completion(ds, start_position=0, display=ds, style="class:completion.cmd")
93
+ return
94
+
95
+ if len(words) == 2 or len(words) == 4:
96
+ # After datasource or after a flag value, show available flags
97
+ available_flags = [f for f in self.mock_flags if f not in words]
98
+ for flag in available_flags:
99
+ yield Completion(flag, start_position=0, display=flag)
100
+ return
101
+
102
+ last_word = words[-1]
103
+ if last_word == "--prompt":
104
+ yield Completion('""', start_position=0, display='"Enter your prompt..."')
105
+ elif last_word == "--rows":
106
+ for rows in self.common_rows:
107
+ yield Completion(rows, start_position=0, display=rows)
108
+
109
+ def _yield_static_commands(self, current_word: str):
110
+ for cmd in self.static_commands:
111
+ if cmd.startswith(current_word):
112
+ yield Completion(
113
+ cmd,
114
+ start_position=-len(current_word) if current_word else 0,
115
+ display=cmd,
116
+ style="class:completion.cmd",
117
+ )
118
+
119
+
120
+ style = Style.from_dict(
121
+ {
122
+ "prompt": "fg:#34D399 bold",
123
+ "completion.cmd": "fg:#34D399 bg:#111111 bold",
124
+ "completion.datasource": "fg:#AB49D0 bg:#111111",
125
+ "completion.pipe": "fg:#FEA827 bg:#111111",
126
+ "completion.keyword": "fg:#34D399 bg:#111111",
127
+ }
128
+ )
129
+
130
+ key_bindings = KeyBindings()
131
+
132
+
133
+ @key_bindings.add("c-d")
134
+ def _(event):
135
+ """
136
+ Start auto completion. If the menu is showing already, select the next
137
+ completion.
138
+ """
139
+ b = event.app.current_buffer
140
+ if b.complete_state:
141
+ b.complete_next()
142
+ else:
143
+ b.start_completion(select_first=False)
144
+
145
+
146
+ class BuildShell:
147
+ def __init__(self, folder: str, client: TinyB, datasources: List[str], pipes: List[str]):
148
+ self.history = self.get_history()
21
149
  self.folder = folder
22
150
  self.client = client
151
+ self.datasources = datasources
152
+ self.pipes = pipes
153
+ self.prompt_message = "\ntb > "
154
+ self.commands = ["create", "mock", "test", "tb", "select"]
155
+
156
+ self.session = PromptSession(
157
+ completer=DynamicCompleter(self.datasources, self.pipes),
158
+ complete_style=CompleteStyle.COLUMN,
159
+ complete_while_typing=True,
160
+ history=self.history,
161
+ )
162
+
163
+ def get_history(self):
164
+ try:
165
+ history_file = os.path.expanduser("~/.tb_history")
166
+ return FileHistory(history_file)
167
+ except Exception:
168
+ return None
169
+
170
+ def run_shell(self):
171
+ while True:
172
+ try:
173
+ user_input = self.session.prompt(
174
+ [("class:prompt", self.prompt_message)], style=style, key_bindings=key_bindings
175
+ )
176
+ self.handle_input(user_input)
177
+ except (EOFError, KeyboardInterrupt):
178
+ sys.exit(0)
179
+ except CLIException as e:
180
+ click.echo(str(e))
181
+ except Exception as e:
182
+ # Catch-all for unexpected exceptions
183
+ click.echo(FeedbackManager.error_exception(error=str(e)))
23
184
 
24
- def do_exit(self, arg):
25
- sys.exit(0)
185
+ def handle_input(self, argline):
186
+ line = argline.strip()
187
+ if not line:
188
+ return
26
189
 
27
- def do_quit(self, arg):
28
- sys.exit(0)
190
+ # Implement the command logic here
191
+ # Replace do_* methods with equivalent logic:
192
+ command_parts = line.split(maxsplit=1)
193
+ cmd = command_parts[0].lower()
194
+ arg = command_parts[1] if len(command_parts) > 1 else ""
195
+
196
+ if cmd in ["exit", "quit"]:
197
+ sys.exit(0)
198
+ elif cmd == "build":
199
+ self.handle_build(arg)
200
+ elif cmd == "auth":
201
+ self.handle_auth(arg)
202
+ elif cmd == "workspace":
203
+ self.handle_workspace(arg)
204
+ elif cmd == "mock":
205
+ self.handle_mock(arg)
206
+ elif cmd == "tb":
207
+ self.handle_tb(arg)
208
+ else:
209
+ # Check if it looks like a SQL query or run as a tb command
210
+ self.default(line)
29
211
 
30
- def do_build(self, arg):
212
+ def handle_build(self, arg):
31
213
  click.echo(FeedbackManager.error(message=f"'tb {arg}' command is not available in watch mode"))
32
214
 
33
- def do_auth(self, arg):
215
+ def handle_auth(self, arg):
34
216
  click.echo(FeedbackManager.error(message=f"'tb {arg}' command is not available in watch mode"))
35
217
 
36
- def do_workspace(self, arg):
218
+ def handle_workspace(self, arg):
37
219
  click.echo(FeedbackManager.error(message=f"'tb {arg}' command is not available in watch mode"))
38
220
 
39
- def do_mock(self, arg):
221
+ def handle_mock(self, arg):
40
222
  subprocess.run(f"tb mock {arg} --folder {self.folder}", shell=True, text=True)
41
223
 
42
- def do_tb(self, arg):
224
+ def handle_tb(self, arg):
43
225
  click.echo("")
44
226
  arg = arg.strip().lower()
45
227
  if arg.startswith("build"):
46
- self.do_build(arg)
228
+ self.handle_build(arg)
47
229
  elif arg.startswith("auth"):
48
- self.do_auth(arg)
230
+ self.handle_auth(arg)
49
231
  elif arg.startswith("workspace"):
50
- self.do_workspace(arg)
232
+ self.handle_workspace(arg)
51
233
  elif arg.startswith("mock"):
52
- self.do_mock(arg)
234
+ self.handle_mock(arg)
53
235
  else:
54
236
  subprocess.run(f"tb --local {arg}", shell=True, text=True)
55
237
 
@@ -66,20 +248,15 @@ class BuildShell(cmd.Cmd):
66
248
  else:
67
249
  subprocess.run(f"tb --local {arg}", shell=True, text=True)
68
250
 
69
- def reprint_prompt(self):
70
- self.stdout.write(self.prompt)
71
- self.stdout.flush()
72
-
73
251
  def run_sql(self, query, rows_limit=20):
74
252
  try:
75
253
  q = query.strip()
76
- if q.startswith("insert"):
254
+ if q.lower().startswith("insert"):
77
255
  click.echo(FeedbackManager.info_append_data())
78
256
  raise CLIException(FeedbackManager.error_invalid_query())
79
- if q.startswith("delete"):
257
+ if q.lower().startswith("delete"):
80
258
  raise CLIException(FeedbackManager.error_invalid_query())
81
259
 
82
- # fuck my life
83
260
  def run_query_in_thread():
84
261
  loop = asyncio.new_event_loop()
85
262
  asyncio.set_event_loop(loop)
@@ -90,9 +267,6 @@ class BuildShell(cmd.Cmd):
90
267
  finally:
91
268
  loop.close()
92
269
 
93
- # Run the query in a separate thread
94
- import concurrent.futures
95
-
96
270
  with concurrent.futures.ThreadPoolExecutor() as executor:
97
271
  res = executor.submit(run_query_in_thread).result()
98
272
 
@@ -107,6 +281,9 @@ class BuildShell(cmd.Cmd):
107
281
  else:
108
282
  click.echo(FeedbackManager.info_no_rows())
109
283
 
284
+ def reprint_prompt(self):
285
+ click.echo(f"{bcolors.OKGREEN}{self.prompt_message}{bcolors.ENDC}", nl=False)
286
+
110
287
 
111
288
  def print_table_formatted(res: dict, name: str):
112
289
  rebuild_colors = [bcolors.FAIL, bcolors.OKBLUE, bcolors.WARNING, bcolors.OKGREEN, bcolors.HEADER]
@@ -14,9 +14,7 @@ class Provider(Enum):
14
14
  GitLab = 1
15
15
 
16
16
 
17
- WORKFLOW_VERSION = "v3.1.0"
18
-
19
- DEFAULT_REQUIREMENTS_FILE = "tinybird-cli>=5,<6"
17
+ WORKFLOW_VERSION = "v0.0.1"
20
18
 
21
19
  GITHUB_CI_YML = """
22
20
  name: Tinybird - CI Workflow
@@ -50,6 +48,8 @@ jobs:
50
48
  run: curl -LsSf https://api.tinybird.co/static/install.sh | sh
51
49
  - name: Build project
52
50
  run: tb build
51
+ - name: Test project
52
+ run: tb test run
53
53
  """
54
54
 
55
55
 
@@ -64,110 +64,30 @@ stages:
64
64
 
65
65
  GITLAB_CI_YML = """
66
66
  tinybird_ci_workflow:
67
+ image: ubuntu:latest
67
68
  stage: tests
68
69
  interruptible: true
69
70
  needs: []
70
71
  rules:
71
- - if: $CI_PIPELINE_SOURCE == "merge_request_event"{% if data_project_dir != '.' %}
72
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
72
73
  changes:
73
- - .gitlab/tinybird/*
74
+ - .gitlab/tinybird/*{% if data_project_dir != '.' %}
74
75
  - {{ data_project_dir }}/*
75
76
  - {{ data_project_dir }}/**/*{% end %}
76
77
  before_script:
78
+ - apt update && apt install -y curl
77
79
  - curl -LsSf https://api.tinybird.co/static/install.sh | sh
78
80
  script:
81
+ - export PATH="$HOME/.local/bin:$PATH"
79
82
  - cd $CI_PROJECT_DIR/{{ data_project_dir }}
80
83
  - tb build
84
+ - tb test run
81
85
  services:
82
86
  - name: tinybirdco/tinybird-local:latest
83
87
  alias: tinybird-local
84
88
  """
85
89
 
86
90
 
87
- EXEC_TEST_SH = """
88
- #!/usr/bin/env bash
89
- set -euxo pipefail
90
-
91
- export TB_VERSION_WARNING=0
92
-
93
- run_test() {
94
- t=$1
95
- echo "** Running $t **"
96
- echo "** $(cat $t)"
97
- tmpfile=$(mktemp)
98
- retries=0
99
- TOTAL_RETRIES=3
100
-
101
- # When appending fixtures, we need to retry in case of the data is not replicated in time
102
- while [ $retries -lt $TOTAL_RETRIES ]; do
103
- # Run the test and store the output in a temporary file
104
- bash $t $2 >$tmpfile
105
- exit_code=$?
106
- if [ "$exit_code" -eq 0 ]; then
107
- # If the test passed, break the loop
108
- if diff -B ${t}.result $tmpfile >/dev/null 2>&1; then
109
- break
110
- # If the test failed, increment the retries counter and try again
111
- else
112
- retries=$((retries+1))
113
- fi
114
- # If the bash command failed, print an error message and break the loop
115
- else
116
- break
117
- fi
118
- done
119
-
120
- if diff -B ${t}.result $tmpfile >/dev/null 2>&1; then
121
- echo "✅ Test $t passed"
122
- rm $tmpfile
123
- return 0
124
- elif [ $retries -eq $TOTAL_RETRIES ]; then
125
- echo "🚨 ERROR: Test $t failed, diff:";
126
- diff -B ${t}.result $tmpfile
127
- rm $tmpfile
128
- return 1
129
- else
130
- echo "🚨 ERROR: Test $t failed with bash command exit code $?"
131
- cat $tmpfile
132
- rm $tmpfile
133
- return 1
134
- fi
135
- echo ""
136
- }
137
- export -f run_test
138
-
139
- fail=0
140
- find ./tests -name "*.test" -print0 | xargs -0 -I {} -P 4 bash -c 'run_test "$@"' _ {} || fail=1
141
-
142
- if [ $fail == 1 ]; then
143
- exit -1;
144
- fi
145
- """
146
-
147
- APPEND_FIXTURES_SH = """
148
- #!/usr/bin/env bash
149
- set -euxo pipefail
150
-
151
- directory="datasources/fixtures"
152
- extensions=("csv" "ndjson")
153
-
154
- absolute_directory=$(realpath "$directory")
155
-
156
- for extension in "${extensions[@]}"; do
157
- file_list=$(find "$absolute_directory" -type f -name "*.$extension")
158
-
159
- for file_path in $file_list; do
160
- file_name=$(basename "$file_path")
161
- file_name_without_extension="${file_name%.*}"
162
-
163
- command="tb datasource append $file_name_without_extension datasources/fixtures/$file_name"
164
- echo $command
165
- $command
166
- done
167
- done
168
- """
169
-
170
-
171
91
  class CICDFile:
172
92
  def __init__(
173
93
  self,
@@ -17,7 +17,7 @@ from contextlib import closing
17
17
  from copy import deepcopy
18
18
  from enum import Enum
19
19
  from functools import wraps
20
- from os import chmod, environ, getcwd, getenv
20
+ from os import environ, getcwd, getenv
21
21
  from pathlib import Path
22
22
  from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, Union
23
23
  from urllib.parse import urlparse
@@ -61,9 +61,7 @@ if TYPE_CHECKING:
61
61
  from tinybird.connectors import Connector
62
62
 
63
63
  from tinybird.feedback_manager import FeedbackManager, warning_message
64
- from tinybird.git_settings import DEFAULT_TINYENV_FILE
65
64
  from tinybird.syncasync import async_to_sync, sync_to_async
66
- from tinybird.tb.modules.cicd import APPEND_FIXTURES_SH, DEFAULT_REQUIREMENTS_FILE, EXEC_TEST_SH
67
65
  from tinybird.tb.modules.config import CLIConfig
68
66
  from tinybird.tb.modules.exceptions import (
69
67
  CLIAuthException,
@@ -371,111 +369,6 @@ async def folder_init(
371
369
  for path in Path(folder).glob(f"*.{format}"):
372
370
  await _generate_datafile(str(path), client, format=format, force=force)
373
371
 
374
- if generate_releases:
375
- base = Path(".")
376
- f = base / (".tinyenv")
377
- if not f.exists() or force:
378
- async with aiofiles.open(".tinyenv", "w") as file:
379
- await file.write(DEFAULT_TINYENV_FILE)
380
- click.echo(FeedbackManager.info_file_created(file=".tinyenv"))
381
- else:
382
- click.echo(FeedbackManager.info_dottinyenv_already_exists())
383
-
384
- base = Path(".")
385
- f = base / ("requirements.txt")
386
- if not f.exists() or force:
387
- async with aiofiles.open("requirements.txt", "w") as file:
388
- await file.write(DEFAULT_REQUIREMENTS_FILE)
389
- click.echo(FeedbackManager.info_file_created(file="requirements.txt"))
390
-
391
- base = Path("scripts")
392
- if not base.exists():
393
- base = Path()
394
- f = base / ("exec_test.sh")
395
- if not f.exists() or force:
396
- async with aiofiles.open(f"{f}", "w") as t_file:
397
- await t_file.write(EXEC_TEST_SH)
398
- click.echo(FeedbackManager.info_file_created(file="scripts/exec_test.sh"))
399
- chmod(f, 0o755)
400
-
401
- f = base / ("append_fixtures.sh")
402
- if not f.exists() or force:
403
- async with aiofiles.open(f"{f}", "w") as t_file:
404
- await t_file.write(APPEND_FIXTURES_SH)
405
- click.echo(FeedbackManager.info_file_created(file="scripts/append_fixtures.sh"))
406
- chmod(f, 0o755)
407
-
408
- base = Path("tests")
409
- if not base.exists():
410
- base = Path()
411
- f = base / ("example.yml")
412
- if not base.exists() or force:
413
- async with aiofiles.open(f"{f}", "w") as t_file:
414
- await t_file.write(
415
- """
416
- ##############################################################################################################################
417
- ### Visit https://www.tinybird.co/docs/production/implementing-test-strategies.html#data-quality-tests ###
418
- ### for more details on Data Quality tests ###
419
- ##############################################################################################################################
420
-
421
- - example_no_negative_numbers:
422
- max_bytes_read: null
423
- max_time: null
424
- sql: |
425
- SELECT
426
- number
427
- FROM numbers(10)
428
- WHERE
429
- number < 0
430
-
431
- # - example_top_products_params_no_empty_top_10_on_2023:
432
- # max_bytes_read: null
433
- # max_time: null
434
- # sql: |
435
- # SELECT *
436
- # FROM top_products_params
437
- # WHERE empty(top_10)
438
- # pipe:
439
- # name: top_products_params
440
- # params:
441
- # start: '2023-01-01'
442
- # end: '2023-12-31'
443
-
444
- """
445
- )
446
-
447
- f = base / ("regression.yaml")
448
- if not base.exists() or force:
449
- async with aiofiles.open(f"{f}", "w") as t_file:
450
- await t_file.write(
451
- """
452
- ############################################################################################################################
453
- ### Visit https://www.tinybird.co/docs/production/implementing-test-strategies.html#regression-tests ###
454
- ### for more details on Regression tests ###
455
- ############################################################################################################################
456
-
457
- ###
458
- ### New pipes are covered by this rule, rules below this one supersede this setting
459
- ###
460
- - pipe: '.*'
461
- tests:
462
- - coverage:
463
-
464
-
465
-
466
- ###
467
- ### These are rules to customize regression testing by pipe using regular expressions
468
- ### For instance skip regression tests for the pipes matching `endpoint_name.*`
469
- ###
470
- - pipe: 'endpoint_name.*'
471
- tests:
472
- - coverage:
473
- config:
474
- skip: True
475
-
476
- """
477
- )
478
-
479
372
 
480
373
  async def configure_connector(connector):
481
374
  if connector not in SUPPORTED_CONNECTORS:
@@ -1,5 +1,4 @@
1
1
  import os
2
- import subprocess
3
2
  from os import getcwd
4
3
  from pathlib import Path
5
4
  from typing import Optional
@@ -126,7 +125,7 @@ async def create(
126
125
  test_name = "api_token_usage"
127
126
  test_path = Path(folder) / "tests" / f"{test_name}.yaml"
128
127
  test_content = fetch_gist_content(
129
- "https://gist.githubusercontent.com/gnzjgo/e58620bbb977d6f42f1d0c2a7b46ac8f/raw/a5f61d5019111f937484f941111829dfce69f648/api_token_usage.yaml"
128
+ "https://gist.githubusercontent.com/gnzjgo/e58620bbb977d6f42f1d0c2a7b46ac8f/raw/a3a1cd0ce3a90bcd2f6dfce00da51e6051443612/api_token_usage.yaml"
130
129
  )
131
130
  test_path.write_text(test_content)
132
131
  click.echo(FeedbackManager.info(message=f"✓ /tests/{test_name}.yaml"))
@@ -147,7 +146,7 @@ async def create(
147
146
  datasource_content = datasource_path.read_text()
148
147
  has_json_path = "`json:" in datasource_content
149
148
  if has_json_path:
150
- sql = await llm.generate_sql_sample_data(schema=datasource_content, rows=rows, context=prompt)
149
+ sql = await llm.generate_sql_sample_data(schema=datasource_content, rows=rows, prompt=prompt)
151
150
  result = await tb_client.query(f"{sql} FORMAT JSON")
152
151
  data = result.get("data", [])
153
152
  fixture_name = build_fixture_name(datasource_path.absolute(), datasource_name, datasource_content)
@@ -214,9 +213,6 @@ def init_git(folder: str):
214
213
  try:
215
214
  path = Path(folder)
216
215
  gitignore_file = path / ".gitignore"
217
- git_folder = path / ".git"
218
- if not git_folder.exists():
219
- subprocess.run(["git", "init"], cwd=path, check=True, capture_output=True)
220
216
 
221
217
  if gitignore_file.exists():
222
218
  content = gitignore_file.read_text()