tinybird 0.0.1.dev123__tar.gz → 0.0.1.dev125__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.

Files changed (109) hide show
  1. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/PKG-INFO +1 -1
  2. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/__cli__.py +2 -2
  3. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/config.py +4 -0
  4. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/build.py +32 -7
  5. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/common.py +1 -1
  6. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/create.py +9 -6
  7. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/fixture.py +11 -2
  8. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datasource.py +1 -1
  9. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/mock.py +19 -9
  10. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/telemetry.py +17 -2
  11. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/watch.py +5 -2
  12. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird.egg-info/PKG-INFO +1 -1
  13. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/setup.cfg +0 -0
  14. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/__cli__.py +0 -0
  15. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/ch_utils/constants.py +0 -0
  16. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/ch_utils/engine.py +0 -0
  17. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/check_pypi.py +0 -0
  18. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/client.py +0 -0
  19. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/config.py +0 -0
  20. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/connectors.py +0 -0
  21. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/context.py +0 -0
  22. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/datafile.py +0 -0
  23. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/datatypes.py +0 -0
  24. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/feedback_manager.py +0 -0
  25. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/git_settings.py +0 -0
  26. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/prompts.py +0 -0
  27. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/sql.py +0 -0
  28. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/sql_template.py +0 -0
  29. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/sql_template_fmt.py +0 -0
  30. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/sql_toolset.py +0 -0
  31. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/syncasync.py +0 -0
  32. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/cli.py +0 -0
  33. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/client.py +0 -0
  34. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/auth.py +0 -0
  35. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/cicd.py +0 -0
  36. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/cli.py +0 -0
  37. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/config.py +0 -0
  38. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/connection.py +0 -0
  39. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/copy.py +0 -0
  40. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/build.py +0 -0
  41. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/build_common.py +0 -0
  42. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  43. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  44. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/common.py +0 -0
  45. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/diff.py +0 -0
  46. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/exceptions.py +0 -0
  47. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/format_common.py +0 -0
  48. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  49. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  50. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/parse_datasource.py +0 -0
  51. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/parse_pipe.py +0 -0
  52. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  53. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/playground.py +0 -0
  54. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/datafile/pull.py +0 -0
  55. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/deployment.py +0 -0
  56. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/endpoint.py +0 -0
  57. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/exceptions.py +0 -0
  58. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/feedback_manager.py +0 -0
  59. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/fmt.py +0 -0
  60. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/infra.py +0 -0
  61. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/job.py +0 -0
  62. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/llm.py +0 -0
  63. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/llm_utils.py +0 -0
  64. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/local.py +0 -0
  65. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/local_common.py +0 -0
  66. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/login.py +0 -0
  67. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/logout.py +0 -0
  68. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/materialization.py +0 -0
  69. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/open.py +0 -0
  70. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/pipe.py +0 -0
  71. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/project.py +0 -0
  72. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/regions.py +0 -0
  73. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/secret.py +0 -0
  74. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/shell.py +0 -0
  75. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/table.py +0 -0
  76. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/tag.py +0 -0
  77. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/test.py +0 -0
  78. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  79. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  80. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/token.py +0 -0
  81. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/workspace.py +0 -0
  82. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb/modules/workspace_members.py +0 -0
  83. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli.py +0 -0
  84. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/auth.py +0 -0
  85. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/branch.py +0 -0
  86. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/cicd.py +0 -0
  87. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/cli.py +0 -0
  88. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/common.py +0 -0
  89. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/config.py +0 -0
  90. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/connection.py +0 -0
  91. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/datasource.py +0 -0
  92. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/exceptions.py +0 -0
  93. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/fmt.py +0 -0
  94. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/job.py +0 -0
  95. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/pipe.py +0 -0
  96. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/regions.py +0 -0
  97. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/tag.py +0 -0
  98. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/telemetry.py +0 -0
  99. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/test.py +0 -0
  100. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  101. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  102. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/workspace.py +0 -0
  103. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  104. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird/tornado_template.py +0 -0
  105. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird.egg-info/SOURCES.txt +0 -0
  106. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird.egg-info/dependency_links.txt +0 -0
  107. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird.egg-info/entry_points.txt +0 -0
  108. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird.egg-info/requires.txt +0 -0
  109. {tinybird-0.0.1.dev123 → tinybird-0.0.1.dev125}/tinybird.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev123
3
+ Version: 0.0.1.dev125
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird
@@ -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.dev123'
8
- __revision__ = '01f52fe'
7
+ __version__ = '0.0.1.dev125'
8
+ __revision__ = '57c6bd7'
@@ -65,6 +65,10 @@ async def get_config(
65
65
  config["host"] = host or config.get("host", DEFAULT_API_HOST)
66
66
  config["workspaces"] = config.get("workspaces", [])
67
67
  config["cwd"] = config.get("cwd", getcwd())
68
+ config["user_email"] = config.get("user_email", None)
69
+ config["user_id"] = config.get("user_id", None)
70
+ config["workspace_id"] = config.get("id", None)
71
+ config["workspace_name"] = config.get("name", None)
68
72
  return config
69
73
 
70
74
 
@@ -20,7 +20,7 @@ from tinybird.tb.modules.common import push_data
20
20
  from tinybird.tb.modules.config import CLIConfig
21
21
  from tinybird.tb.modules.datafile.build import folder_build
22
22
  from tinybird.tb.modules.datafile.exceptions import ParseException
23
- from tinybird.tb.modules.datafile.fixture import get_fixture_dir, persist_fixture
23
+ from tinybird.tb.modules.datafile.fixture import FixtureExtension, get_fixture_dir, persist_fixture
24
24
  from tinybird.tb.modules.datafile.parse_datasource import parse_datasource
25
25
  from tinybird.tb.modules.datafile.parse_pipe import parse_pipe
26
26
  from tinybird.tb.modules.datafile.playground import folder_playground
@@ -145,8 +145,21 @@ def build_project(project: Project, tb_client: TinyB, file_changed: Optional[str
145
145
  ds_path = Path(filename)
146
146
  ds_name = ds_path.stem
147
147
  fixture_folder = get_fixture_dir(project.folder)
148
- fixture_path = fixture_folder / f"{ds_name}.ndjson"
149
- if fixture_path.exists():
148
+ fixture_extensions = [FixtureExtension.NDJSON, FixtureExtension.CSV]
149
+ fixture_path = next(
150
+ (
151
+ fixture_folder / f"{ds_name}{ext}"
152
+ for ext in fixture_extensions
153
+ if (fixture_folder / f"{ds_name}{ext}").exists()
154
+ ),
155
+ None,
156
+ )
157
+ if not fixture_path:
158
+ sql_path = fixture_folder / f"{ds_name}.sql"
159
+ if sql_path.exists():
160
+ fixture_path = rebuild_fixture_sql(project, tb_client, str(sql_path))
161
+
162
+ if fixture_path:
150
163
  append_fixture(tb_client, ds_name, str(fixture_path))
151
164
 
152
165
  except Exception as e:
@@ -252,7 +265,7 @@ def process(
252
265
  ) -> None:
253
266
  time_start = time.time()
254
267
  build_failed = False
255
- if file_changed and file_changed.endswith(".ndjson"):
268
+ if file_changed and (file_changed.endswith(FixtureExtension.NDJSON) or file_changed.endswith(FixtureExtension.CSV)):
256
269
  rebuild_fixture(project, tb_client, file_changed)
257
270
  elif file_changed and file_changed.endswith(".sql"):
258
271
  rebuild_fixture_sql(project, tb_client, file_changed)
@@ -295,13 +308,25 @@ def run_watch(
295
308
  shell.run()
296
309
 
297
310
 
298
- def rebuild_fixture_sql(project: Project, tb_client: TinyB, sql_file: str) -> None:
311
+ def rebuild_fixture_sql(project: Project, tb_client: TinyB, sql_file: str) -> Path:
299
312
  sql_path = Path(sql_file)
300
313
  datasource_name = sql_path.stem
314
+ valid_extensions = [FixtureExtension.NDJSON, FixtureExtension.CSV]
315
+ fixtures_path = get_fixture_dir(project.folder)
316
+ current_fixture_path = next(
317
+ (
318
+ fixtures_path / f"{datasource_name}{extension}"
319
+ for extension in valid_extensions
320
+ if (fixtures_path / f"{datasource_name}{extension}").exists()
321
+ ),
322
+ None,
323
+ )
324
+ fixture_format = current_fixture_path.suffix.lstrip(".") if current_fixture_path else "ndjson"
301
325
  sql = sql_path.read_text()
302
- result = asyncio.run(tb_client.query(f"{sql} FORMAT JSON"))
326
+ sql_format = "CSV" if fixture_format == "csv" else "JSON"
327
+ result = asyncio.run(tb_client.query(f"{sql} FORMAT {sql_format}"))
303
328
  data = result.get("data", [])
304
- persist_fixture(datasource_name, data, project.folder)
329
+ return persist_fixture(datasource_name, data, project.folder, format=fixture_format)
305
330
 
306
331
 
307
332
  def is_vendor(f: Path) -> bool:
@@ -243,7 +243,7 @@ class CatchAuthExceptions(AliasedGroup):
243
243
  formatter.write_heading("Telemetry")
244
244
  formatter.write_text(
245
245
  """
246
- Tinybird collects anonymous usage data and errors to improve the command
246
+ Tinybird collects usage data and errors to improve the command
247
247
  line experience. To opt-out, set TB_CLI_TELEMETRY_OPTOUT to '1' or 'true'."""
248
248
  )
249
249
  formatter.write_paragraph()
@@ -88,7 +88,8 @@ async def create(
88
88
  click.echo(FeedbackManager.success(message="✓ Scaffolding completed!\n"))
89
89
  created_something = True
90
90
  result = ""
91
- if (data or prompt) and user_token:
91
+
92
+ if data or (prompt and user_token):
92
93
  click.echo(FeedbackManager.highlight(message="\n» Creating resources..."))
93
94
  result, created_something = await create_resources(
94
95
  local_client, tb_client, user_token, data, prompt, folder
@@ -133,10 +134,12 @@ async def create(
133
134
 
134
135
  if data:
135
136
  ds_name = os.path.basename(data.split(".")[0])
136
- data_content = Path(data).read_text()
137
+ data_path = Path(data)
138
+ data_content = data_path.read_text()
139
+ data_format = data_path.suffix.lstrip(".")
137
140
  datasource_path = Path(folder) / "datasources" / f"{ds_name}.datasource"
138
141
  click.echo(FeedbackManager.info(message=f"✓ /fixtures/{ds_name}"))
139
- persist_fixture(ds_name, data_content, folder)
142
+ persist_fixture(ds_name, data_content, folder, format=data_format)
140
143
  created_something = True
141
144
  elif prompt and user_token:
142
145
  datasource_files = [f for f in os.listdir(Path(folder) / "datasources") if f.endswith(".datasource")]
@@ -154,7 +157,7 @@ async def create(
154
157
  query_result = await local_client.query(f"{sql} FORMAT JSON")
155
158
  data = query_result.get("data", [])
156
159
  if data:
157
- persist_fixture(datasource_name, data, folder)
160
+ persist_fixture(datasource_name, data, folder, format="ndjson")
158
161
  click.echo(FeedbackManager.info(message=f"✓ /fixtures/{datasource_name}"))
159
162
  created_something = True
160
163
 
@@ -221,7 +224,7 @@ async def create_resources(
221
224
  path = folder_path / data
222
225
  format = path.suffix.lstrip(".")
223
226
  await _generate_datafile(str(path), local_client, format=format, force=True)
224
- name = data.split(".")[0]
227
+ name = path.stem
225
228
  generate_pipe_file(
226
229
  f"{name}_endpoint",
227
230
  f"""
@@ -354,7 +357,7 @@ def generate_pipe_file(name: str, content: str, folder: str) -> Path:
354
357
 
355
358
  base = Path(folder) / pathname
356
359
  if not base.exists():
357
- base = Path()
360
+ base.mkdir()
358
361
  f = base / (f"{name}.pipe")
359
362
  with open(f"{f}", "w") as file:
360
363
  file.write(content)
@@ -17,10 +17,14 @@ def persist_fixture_sql(fixture_name: str, sql: str, folder: str) -> Path:
17
17
  return fixture_file
18
18
 
19
19
 
20
- def persist_fixture(fixture_name: str, data: Union[List[Dict[str, Any]], str], folder: str, format="ndjson") -> Path:
20
+ def persist_fixture(fixture_name: str, data: Union[List[Dict[str, Any]], str], folder: str, format: str) -> Path:
21
21
  fixture_dir = get_fixture_dir(folder)
22
22
  fixture_file = fixture_dir / f"{fixture_name}.{format}"
23
- fixture_file.write_text(data if isinstance(data, str) else format_data_to_ndjson(data))
23
+ extension = f".{format}"
24
+ if extension == FixtureExtension.NDJSON:
25
+ fixture_file.write_text(data if isinstance(data, str) else format_data_to_ndjson(data))
26
+ elif extension == FixtureExtension.CSV:
27
+ fixture_file.write_text(data if isinstance(data, str) else str(data)) ## this should not happen
24
28
  return fixture_file
25
29
 
26
30
 
@@ -34,3 +38,8 @@ def load_fixture(
34
38
  if not fixture_file.exists():
35
39
  return None
36
40
  return fixture_file
41
+
42
+
43
+ class FixtureExtension:
44
+ NDJSON = ".ndjson"
45
+ CSV = ".csv"
@@ -445,7 +445,7 @@ async def datasource_export(
445
445
 
446
446
  res = await client.query(query)
447
447
 
448
- fixture_path = persist_fixture(datasource, res, project.folder)
448
+ fixture_path = persist_fixture(datasource, res, project.folder, format=format_)
449
449
  file_size = os.path.getsize(fixture_path)
450
450
 
451
451
  click.echo(
@@ -24,9 +24,16 @@ from tinybird.tb.modules.project import Project
24
24
  default="",
25
25
  help="Extra context to use for data generation",
26
26
  )
27
+ @click.option(
28
+ "--format",
29
+ "format_",
30
+ type=click.Choice(["ndjson", "csv"], case_sensitive=False),
31
+ default="ndjson",
32
+ help="Format of the fixture to create",
33
+ )
27
34
  @click.pass_context
28
35
  @coro
29
- async def mock(ctx: click.Context, datasource: str, rows: int, prompt: str) -> None:
36
+ async def mock(ctx: click.Context, datasource: str, rows: int, prompt: str, format_: str) -> None:
30
37
  """Generate sample data for a data source.
31
38
 
32
39
  Args:
@@ -79,13 +86,16 @@ async def mock(ctx: click.Context, datasource: str, rows: int, prompt: str) -> N
79
86
  response = llm.ask(system_prompt=mock_prompt(rows, error), prompt=prompt)
80
87
  sql = extract_xml(response, "sql")
81
88
  sql_path = persist_fixture_sql(datasource_name, sql, folder)
82
- result = await tb_client.query(f"{sql} FORMAT JSON")
83
- data = result.get("data", [])[:rows]
84
- error_response = result.get("error", None)
85
- if error_response:
86
- raise CLIException(error_response)
89
+ sql_format = "JSON" if format_ == "ndjson" else "CSV"
90
+ result = await tb_client.query(f"SELECT * FROM ({sql}) LIMIT {rows} FORMAT {sql_format}")
91
+ if sql_format == "JSON":
92
+ data = result.get("data", [])[:rows]
93
+ error_response = result.get("error", None)
94
+ if error_response:
95
+ raise CLIException(error_response)
87
96
  else:
88
- break
97
+ data = result
98
+ break
89
99
  except Exception as e:
90
100
  error = str(e)
91
101
  attempts += 1
@@ -94,8 +104,8 @@ async def mock(ctx: click.Context, datasource: str, rows: int, prompt: str) -> N
94
104
  else:
95
105
  continue
96
106
 
97
- fixture_path = persist_fixture(datasource_name, data, folder)
98
- click.echo(FeedbackManager.info(message=f"✓ /fixtures/{datasource_name}.ndjson created"))
107
+ fixture_path = persist_fixture(datasource_name, data, folder, format=format_)
108
+ click.echo(FeedbackManager.info(message=f"✓ /fixtures/{datasource_name}.{format_} created"))
99
109
  if env == "cloud":
100
110
  await append_fixture(tb_client, datasource_name, str(fixture_path))
101
111
 
@@ -1,4 +1,5 @@
1
1
  import functools
2
+ import hashlib
2
3
  import json
3
4
  import os
4
5
  import platform
@@ -13,7 +14,8 @@ from urllib.parse import urlencode
13
14
 
14
15
  import requests
15
16
 
16
- from tinybird.tb.config import CURRENT_VERSION
17
+ from tinybird.syncasync import async_to_sync
18
+ from tinybird.tb.config import CURRENT_VERSION, get_config
17
19
 
18
20
  TELEMETRY_TIMEOUT: int = 1
19
21
  TELEMETRY_DATASOURCE: str = "tb_cli_telemetry"
@@ -80,7 +82,11 @@ def _hide_tokens(text: str) -> str:
80
82
 
81
83
 
82
84
  class TelemetryHelper:
83
- def __init__(self, tb_host: Optional[str] = None, max_enqueued_events: int = 5) -> None:
85
+ def __init__(
86
+ self,
87
+ tb_host: Optional[str] = None,
88
+ max_enqueued_events: int = 5,
89
+ ) -> None:
84
90
  self.tb_host = tb_host or os.getenv("TB_CLI_TELEMETRY_HOST", "https://api.tinybird.co")
85
91
  self.max_enqueued_events: int = max_enqueued_events
86
92
 
@@ -112,6 +118,15 @@ class TelemetryHelper:
112
118
  self.log("Not sending events in local development mode")
113
119
  return
114
120
 
121
+ event_data["fingerprint_id"] = hashlib.sha256(platform.node().encode()).hexdigest()
122
+
123
+ config = async_to_sync(get_config)(None, None)
124
+ if config:
125
+ event_data["workspace_id"] = config.get("workspace_id", "")
126
+ event_data["workspace_name"] = config.get("workspace_name", "")
127
+ event_data["user_email"] = config.get("user_email", "")
128
+ event_data["user_id"] = config.get("user_id", "")
129
+
115
130
  # Let's save deep copies to not interfere with original objects
116
131
  event_dict: Dict[str, Any] = deepcopy(self._defaults)
117
132
  event_dict["event"] = event
@@ -16,13 +16,14 @@ from watchdog.events import (
16
16
  from watchdog.observers import Observer
17
17
 
18
18
  from tinybird.tb.modules.datafile.common import Datafile, DatafileKind
19
+ from tinybird.tb.modules.datafile.fixture import FixtureExtension
19
20
  from tinybird.tb.modules.feedback_manager import FeedbackManager
20
21
  from tinybird.tb.modules.project import Project
21
22
  from tinybird.tb.modules.shell import Shell
22
23
 
23
24
 
24
25
  class WatchProjectHandler(PatternMatchingEventHandler):
25
- valid_extensions = [".datasource", ".pipe", "connection", ".ndjson", ".sql"]
26
+ valid_extensions = [".datasource", ".pipe", "connection", FixtureExtension.CSV, FixtureExtension.NDJSON, ".sql"]
26
27
 
27
28
  def __init__(self, shell: Shell, project: Project, process: Callable):
28
29
  self.shell = shell
@@ -163,7 +164,9 @@ class FileChangeHandler(FileSystemEventHandler):
163
164
  is_vendor = "vendor/" in path
164
165
  if is_vendor:
165
166
  return False
166
- return any(path.endswith(ext) for ext in [".datasource", ".pipe", ".ndjson"])
167
+ return any(
168
+ path.endswith(ext) for ext in [".datasource", ".pipe", FixtureExtension.NDJSON, FixtureExtension.CSV]
169
+ )
167
170
 
168
171
  if should_process_path(event.src_path):
169
172
  return event.src_path
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev123
3
+ Version: 0.0.1.dev125
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird