relationalai 1.0.0a2__py3-none-any.whl → 1.0.0a3__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.
Files changed (39) hide show
  1. relationalai/shims/executor.py +4 -1
  2. relationalai/shims/mm2v0.py +15 -10
  3. {relationalai-1.0.0a2.dist-info → relationalai-1.0.0a3.dist-info}/METADATA +1 -1
  4. {relationalai-1.0.0a2.dist-info → relationalai-1.0.0a3.dist-info}/RECORD +39 -30
  5. v0/relationalai/__init__.py +69 -22
  6. v0/relationalai/clients/__init__.py +15 -2
  7. v0/relationalai/clients/client.py +4 -4
  8. v0/relationalai/clients/local.py +5 -5
  9. v0/relationalai/clients/resources/__init__.py +8 -0
  10. v0/relationalai/clients/{azure.py → resources/azure/azure.py} +12 -12
  11. v0/relationalai/clients/resources/snowflake/__init__.py +20 -0
  12. v0/relationalai/clients/resources/snowflake/cli_resources.py +87 -0
  13. v0/relationalai/clients/resources/snowflake/direct_access_resources.py +711 -0
  14. v0/relationalai/clients/resources/snowflake/engine_state_handlers.py +309 -0
  15. v0/relationalai/clients/resources/snowflake/error_handlers.py +199 -0
  16. v0/relationalai/clients/resources/snowflake/resources_factory.py +99 -0
  17. v0/relationalai/clients/{snowflake.py → resources/snowflake/snowflake.py} +606 -1392
  18. v0/relationalai/clients/{use_index_poller.py → resources/snowflake/use_index_poller.py} +43 -12
  19. v0/relationalai/clients/resources/snowflake/use_index_resources.py +188 -0
  20. v0/relationalai/clients/resources/snowflake/util.py +387 -0
  21. v0/relationalai/early_access/dsl/ir/executor.py +4 -4
  22. v0/relationalai/early_access/dsl/snow/api.py +2 -1
  23. v0/relationalai/experimental/solvers.py +7 -7
  24. v0/relationalai/semantics/devtools/benchmark_lqp.py +4 -5
  25. v0/relationalai/semantics/devtools/extract_lqp.py +1 -1
  26. v0/relationalai/semantics/internal/snowflake.py +1 -1
  27. v0/relationalai/semantics/lqp/executor.py +4 -11
  28. v0/relationalai/semantics/metamodel/util.py +6 -5
  29. v0/relationalai/semantics/rel/executor.py +14 -11
  30. v0/relationalai/semantics/sql/executor/snowflake.py +9 -5
  31. v0/relationalai/semantics/tests/test_snapshot_abstract.py +1 -1
  32. v0/relationalai/tools/cli.py +26 -30
  33. v0/relationalai/tools/cli_helpers.py +10 -2
  34. v0/relationalai/util/otel_configuration.py +2 -1
  35. v0/relationalai/util/otel_handler.py +1 -1
  36. {relationalai-1.0.0a2.dist-info → relationalai-1.0.0a3.dist-info}/WHEEL +0 -0
  37. {relationalai-1.0.0a2.dist-info → relationalai-1.0.0a3.dist-info}/entry_points.txt +0 -0
  38. {relationalai-1.0.0a2.dist-info → relationalai-1.0.0a3.dist-info}/top_level.txt +0 -0
  39. /v0/relationalai/clients/{cache_store.py → resources/snowflake/cache_store.py} +0 -0
@@ -17,6 +17,7 @@ from v0.relationalai.semantics.sql.executor.result_helpers import format_columns
17
17
  from v0.relationalai.semantics.metamodel.visitor import collect_by_type
18
18
  from v0.relationalai.semantics.metamodel.typer import typer
19
19
  from v0.relationalai.tools.constants import USE_DIRECT_ACCESS
20
+ from v0.relationalai.clients.resources.snowflake import Resources, DirectAccessResources, Provider
20
21
 
21
22
  if TYPE_CHECKING:
22
23
  from v0.relationalai.semantics.snowflake import Table
@@ -51,17 +52,20 @@ class SnowflakeExecutor(e.Executor):
51
52
  if not self._resources:
52
53
  with debugging.span("create_session"):
53
54
  self.dry_run |= bool(self.config.get("compiler.dry_run", False))
54
- resource_class = rai.clients.snowflake.Resources
55
+ resource_class: type = Resources
55
56
  if self.config.get("use_direct_access", USE_DIRECT_ACCESS):
56
- resource_class = rai.clients.snowflake.DirectAccessResources
57
- self._resources = resource_class(dry_run=self.dry_run, config=self.config, generation=rai.Generation.QB,
58
- connection=self.connection)
57
+ resource_class = DirectAccessResources
58
+ self._resources = resource_class(
59
+ dry_run=self.dry_run, config=self.config, generation=rai.Generation.QB,
60
+ connection=self.connection,
61
+ language="sql",
62
+ )
59
63
  return self._resources
60
64
 
61
65
  @property
62
66
  def provider(self):
63
67
  if not self._provider:
64
- self._provider = rai.clients.snowflake.Provider(resources=self.resources)
68
+ self._provider = Provider(resources=self.resources)
65
69
  return self._provider
66
70
 
67
71
  def execute(self, model: ir.Model, task: ir.Task, format:Literal["pandas", "snowpark"]="pandas",
@@ -10,7 +10,7 @@ from v0.relationalai.semantics.tests.utils import reset_state
10
10
  from v0.relationalai.semantics.internal import internal
11
11
  from v0.relationalai.clients.result_helpers import sort_data_frame_result
12
12
  from v0.relationalai.clients.util import IdentityParser
13
- from v0.relationalai.clients.snowflake import Provider as SFProvider
13
+ from v0.relationalai.clients.resources.snowflake import Provider as SFProvider
14
14
  from v0.relationalai import Provider
15
15
  from typing import cast, Dict, Union
16
16
  from pathlib import Path
@@ -27,7 +27,9 @@ from v0.relationalai.loaders.loader import Loader, rel_schema_to_type
27
27
  from ..clients.types import ImportSource, ImportSourceFile, ImportSourceTable
28
28
  from ..clients.client import ResourcesBase
29
29
  from ..tools import debugger as deb, qb_debugger as qb_deb
30
- from ..clients import config, snowflake
30
+ from ..clients import config
31
+ from v0.relationalai.tools.constants import RAI_APP_NAME
32
+ from v0.relationalai.clients.resources.snowflake.cli_resources import CLIResources
31
33
  from v0.relationalai.tools.cli_helpers import (
32
34
  EMPTY_STRING_REGEX,
33
35
  ENGINE_NAME_ERROR,
@@ -337,7 +339,7 @@ def check_snowflake_connections_flow(cfg:config.Config):
337
339
  return True
338
340
 
339
341
  def role_flow(provider:ResourcesBase, cfg:config.Config):
340
- roles = cast(snowflake.Resources, provider).list_roles()
342
+ roles = cast(CLIResources, provider).list_roles()
341
343
  result = controls.fuzzy_with_refetch(
342
344
  "Select a role:",
343
345
  "roles",
@@ -355,7 +357,7 @@ def warehouse_flow(provider:ResourcesBase, cfg:config.Config):
355
357
  result = controls.fuzzy_with_refetch(
356
358
  "Select a warehouse:",
357
359
  "warehouses",
358
- lambda: [w["name"] for w in cast(snowflake.Resources, provider).list_warehouses()],
360
+ lambda: [w["name"] for w in cast(CLIResources, provider).list_warehouses()],
359
361
  default=cfg.get("warehouse", None),
360
362
  )
361
363
  if not result or isinstance(result, Exception):
@@ -367,12 +369,12 @@ def warehouse_flow(provider:ResourcesBase, cfg:config.Config):
367
369
  def rai_app_flow(provider:ResourcesBase, cfg:config.Config):
368
370
  auto_select = None
369
371
  if provider.config.get("platform") == "snowflake":
370
- auto_select=snowflake.RAI_APP_NAME
372
+ auto_select=RAI_APP_NAME
371
373
 
372
374
  result = controls.fuzzy_with_refetch(
373
375
  "Select RelationalAI app name:",
374
376
  "apps",
375
- lambda: [w["name"] for w in cast(snowflake.Resources, provider).list_apps()],
377
+ lambda: [w["name"] for w in cast(CLIResources, provider).list_apps()],
376
378
  default=cfg.get("rai_app_name", None),
377
379
  auto_select=auto_select
378
380
  )
@@ -454,7 +456,8 @@ def name_profile_flow(cfg: config.Config):
454
456
  )
455
457
  return name_profile_flow(cfg)
456
458
  config_store = ConfigStore()
457
- if profile in config_store.get_profiles():
459
+ profiles = config_store.get_profiles() or {}
460
+ if profile in profiles:
458
461
  overwrite = controls.confirm(f"[yellow]Overwrite existing {profile} profile?")
459
462
  if overwrite:
460
463
  return profile
@@ -464,7 +467,8 @@ def name_profile_flow(cfg: config.Config):
464
467
 
465
468
  def save_flow(cfg:config.Config):
466
469
  config_store = ConfigStore()
467
- if cfg.profile != PARTIAL_PROFILE_NAME and cfg.profile in config_store.get_profiles():
470
+ profiles = config_store.get_profiles() or {}
471
+ if cfg.profile != PARTIAL_PROFILE_NAME and cfg.profile in profiles:
468
472
  if not controls.confirm(f"Overwrite existing {cfg.profile} profile"):
469
473
  rich.print()
470
474
  profile_name = controls.text("Profile name:")
@@ -570,7 +574,7 @@ def profile_switch(profile:str|None=None):
570
574
  rich.print(f"\n[yellow]Error: {e}")
571
575
  pass
572
576
 
573
- profiles = list(config_store.get_profiles().keys())
577
+ profiles = list((config_store.get_profiles() or {}).keys())
574
578
  divider()
575
579
  if not profile:
576
580
  if len(profiles) == 0:
@@ -672,7 +676,8 @@ def config_explain(profile:str|None=None, all_profiles:bool=False):
672
676
  ))
673
677
 
674
678
  if all_profiles:
675
- for profile, props in config_store.get_profiles().items():
679
+ profiles = config_store.get_profiles() or {}
680
+ for profile, props in profiles.items():
676
681
  if profile == cfg.profile:
677
682
  continue
678
683
  if len(props):
@@ -872,7 +877,6 @@ def engines_get(name:str|None=None):
872
877
  def create_engine_flow(cfg:config.Config, name=None, size=None, auto_suspend_mins=None):
873
878
  provider = get_resource_provider(None, cfg)
874
879
  engine = None
875
- create_exception = None
876
880
  is_engine_present = False
877
881
  is_engine_suspended = False
878
882
  is_interactive = name is None or size is None
@@ -957,15 +961,7 @@ def create_engine_flow(cfg:config.Config, name=None, size=None, auto_suspend_min
957
961
  f"Engine '{name}' created!",
958
962
  failed_message="Error:"
959
963
  ):
960
- try:
961
- provider.create_engine(name, size, auto_suspend_mins)
962
- except Exception as e:
963
- create_exception = e
964
- # We do not want to print the success context message if the engine creation fails
965
- # Since we are raising here and passing a "fail_message", the spinner will print the actual error message
966
- raise e
967
- if isinstance(create_exception, Exception):
968
- exit_with_error(f"[yellow]{create_exception}")
964
+ provider.create_engine(name, size, auto_suspend_mins)
969
965
  return name
970
966
 
971
967
  @cli.command(name="engines:create", help="Create a new engine")
@@ -1164,19 +1160,19 @@ def engines_alter_pool(size:str|None=None, min:int|None=None, max:int|None=None)
1164
1160
  def import_source_flow(provider: ResourcesBase) -> Sequence[ImportSource]:
1165
1161
  provider_type = type(provider)
1166
1162
 
1167
- if isinstance(provider, snowflake.Resources):
1163
+ if isinstance(provider, CLIResources):
1168
1164
  return snowflake_import_source_flow(provider)
1169
1165
  else:
1170
1166
  # Lazy import for azure to avoid optional dependency issues
1171
1167
  try:
1172
- from v0.relationalai.clients import azure
1173
- if isinstance(provider, azure.Resources):
1168
+ from v0.relationalai.clients.resources.azure.azure import Resources as AzureResources
1169
+ if isinstance(provider, AzureResources):
1174
1170
  return azure_import_source_flow(provider)
1175
1171
  except ImportError:
1176
1172
  pass
1177
1173
  raise Exception(f"No import source flow available for {provider_type.__module__}.{provider_type.__name__}")
1178
1174
 
1179
- def snowflake_import_source_flow(provider: snowflake.Resources) -> Sequence[ImportSource]:
1175
+ def snowflake_import_source_flow(provider: CLIResources) -> Sequence[ImportSource]:
1180
1176
  with Spinner("Fetching databases", "Databases fetched"):
1181
1177
  try:
1182
1178
  dbs = provider.list_databases()
@@ -1227,7 +1223,7 @@ def azure_import_source_flow(provider: azure.Resources) -> Sequence[ImportSource
1227
1223
 
1228
1224
  def import_source_options_flow(provider: ResourcesBase, source: ImportSource, default_options:dict) -> dict:
1229
1225
  if isinstance(source, ImportSourceFile):
1230
- type: LoadType = default_options.get("type", None)
1226
+ type: LoadType | None = default_options.get("type", None)
1231
1227
  if type is None or type == "auto":
1232
1228
  type = Loader.get_type_for(source)
1233
1229
  if type == "csv":
@@ -1329,7 +1325,7 @@ def parse_source(provider: ResourcesBase, raw: str) -> ImportSource:
1329
1325
  def imports_setup(engine_size:str|None=None, resume:bool=False, suspend:bool=False):
1330
1326
  divider(flush=True)
1331
1327
  ensure_config()
1332
- provider = get_resource_provider()
1328
+ provider = cast(CLIResources, get_resource_provider())
1333
1329
  data = None
1334
1330
 
1335
1331
  if resume or suspend:
@@ -1394,7 +1390,7 @@ def imports_setup(engine_size:str|None=None, resume:bool=False, suspend:bool=Fal
1394
1390
  def imports_get(id:str|None=None):
1395
1391
  divider(flush=True)
1396
1392
  ensure_config()
1397
- provider = get_resource_provider()
1393
+ provider = cast(CLIResources, get_resource_provider())
1398
1394
  import_streams = []
1399
1395
  import_response = []
1400
1396
  with Spinner("Fetching imports", "Imports fetched", "Error:"):
@@ -1567,7 +1563,7 @@ def imports_stream(
1567
1563
  ):
1568
1564
  divider(flush=True)
1569
1565
  ensure_config()
1570
- provider = get_resource_provider()
1566
+ provider = cast(CLIResources, get_resource_provider())
1571
1567
  default_options = ImportOptionsType.reduce(options)
1572
1568
 
1573
1569
  # Resume or suspend import stream
@@ -1713,7 +1709,7 @@ def imports_snapshot(source:str|None, model:str|None, name:str|None, type:str|No
1713
1709
  def imports_delete(object, model, force):
1714
1710
  divider(flush=True)
1715
1711
  ensure_config()
1716
- provider = cast(snowflake.Resources, get_resource_provider())
1712
+ provider = cast(CLIResources, get_resource_provider())
1717
1713
  if not model:
1718
1714
  with Spinner("Fetching models", "Models fetched"):
1719
1715
  try:
@@ -1768,7 +1764,7 @@ def imports_delete(object, model, force):
1768
1764
  def exports_list(model):
1769
1765
  divider(flush=True)
1770
1766
  ensure_config()
1771
- provider = cast(snowflake.Resources, get_resource_provider())
1767
+ provider = cast(CLIResources, get_resource_provider())
1772
1768
  coming_soon()
1773
1769
  if not model:
1774
1770
  with Spinner("Fetching models", "Models fetched"):
@@ -1810,7 +1806,7 @@ def exports_list(model):
1810
1806
  def exports_delete(export, model):
1811
1807
  divider(flush=True)
1812
1808
  ensure_config()
1813
- provider = cast(snowflake.Resources, get_resource_provider())
1809
+ provider = cast(CLIResources, get_resource_provider())
1814
1810
  coming_soon()
1815
1811
  if not model:
1816
1812
  with Spinner("Fetching models", "Models fetched"):
@@ -11,7 +11,6 @@ import functools
11
11
  import pytz
12
12
 
13
13
  from v0.relationalai.util.constants import TOP_LEVEL_PROFILE_NAME
14
- from .. import Resources
15
14
  from rich.table import Table
16
15
  from typing import Callable, Dict, Any
17
16
  from ..clients import config
@@ -39,7 +38,16 @@ def get_config(profile:str|Dict[str, Any]|None = None):
39
38
  @functools.cache
40
39
  def get_resource_provider(platform:str|None=None, _cfg:config.Config|None = None) -> ResourcesBase:
41
40
  cfg = _cfg or get_config()
42
- provider = Resources(config=cfg)
41
+ platform = platform or cfg.get("platform", "snowflake")
42
+ if platform == "snowflake":
43
+ from v0.relationalai.clients.resources.snowflake.cli_resources import CLIResources
44
+ provider = CLIResources(config=cfg)
45
+ elif platform == "azure":
46
+ from v0.relationalai.clients.resources.azure.azure import Resources
47
+ provider = Resources(config=cfg)
48
+ else:
49
+ from .. import Resources
50
+ provider = Resources(config=cfg)
43
51
  return provider
44
52
 
45
53
  def unexpand_user_path(path):
@@ -1,7 +1,8 @@
1
1
  from typing import cast
2
2
 
3
3
  from v0.relationalai.clients.config import Config
4
- from v0.relationalai.clients.snowflake import Resources, ResourcesBase
4
+ from v0.relationalai.clients.resources.snowflake import Resources
5
+ from v0.relationalai.clients.client import ResourcesBase
5
6
  from v0.relationalai.environments import runtime_env, SnowbookEnvironment
6
7
 
7
8
  def configure_otel(enable_otel_handler: bool, config: Config, resources: ResourcesBase):
@@ -17,7 +17,7 @@ from v0.relationalai.util.span_tracker import record_is_span, get_span_path_as_s
17
17
  from v0.relationalai.util.span_tracker import get_span_allowed_attributes_values, get_span_value_from_key
18
18
  from v0.relationalai.debugging import logger, Span, filter_span_attrs, otel_traceid_to_opentracing, get_current_span
19
19
 
20
- from v0.relationalai.clients.snowflake import Resources
20
+ from v0.relationalai.clients.resources.snowflake import Resources
21
21
 
22
22
  MAX_PAYLOAD_SIZE = 25*1024 # 25KB
23
23
  MAX_ATTRIBUTE_LENGTH = 1000