relationalai 0.13.1__py3-none-any.whl → 0.13.2__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.
@@ -1,6 +1,7 @@
1
1
  #pyright: reportPrivateImportUsage=false
2
2
  from __future__ import annotations
3
3
  import io
4
+ import json
4
5
  import os
5
6
  import re
6
7
  import sys
@@ -9,10 +10,12 @@ import rich
9
10
  import click
10
11
  import functools
11
12
  import pytz
13
+ from typing import NoReturn
12
14
 
13
15
  from relationalai.util.constants import TOP_LEVEL_PROFILE_NAME
16
+ from relationalai.errors import RAIException
14
17
  from rich.table import Table
15
- from typing import Callable, Dict, Any
18
+ from typing import Callable, Dict, Any, List, cast
16
19
  from ..clients import config
17
20
  from click.core import Context
18
21
  from rich.console import Console
@@ -23,9 +26,10 @@ from ..clients.config import ConfigFile
23
26
  from datetime import datetime, timedelta
24
27
  from click.formatting import HelpFormatter
25
28
  from ..clients.client import ResourcesBase
26
- from relationalai.tools.constants import GlobalProfile
29
+ from relationalai.tools.constants import GlobalProfile, SHOW_FULL_TRACES
27
30
  from relationalai.tools.cli_controls import divider
28
31
  from relationalai.util.format import humanized_bytes, humanized_duration
32
+ from InquirerPy.base.control import Choice
29
33
 
30
34
  #--------------------------------------------------
31
35
  # Helpers
@@ -152,6 +156,291 @@ def validate_engine_name(name:str) -> tuple[bool, str|None]:
152
156
  return False, ENGINE_NAME_ERROR
153
157
  return True, None
154
158
 
159
+ #--------------------------------------------------
160
+ # Engine types & selection helpers (Snowflake)
161
+ #--------------------------------------------------
162
+
163
+ def format_state_with_color(state: str) -> str:
164
+ """Format engine state with colors for display."""
165
+ if not state:
166
+ return ""
167
+ state_upper = state.upper()
168
+ if state_upper == "READY":
169
+ return f"[green]{state_upper}[/green]"
170
+ if state_upper == "SUSPENDED":
171
+ return f"[yellow]{state_upper}[/yellow]"
172
+ if state_upper in ("PENDING", "SYNCING", "PROCESSING"):
173
+ return f"[bold yellow]{state_upper}[/bold yellow]"
174
+ if state_upper in ("ABORTED", "QUARANTINED", "GONE"):
175
+ return f"[red]{state_upper}[/red]"
176
+ return state_upper
177
+
178
+ def _get_engine_type_api():
179
+ # Local import to avoid importing snowflake modules for non-snowflake usage
180
+ from relationalai.clients.resources.snowflake import EngineType
181
+ return EngineType
182
+
183
+ def _get_internal_engine_sizes() -> list[str]:
184
+ # Local import to avoid snowflake imports for non-snowflake usage
185
+ from relationalai.clients.resources.snowflake import INTERNAL_ENGINE_SIZES
186
+ return list(INTERNAL_ENGINE_SIZES)
187
+
188
+ def get_engine_type_choices(cfg: config.Config, exclude_types: List[str] | None = None) -> List[Choice]:
189
+ """Get sorted list of engine type choices for interactive selection."""
190
+ EngineType = _get_engine_type_api()
191
+ if exclude_types is None:
192
+ exclude_types = []
193
+ exclude_types_upper = [et.upper() for et in exclude_types]
194
+ engine_types_list = [EngineType.LOGIC, EngineType.ML, EngineType.SOLVER]
195
+ engine_types_list = [et for et in engine_types_list if et.upper() not in exclude_types_upper]
196
+ engine_types_list.sort(key=lambda et: EngineType.get_label(et))
197
+ return [
198
+ Choice(value=et, name=f"{EngineType.get_label(et)}: {EngineType.get_description(et)}")
199
+ for et in engine_types_list
200
+ ]
201
+
202
+ def select_engine_type_interactive(cfg: config.Config) -> str:
203
+ """Show interactive engine type selection and return the selected type."""
204
+ from . import cli_controls as controls
205
+ rich.print("")
206
+ engine_type_choices = get_engine_type_choices(cfg)
207
+ return controls.select("Engine type:", cast("list[str | Choice]", engine_type_choices), None, newline=True)
208
+
209
+ def select_engine_interactive(
210
+ provider: ResourcesBase,
211
+ prompt: str = "Select an engine:",
212
+ engine_name: str | None = None,
213
+ engines: List[Dict[str, Any]] | None = None,
214
+ ) -> tuple[str, str | None] | None:
215
+ """Interactive engine picker returning (name, type)."""
216
+ from . import cli_controls as controls
217
+
218
+ engine_map: Dict[str, tuple[str, str | None]] = {}
219
+
220
+ def get_engines():
221
+ engine_list = engines if engines is not None else provider.list_engines()
222
+ engine_map.clear()
223
+ items: List[str] = []
224
+ EngineType = _get_engine_type_api()
225
+ for engine in engine_list:
226
+ eng_name = engine.get("name", "")
227
+ if engine_name and eng_name.upper() != engine_name.upper():
228
+ continue
229
+ eng_type = engine.get("type", "")
230
+ eng_size = engine.get("size", "")
231
+ if eng_type:
232
+ label = f"{EngineType.get_label(eng_type)} ({eng_type})" if EngineType.is_valid(eng_type) else f"{eng_type} ({eng_type})"
233
+ display = f"{eng_name}, {label}, {eng_size}"
234
+ else:
235
+ display = f"{eng_name}, {eng_size}" if eng_size else eng_name
236
+ engine_map[display] = (eng_name, eng_type or None)
237
+ items.append(display)
238
+ return items
239
+
240
+ # Auto-select when engine_name uniquely identifies an engine
241
+ if engine_name:
242
+ engine_list = engines if engines is not None else provider.list_engines()
243
+ matches = [e for e in engine_list if e.get("name", "").upper() == engine_name.upper()]
244
+ if len(matches) == 1:
245
+ e = matches[0]
246
+ return (e.get("name", ""), e.get("type"))
247
+ if len(matches) == 0:
248
+ return None
249
+
250
+ selected = controls.fuzzy_with_refetch(prompt, "engines", get_engines)
251
+ if not selected or isinstance(selected, Exception):
252
+ return None
253
+ return engine_map.get(selected)
254
+
255
+ def select_engine_with_state_filter(
256
+ provider: ResourcesBase,
257
+ engine_name: str | None,
258
+ engine_type: str | None,
259
+ state_filter: str,
260
+ prompt_no_name: str,
261
+ prompt_with_name: str,
262
+ error_no_engines: str,
263
+ error_no_matching: str,
264
+ ) -> tuple[str, str | None] | None:
265
+ """Select an engine with optional state filtering + optional name filtering."""
266
+ EngineType = _get_engine_type_api()
267
+
268
+ if not engine_name:
269
+ filtered = provider.list_engines(state_filter)
270
+ if not filtered:
271
+ exit_with_error(error_no_engines)
272
+ return select_engine_interactive(provider, prompt_no_name, engines=filtered)
273
+
274
+ # If type provided and valid, return directly
275
+ if engine_type and EngineType.is_valid(engine_type):
276
+ return (engine_name, engine_type)
277
+
278
+ # Filter by name + state; selection handles (name,type)
279
+ filtered = provider.list_engines(state_filter, name=engine_name)
280
+ if not filtered:
281
+ exit_with_error(error_no_matching)
282
+ return select_engine_interactive(provider, prompt_with_name, engine_name=engine_name, engines=filtered)
283
+
284
+ def ensure_engine_type_for_snowflake(
285
+ provider: ResourcesBase,
286
+ engine_name: str,
287
+ engine_type: str | None,
288
+ error_message: str,
289
+ ) -> str:
290
+ """Ensure engine_type is provided and valid; default to LOGIC if omitted."""
291
+ EngineType = _get_engine_type_api()
292
+ # If --type was omitted, default to LOGIC for backwards compatibility
293
+ if engine_type is None:
294
+ return EngineType.LOGIC
295
+ assert isinstance(engine_type, str)
296
+ if engine_type == "" or not EngineType.is_valid(engine_type):
297
+ cfg = get_config()
298
+ if engine_type == "":
299
+ rich.print(f"[yellow]Empty engine type provided for engine '{engine_name}'.")
300
+ else:
301
+ rich.print(f"[yellow]Invalid engine type '{engine_type}' for engine '{engine_name}'.")
302
+ return select_engine_type_interactive(cfg)
303
+ return engine_type
304
+
305
+ def build_engine_operation_messages(
306
+ provider: ResourcesBase,
307
+ engine_name: str,
308
+ engine_type: str | None,
309
+ action: str,
310
+ action_past: str,
311
+ ) -> tuple[str, str]:
312
+ EngineType = _get_engine_type_api()
313
+ if engine_type:
314
+ label = EngineType.get_label(engine_type) if EngineType.is_valid(engine_type) else engine_type
315
+ return (f"{action} {label} engine '{engine_name}'", f"{label} Engine '{engine_name}' {action_past.lower()}")
316
+ return (f"{action} '{engine_name}' engine", f"Engine '{engine_name}' {action_past.lower()}")
317
+
318
+ def prompt_and_validate_engine_name(name: str | None) -> str:
319
+ """Prompt for engine name if missing; validate using ENGINE_NAME_REGEX."""
320
+ from . import cli_controls as controls
321
+ if not name:
322
+ name = controls.prompt(
323
+ "Engine name:",
324
+ name,
325
+ validator=ENGINE_NAME_REGEX.match,
326
+ invalid_message=ENGINE_NAME_ERROR,
327
+ newline=True,
328
+ )
329
+ assert isinstance(name, str)
330
+ return name
331
+
332
+ def validate_auto_suspend_mins(auto_suspend_mins: int | str | None) -> int | None:
333
+ if auto_suspend_mins is None:
334
+ return None
335
+ if isinstance(auto_suspend_mins, int):
336
+ return auto_suspend_mins
337
+ error_msg = f"[yellow]Error: auto_suspend_mins must be an integer instead of {type(auto_suspend_mins)}"
338
+ try:
339
+ return int(auto_suspend_mins)
340
+ except ValueError:
341
+ exit_with_error(error_msg)
342
+ return None
343
+
344
+ def get_engine_type_for_creation(provider: ResourcesBase, cfg: config.Config, engine_type: str | None) -> str | None:
345
+ """Get engine type for engine creation; defaults to LOGIC when omitted."""
346
+ EngineType = _get_engine_type_api()
347
+ if engine_type is None:
348
+ return EngineType.LOGIC
349
+ if engine_type == "" or not EngineType.is_valid(engine_type):
350
+ if engine_type == "":
351
+ rich.print("[yellow]Empty engine type provided.")
352
+ else:
353
+ valid_types_display = ", ".join(EngineType.get_all_types())
354
+ rich.print(f"[yellow]Invalid engine type '{engine_type}'. Valid types: {valid_types_display}")
355
+ return select_engine_type_interactive(cfg)
356
+ return engine_type
357
+
358
+ def get_and_validate_engine_size(
359
+ provider: ResourcesBase,
360
+ cfg: config.Config,
361
+ size: str | None,
362
+ engine_type: str | None = None,
363
+ ) -> str:
364
+ from . import cli_controls as controls
365
+ EngineType = _get_engine_type_api()
366
+ internal_sizes = set(_get_internal_engine_sizes())
367
+
368
+ cloud_provider = provider.get_cloud_provider()
369
+ valid_sizes = provider.get_engine_sizes(cloud_provider)
370
+
371
+ # Engine-type-aware filtering:
372
+ # Internal sizes (XS/S/M/L) are only valid for LOGIC engines (and only on some accounts).
373
+ # For ML/SOLVER, hide them to avoid presenting invalid options.
374
+ if engine_type and EngineType.is_valid(engine_type) and engine_type != EngineType.LOGIC:
375
+ valid_sizes = [s for s in valid_sizes if s not in internal_sizes]
376
+
377
+ # Ask if missing and not in config
378
+ if not size and not cfg.get("engine_size", None):
379
+ rich.print("")
380
+ # This refers to the cloud backing your Snowflake account (AWS/Azure), not the engine "platform".
381
+ size = controls.fuzzy(f"Engine size (Snowflake cloud: {cloud_provider.upper()}):", choices=valid_sizes)
382
+ elif size is None and cfg.get("engine_size", None):
383
+ size = cfg.get("engine_size", None)
384
+ if not isinstance(size, str) or size not in valid_sizes:
385
+ exit_with_error(f"\nInvalid engine size [yellow]{size}[/yellow] provided. Please check your config.\n\nValid sizes: [green]{valid_sizes}[/green]")
386
+ return size
387
+
388
+ def create_engine_with_spinner(
389
+ provider: ResourcesBase,
390
+ engine_name: str,
391
+ engine_size: str,
392
+ engine_type: str | None,
393
+ auto_suspend_mins: int | None,
394
+ ) -> None:
395
+ """Create an engine with appropriate spinner messages and error handling."""
396
+ from .cli_controls import Spinner
397
+
398
+ EngineType = _get_engine_type_api()
399
+ # Build creation message with engine type when available
400
+ if engine_type:
401
+ creation_message = (
402
+ f"Creating {EngineType.get_label(engine_type)} engine '{engine_name}' with size {engine_size}... "
403
+ f"(this may take several minutes)"
404
+ )
405
+ else:
406
+ creation_message = (
407
+ f"Creating engine '{engine_name}' with size {engine_size}... "
408
+ f"(this may take several minutes)"
409
+ )
410
+
411
+ with Spinner(
412
+ creation_message,
413
+ f"Engine '{engine_name}' created!",
414
+ failed_message=None, # We handle error display ourselves below
415
+ ):
416
+ try:
417
+ provider.create_engine(
418
+ engine_name,
419
+ type=engine_type,
420
+ size=engine_size,
421
+ auto_suspend_mins=auto_suspend_mins,
422
+ )
423
+ except Exception as e:
424
+ # Prefer richer error messages when available
425
+ error_msg = None
426
+
427
+ # EngineProvisioningFailed has a format_message() method that provides better error details
428
+ if hasattr(e, "format_message"):
429
+ try:
430
+ error_msg = getattr(e, "format_message")()
431
+ except Exception:
432
+ pass
433
+
434
+ # Try content/message fallbacks
435
+ if not error_msg and hasattr(e, "content"):
436
+ error_msg = getattr(e, "content", None)
437
+ if not error_msg and hasattr(e, "message"):
438
+ error_msg = str(getattr(e, "message", ""))
439
+ if not error_msg:
440
+ error_msg = str(e)
441
+
442
+ raise Exception(error_msg)
443
+
155
444
  #--------------------------------------------------
156
445
  # Tables
157
446
  #--------------------------------------------------
@@ -190,7 +479,7 @@ def format_value(value) -> str:
190
479
  def format_row(key: str, value) -> dict:
191
480
  result = {}
192
481
  result[key] = value
193
- if "status" or "state" in key.lower():
482
+ if "status" in key.lower() or "state" in key.lower():
194
483
  result["style"] = get_color_by_state(value)
195
484
  if key == "query_size" and isinstance(value, int):
196
485
  result[key] = humanized_bytes(value)
@@ -216,6 +505,28 @@ def show_dictionary_table(dict, format_fn:Callable|None=None):
216
505
 
217
506
 
218
507
  class RichGroup(click.Group):
508
+ def invoke(self, ctx: Context) -> Any:
509
+ """Invoke the CLI command, suppressing tracebacks for handled RAIExceptions.
510
+
511
+ Any `RAIException` is expected to already know how to render itself nicely via
512
+ `pprint()`. When such an exception bubbles up to the top-level Click runner,
513
+ Click will otherwise print a full Python traceback, which is noisy for users.
514
+ """
515
+ try:
516
+ return super().invoke(ctx)
517
+ except RAIException as exc:
518
+ # Respect config-based full-trace setting when available.
519
+ try:
520
+ show_full_traces = get_config().get("show_full_traces", SHOW_FULL_TRACES)
521
+ except Exception:
522
+ show_full_traces = SHOW_FULL_TRACES
523
+
524
+ if show_full_traces:
525
+ raise
526
+
527
+ exc.pprint()
528
+ raise click.exceptions.Exit(1) from None
529
+
219
530
  def format_help(self, ctx: Context, formatter: HelpFormatter) -> None:
220
531
  is_latest, current_ver, latest_ver = is_latest_cli_version()
221
532
 
@@ -383,16 +694,109 @@ def show_engines(engines):
383
694
  table = Table(show_header=True, border_style="dim", header_style="bold", box=rich_box.SIMPLE_HEAD)
384
695
  table.add_column("#")
385
696
  table.add_column("Name")
697
+ # Show type column if present
698
+ table.add_column("Type")
386
699
  table.add_column("Size")
387
700
  table.add_column("State")
701
+ table.add_column("Created By")
702
+ table.add_column("Created On")
703
+ EngineType = _get_engine_type_api()
388
704
  for index, engine in enumerate(engines):
389
- table.add_row(f"{index+1}", engine.get("name"), engine.get("size"), engine.get("state"))
705
+ engine_type = engine.get("type", "")
706
+ type_display = EngineType.get_label_with_value(engine_type) if engine_type and EngineType.is_valid(engine_type) else (engine_type or "")
707
+ created_on = format_value(engine.get("created_on"))
708
+ state_display = format_state_with_color(engine.get("state", ""))
709
+ table.add_row(
710
+ f"{index+1}",
711
+ engine.get("name"),
712
+ type_display,
713
+ engine.get("size"),
714
+ state_display,
715
+ engine.get("created_by", ""),
716
+ created_on,
717
+ )
390
718
  rich.print(table)
391
719
 
392
- def exit_with_error(message:str):
720
+
721
+ def show_engine_details(engine: dict[str, Any]) -> None:
722
+ """Print a vertical table of engine details (one field per row)."""
723
+ from relationalai.clients.resources.snowflake import EngineType as _EngineType
724
+
725
+ table = Table(
726
+ show_header=True,
727
+ border_style="dim",
728
+ header_style="bold",
729
+ box=rich_box.SIMPLE_HEAD,
730
+ )
731
+ table.add_column("Field")
732
+ table.add_column("Value", overflow="fold")
733
+
734
+ engine_type_from_db = engine.get("type", "")
735
+ type_display = (
736
+ _EngineType.get_label_with_value(engine_type_from_db)
737
+ if engine_type_from_db and _EngineType.is_valid(engine_type_from_db)
738
+ else engine_type_from_db
739
+ )
740
+
741
+ rows: list[tuple[str, str]] = [
742
+ ("Name", str(engine.get("name", ""))),
743
+ ("Type", str(type_display)),
744
+ ("Size", str(engine.get("size", ""))),
745
+ ("State", str(format_state_with_color(engine.get("state", "")))),
746
+ ("Created By", str(engine.get("created_by", ""))),
747
+ ("Created On", str(format_value(engine.get("created_on")))),
748
+ ]
749
+
750
+ # Optional fields (may not exist on older backends).
751
+ for key, label, formatter in [
752
+ ("version", "Version", lambda v: "" if v is None else str(v)),
753
+ ("updated_on", "Updated On", format_value),
754
+ ("suspends_at", "Suspends At", format_value),
755
+ ]:
756
+ if key in engine:
757
+ try:
758
+ val = engine.get(key)
759
+ rows.append((label, str(formatter(val))))
760
+ except Exception:
761
+ rows.append((label, str(engine.get(key))))
762
+
763
+ # Auto-suspend minutes is represented differently across backends:
764
+ # - list_engines tends to return auto_suspend_mins
765
+ # - get_engine (Snowflake EngineServiceSQL) returns auto_suspend
766
+ if "auto_suspend_mins" in engine or "auto_suspend" in engine:
767
+ auto_suspend_val = engine.get("auto_suspend_mins", engine.get("auto_suspend"))
768
+ rows.append(("Auto Suspend (mins)", "" if auto_suspend_val is None else str(auto_suspend_val)))
769
+
770
+ settings = engine.get("settings")
771
+ if settings in (None, {}, ""):
772
+ settings_str = ""
773
+ elif isinstance(settings, dict):
774
+ settings_str = json.dumps(settings, indent=2, sort_keys=True)
775
+ else:
776
+ settings_str = str(settings)
777
+ rows.append(("Settings", settings_str))
778
+
779
+ for field, value in rows:
780
+ table.add_row(field, value)
781
+
782
+ rich.print(table)
783
+
784
+ def exit_with_error(message: str) -> NoReturn:
393
785
  rich.print(message, file=sys.stderr)
394
786
  exit_with_divider(1)
395
787
 
396
- def exit_with_divider(exit_code:int=0):
788
+ def exit_with_handled_exception(context: str, exc: Exception) -> NoReturn:
789
+ """Exit with a nicely formatted message for handled RAIExceptions.
790
+
791
+ - If `exc` is a RAIException (i.e. produced by an error handler), print its rich
792
+ formatted content via `exc.pprint()`.
793
+ - Otherwise, print a raw one-line error including the context and exception string.
794
+ """
795
+ if isinstance(exc, RAIException):
796
+ exc.pprint()
797
+ sys.exit(1)
798
+ exit_with_error(f"\n\n[yellow]{context}: {exc}")
799
+
800
+ def exit_with_divider(exit_code: int = 0) -> NoReturn:
397
801
  divider()
398
802
  sys.exit(exit_code)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: relationalai
3
- Version: 0.13.1
3
+ Version: 0.13.2
4
4
  Summary: RelationalAI Library and CLI
5
5
  Author-email: RelationalAI <support@relational.ai>
6
6
  License-File: LICENSE
@@ -4,7 +4,7 @@ relationalai/debugging.py,sha256=wqGly2Yji4ErdV9F_S1Bny35SiGqI3C7S-hap7B8yUs,119
4
4
  relationalai/dependencies.py,sha256=tL113efcISkJUiDXYHmRdU_usdD7gmee-VRHA7N4EFA,16574
5
5
  relationalai/docutils.py,sha256=1gVv9mk0ytdMB2W7_NvslJefmSQtTOg8LHTCDcGCjyE,1554
6
6
  relationalai/dsl.py,sha256=UJr93X8kwnnyUY-kjPzp_jhsp2pYBUnDfu8mhNXPNII,66116
7
- relationalai/errors.py,sha256=PaWzKsfWwjca7J0huILkiR515_PwJXP1Hlq6owOjL0Y,96828
7
+ relationalai/errors.py,sha256=LNMUXoe7e19c4azqx3WDYpQs-59IEwCH_i3iXxGptE8,96830
8
8
  relationalai/metagen.py,sha256=o10PNvR_myr_61DC8g6lkB093bFo9qXGUkZKgKyfXiE,26821
9
9
  relationalai/metamodel.py,sha256=P1hliwHd1nYxbXON4LZeaYZD6T6pZm97HgmFBFrWyCk,32886
10
10
  relationalai/rel.py,sha256=ePmAXx4NxOdsPcHNHyGH3Jkp_cB3QzfKu5p_EQSHPh0,38293
@@ -19,27 +19,28 @@ relationalai/auth/oauth_callback_server.py,sha256=vbcpz77n_WKMDZ4sac6IYyrpxScR0D
19
19
  relationalai/auth/token_handler.py,sha256=d5aueGEiK6BmzkxSab3reCdkhtjdphb0CeecyvvNaQU,19443
20
20
  relationalai/auth/util.py,sha256=oXOUwW5gaBhEV5v5A-q2ME1VnfjfRWswvRlXW4oBYpk,1116
21
21
  relationalai/clients/__init__.py,sha256=LQ_yHsutRMpoW2mOTmOPGF8mrbP0OiV5E68t8uVwDyQ,833
22
- relationalai/clients/client.py,sha256=gk_V9KS7_MM2dLL2OCO7EPLHD9dsRwR6R-30SW8lDwU,35759
22
+ relationalai/clients/client.py,sha256=3yK1mCXYSECAS7vBa9uovTeRbfOvnBAJ9USWzhtr_bk,36715
23
23
  relationalai/clients/config.py,sha256=hERaKjc3l4kd-kf0l-NUOHrWunCn8gmFWpuE0j3ScJg,24457
24
24
  relationalai/clients/direct_access_client.py,sha256=VGjQ7wzduxCo04BkxSZjlPAgqK-aBc32zIXcMfAzzSU,6436
25
25
  relationalai/clients/exec_txn_poller.py,sha256=JbmrTvsWGwxM5fcZVjeJihQDqhMf-ySfHN3Jn0HGwG0,3108
26
26
  relationalai/clients/hash_util.py,sha256=pZVR1FX3q4G_19p_r6wpIR2tIM8_WUlfAR7AVZJjIYM,1495
27
- relationalai/clients/local.py,sha256=vo5ikSWg38l3xQAh9yL--4sMAj_T5Tn7YEZiw7TCH08,23504
27
+ relationalai/clients/local.py,sha256=X_v4h8HNyZEYeyQuoDBfavLuedjCVKg5GvnEtOUn5WM,23952
28
28
  relationalai/clients/profile_polling.py,sha256=pUH7WKH4nYDD0SlQtg3wsWdj0K7qt6nZqUw8jTthCBs,2565
29
29
  relationalai/clients/result_helpers.py,sha256=wDSD02Ngx6W-YQqBIGKnpXD4Ju3pA1e9Nz6ORRI6SRI,17808
30
- relationalai/clients/types.py,sha256=eNo6akcMTbnBFbBbHd5IgVeY-zuAgtXlOs8Bo1SWmVU,2890
30
+ relationalai/clients/types.py,sha256=xHkmrbqOfxxhBrTiQDUQqN0Lqnsv8pkAzstffYNdqqg,3038
31
31
  relationalai/clients/util.py,sha256=NJC8fnrWHR01NydwESPSetIHRWf7jQJURYpaWJjmDyE,12311
32
32
  relationalai/clients/resources/__init__.py,sha256=pymn8gB86Q3C2bVoFei0KAL8pX_U04uDY9TE4TKzTBs,260
33
- relationalai/clients/resources/azure/azure.py,sha256=TDapfM5rLoHrPrXg5cUe827m3AO0gSqQjNid1VUlUFo,20631
34
- relationalai/clients/resources/snowflake/__init__.py,sha256=Ofyf1RZu9GLQdvsjpHDUHEQHHVODb9vKYI4hMOxczH4,923
33
+ relationalai/clients/resources/azure/azure.py,sha256=3RQucsot4M8sU4yqeCi5IIeC4BgVFMQm1q9uhWY54W0,21676
34
+ relationalai/clients/resources/snowflake/__init__.py,sha256=kHjuNWr37viTd-n8tNMVo0FGhlKlrStb8_V9yJx_CNw,975
35
35
  relationalai/clients/resources/snowflake/cache_store.py,sha256=A-qd11wcwN3TkIqvlN0_iFUU3aEjJal3T2pqFBwkkzQ,3966
36
- relationalai/clients/resources/snowflake/cli_resources.py,sha256=xTIcCzvgbkxuNAEvzZoRpj0n-js0hZCK30q7IZXztbI,3252
37
- relationalai/clients/resources/snowflake/direct_access_resources.py,sha256=5LZIQCSiX_TT2tVHqbTBzJTBXZzHmQI7cxFOY6CDDBM,28871
38
- relationalai/clients/resources/snowflake/engine_state_handlers.py,sha256=SQBu4GfbyABU6xrEV-koivC-ubsVrfCBTF0FEQgJM5g,12054
39
- relationalai/clients/resources/snowflake/error_handlers.py,sha256=581G2xOihUoiPlucC_Z2FOzhKu_swdIc3uORd0yJQuA,8805
36
+ relationalai/clients/resources/snowflake/cli_resources.py,sha256=DjvGyxYLwfCA57FgxpmyBfAyyHIHsbpa-UsoYziEowk,3689
37
+ relationalai/clients/resources/snowflake/direct_access_resources.py,sha256=HF9rowNOBrjimtBGJlDSRsS0jGEHu9FdQhRxImdCM0M,30624
38
+ relationalai/clients/resources/snowflake/engine_service.py,sha256=CYW0RoQjIlEr2w1FeUXwl2gj5o0HoNg9qLmiLo_7rQY,13492
39
+ relationalai/clients/resources/snowflake/engine_state_handlers.py,sha256=gHdqotbNkfAsXQq9XR7aRcsW4QBk7sKAxdra9YS5bsM,12079
40
+ relationalai/clients/resources/snowflake/error_handlers.py,sha256=R5f-3WhOBOFN373BjhkCNLBKVWBIMNPEm2VbAvyvELo,10733
40
41
  relationalai/clients/resources/snowflake/export_procedure.py.jinja,sha256=00iLO2qmvJoqAeJUWt3bAsFDDnof7Ab2spggzelbwK4,10566
41
42
  relationalai/clients/resources/snowflake/resources_factory.py,sha256=4LGd4IQ6z8hGeGlO1TIjSFJEeUNHutaB7j9q1a9rYfQ,3385
42
- relationalai/clients/resources/snowflake/snowflake.py,sha256=SuFwAdhaFrd3JZFEjVJMVVFuLrC_T3dqXS27ABrXZAw,136973
43
+ relationalai/clients/resources/snowflake/snowflake.py,sha256=wlGd0AA2fWo2ew681l3Q-N7It0PmcAmiJ4SekzOLcf4,135366
43
44
  relationalai/clients/resources/snowflake/use_index_poller.py,sha256=xF_9XAymO82YZcZOQqz0r9oZZTqvbWW-WjDTZm4-tFM,48859
44
45
  relationalai/clients/resources/snowflake/use_index_resources.py,sha256=69PNWHI_uf-Aw_evfwC6j8HLVdjhp84vs8hLkjnhwbg,6462
45
46
  relationalai/clients/resources/snowflake/util.py,sha256=BEnm1B1-nqqHdm41RNxblbb-zqXbtqEGGZmTdAYeN_M,13841
@@ -360,7 +361,7 @@ relationalai/semantics/metamodel/rewrite/flatten.py,sha256=oyCYyJrq84YpNC6UpLDfS
360
361
  relationalai/semantics/metamodel/rewrite/format_outputs.py,sha256=n0IxC3RL3UMly6MWsq342EGfL2yGj3vOgVG_wg7kt-o,6225
361
362
  relationalai/semantics/metamodel/typer/__init__.py,sha256=E3ydmhWRdm-cAqWsNR24_Qd3NcwiHx8ElO2tzNysAXc,143
362
363
  relationalai/semantics/metamodel/typer/checker.py,sha256=frY0gilDO6skbDiYFiIpDUOWyt9s9jAJsRBs848DcG0,19184
363
- relationalai/semantics/metamodel/typer/typer.py,sha256=6yyLfGXPuh71TbAvK4I9AkMI4Ap5LlHhhMuDYWzj6Dw,62774
364
+ relationalai/semantics/metamodel/typer/typer.py,sha256=cgb8ckAIQSIzkS2VLvj9tl2UdGALKZXrsn_io35ojNk,62906
364
365
  relationalai/semantics/reasoners/__init__.py,sha256=cLrGNKFX859EdPjk2n6MdYLvueaFtTEnfVYnBriQMfI,303
365
366
  relationalai/semantics/reasoners/experimental/__init__.py,sha256=ZWXb3Oun7m_G2c3ijKnqxbEsAzTMVa7ciBXjdi4dCNI,144
366
367
  relationalai/semantics/reasoners/graph/README.md,sha256=QgKEXTllp5PO-yK8oDfMx1PNTYF2uVoneMRKsWTY5GU,23953
@@ -417,9 +418,9 @@ relationalai/std/re.py,sha256=7B0dPaYyEdIlEgZfDzs7HJ_MTqccYTfIZieqst6MHbk,4457
417
418
  relationalai/std/strings.py,sha256=vHvex_W5GHhhsVws6Dfyl4w1EHdbDE3nPjT09DnpvSE,4260
418
419
  relationalai/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
419
420
  relationalai/tools/cleanup_snapshots.py,sha256=s1q1ophi1RmiTZ9QQolQ6q1K9ZwseCaOuDtI1Rm99MQ,3434
420
- relationalai/tools/cli.py,sha256=z6FpwRe3pVro78QDlTkfq6D-Tpb7KpgyscGpVKhJGVM,76841
421
+ relationalai/tools/cli.py,sha256=KM-_4KCNkW6loi3LjfLNRcApKTcusd_8gFS8166ZEAs,84147
421
422
  relationalai/tools/cli_controls.py,sha256=84K0sjfsVwqi9C8ZlpvPi6XZPhjyW-R06Pir9Ex_Xtg,70468
422
- relationalai/tools/cli_helpers.py,sha256=dUIx9Z1I1rTZ3VKtn4jlKGCY5TNk1rl1CY8g3-m99A0,14431
423
+ relationalai/tools/cli_helpers.py,sha256=z7D4-9hX8DMm_WrG_5JYpsRhe9WzznsbKh2kN4OvGuw,30846
423
424
  relationalai/tools/constants.py,sha256=A8Qz0CPs2cRUs5xaZ-Y7BCyvqmI6RLvipzwLDYZ3_PU,4505
424
425
  relationalai/tools/debugger.py,sha256=iWO1tMJud3dXHIkrjdZ5Temp0MR2AwN5_QGDt-ddmcs,6934
425
426
  relationalai/tools/debugger_client.py,sha256=g9vBaeJLKVq6vW63W-KKSaPJ--g5Wuf4LcIuYRA_pk4,3729
@@ -444,7 +445,7 @@ relationalai/util/spans_file_handler.py,sha256=a0sDwDPBBvGsM6be2En3mId9sXpuJlXia
444
445
  relationalai/util/timeout.py,sha256=2o6BVNFnFc-B2j-i1pEkZcQbMRto9ps2emci0XwiA4I,783
445
446
  relationalai/util/tracing_handler.py,sha256=H919ETAxh7Z1tRz9x8m90qP51_264UunHAPw8Sr6x2g,1729
446
447
  relationalai_test_util/__init__.py,sha256=Io_9_IQXXnrUlaL7S1Ndv-4YHilNxy36LrL723MI7lw,118
447
- relationalai_test_util/fixtures.py,sha256=WhpPto6LtZTGWQhYV9Tmz9yJGoVAkYlGRrgM_7errm4,9455
448
+ relationalai_test_util/fixtures.py,sha256=1fCU-45pUMuWstkOfQ1u_37lJnPPqC43ks2nYW-UA7A,9478
448
449
  relationalai_test_util/snapshot.py,sha256=FeH2qYBzLxr2-9qs0yElPIgWUjm_SrzawB3Jgn-aSuE,9291
449
450
  relationalai_test_util/traceback.py,sha256=lD0qaEmCyO-7xg9CNf6IzwS-Q-sTS8N9YIv8RroAE50,3298
450
451
  frontend/debugger/dist/.gitignore,sha256=JAo-DTfS6GthQGP1NH6wLU-ZymwlTea4KHH_jZVTKn0,14
@@ -452,8 +453,8 @@ frontend/debugger/dist/index.html,sha256=0wIQ1Pm7BclVV1wna6Mj8OmgU73B9rSEGPVX-Wo
452
453
  frontend/debugger/dist/assets/favicon-Dy0ZgA6N.png,sha256=tPXOEhOrM4tJyZVJQVBO_yFgNAlgooY38ZsjyrFstgg,620
453
454
  frontend/debugger/dist/assets/index-Cssla-O7.js,sha256=MxgIGfdKQyBWgufck1xYggQNhW5nj6BPjCF6Wleo-f0,298886
454
455
  frontend/debugger/dist/assets/index-DlHsYx1V.css,sha256=21pZtAjKCcHLFjbjfBQTF6y7QmOic-4FYaKNmwdNZVE,60141
455
- relationalai-0.13.1.dist-info/METADATA,sha256=zO4iuv-8tLuz3rByVdd1X3MSdh5MU6XZzqzXcAvdf4k,2561
456
- relationalai-0.13.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
457
- relationalai-0.13.1.dist-info/entry_points.txt,sha256=fo_oLFJih3PUgYuHXsk7RnCjBm9cqRNR--ab6DgI6-0,88
458
- relationalai-0.13.1.dist-info/licenses/LICENSE,sha256=pPyTVXFYhirkEW9VsnHIgUjT0Vg8_xsE6olrF5SIgpc,11343
459
- relationalai-0.13.1.dist-info/RECORD,,
456
+ relationalai-0.13.2.dist-info/METADATA,sha256=C_6NBEgmM09pft0zVQWwdSXVuUDJG6IGrY_C0WKuVCE,2561
457
+ relationalai-0.13.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
458
+ relationalai-0.13.2.dist-info/entry_points.txt,sha256=fo_oLFJih3PUgYuHXsk7RnCjBm9cqRNR--ab6DgI6-0,88
459
+ relationalai-0.13.2.dist-info/licenses/LICENSE,sha256=pPyTVXFYhirkEW9VsnHIgUjT0Vg8_xsE6olrF5SIgpc,11343
460
+ relationalai-0.13.2.dist-info/RECORD,,
@@ -78,14 +78,14 @@ def create_engine(engine_name: str, size: str, use_direct_access=False):
78
78
 
79
79
  provider = rai.Resources(config=config)
80
80
  print(f"Creating engine {engine_name}")
81
- provider.create_engine(name=engine_name, size=size)
81
+ provider.create_engine(name=engine_name, type="LOGIC", size=size)
82
82
  print(f"Engine {engine_name} created")
83
83
 
84
84
  def delete_engine(engine_name: str, use_direct_access=False):
85
85
  print(f"Deleting engine {engine_name}")
86
86
  config = make_config(engine_name, use_direct_access=use_direct_access)
87
87
  provider = rai.Resources(config=config)
88
- provider.delete_engine(engine_name)
88
+ provider.delete_engine(engine_name, "LOGIC")
89
89
  print(f"Engine {engine_name} deleted")
90
90
 
91
91
  def make_config(engine_name: str | None = None, fetch_profile: bool = True, use_package_manager = USE_PACKAGE_MANAGER, use_direct_access = False, show_full_traces = True, show_debug_logs = True, reuse_model = False) -> cfg.Config: