relationalai 0.12.10__py3-none-any.whl → 0.12.11__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.
@@ -441,8 +441,7 @@ class Resources(ResourcesBase):
441
441
  code: str,
442
442
  params: List[Any] | Any | None = None,
443
443
  raw: bool = False,
444
- help: bool = True,
445
- skip_auto_create: bool = False
444
+ help: bool = True
446
445
  ) -> Any:
447
446
  # print(f"\n--- sql---\n{code}\n--- end sql---\n")
448
447
  if not self._session:
@@ -459,6 +458,7 @@ class Resources(ResourcesBase):
459
458
  rai_app = self.config.get("rai_app_name", "")
460
459
  current_role = self.config.get("role")
461
460
  engine = self.get_default_engine_name()
461
+ engine_size = self.config.get_default_engine_size()
462
462
  assert isinstance(rai_app, str), f"rai_app_name must be a string, not {type(rai_app)}"
463
463
  assert isinstance(engine, str), f"engine must be a string, not {type(engine)}"
464
464
  print("\n")
@@ -467,10 +467,15 @@ class Resources(ResourcesBase):
467
467
  if re.search(f"database '{rai_app}' does not exist or not authorized.".lower(), orig_message):
468
468
  exception = SnowflakeAppMissingException(rai_app, current_role)
469
469
  raise exception from None
470
- # skip creating the engine if the query is a user transaction. exec_async_v2 will handle that case.
471
- if _is_engine_issue(orig_message) and not skip_auto_create:
470
+ if _is_engine_issue(orig_message) or _is_database_issue(orig_message):
472
471
  try:
473
- self.auto_create_engine(engine)
472
+ self._poll_use_index(
473
+ app_name=self.get_app_name(),
474
+ sources=self.sources,
475
+ model=self.database,
476
+ engine_name=engine,
477
+ engine_size=engine_size
478
+ )
474
479
  return self._exec(code, params, raw=raw, help=help)
475
480
  except EngineNameValidationException as e:
476
481
  raise EngineNameValidationException(engine) from e
@@ -1607,7 +1612,6 @@ Otherwise, remove it from your '{profile}' configuration profile.
1607
1612
  response = self._exec(
1608
1613
  sql_string,
1609
1614
  raw_code,
1610
- skip_auto_create=True,
1611
1615
  )
1612
1616
  if not response:
1613
1617
  raise Exception("Failed to create transaction")
@@ -1625,7 +1629,6 @@ Otherwise, remove it from your '{profile}' configuration profile.
1625
1629
  bypass_index=False,
1626
1630
  language: str = "rel",
1627
1631
  query_timeout_mins: int | None = None,
1628
- gi_setup_skipped: bool = False,
1629
1632
  ):
1630
1633
  if inputs is None:
1631
1634
  inputs = {}
@@ -1635,8 +1638,6 @@ Otherwise, remove it from your '{profile}' configuration profile.
1635
1638
  with debugging.span("transaction", **query_attrs_dict) as txn_span:
1636
1639
  with debugging.span("create_v2", **query_attrs_dict) as create_span:
1637
1640
  request_headers['user-agent'] = get_pyrel_version(self.generation)
1638
- request_headers['gi_setup_skipped'] = str(gi_setup_skipped)
1639
- request_headers['pyrel_program_id'] = debugging.get_program_span_id() or ""
1640
1641
  response = self._exec_rai_app(
1641
1642
  database=database,
1642
1643
  engine=engine,
@@ -1896,29 +1897,26 @@ Otherwise, remove it from your '{profile}' configuration profile.
1896
1897
  # Exec
1897
1898
  #--------------------------------------------------
1898
1899
 
1899
- def _exec_with_gi_retry(
1900
+ def exec_lqp(
1900
1901
  self,
1901
1902
  database: str,
1902
1903
  engine: str | None,
1903
- raw_code: str,
1904
- inputs: Dict | None,
1905
- readonly: bool,
1906
- nowait_durable: bool,
1907
- headers: Dict | None,
1908
- bypass_index: bool,
1909
- language: str,
1910
- query_timeout_mins: int | None,
1904
+ raw_code: bytes,
1905
+ readonly=True,
1906
+ *,
1907
+ inputs: Dict | None = None,
1908
+ nowait_durable=False,
1909
+ headers: Dict | None = None,
1910
+ bypass_index=False,
1911
+ query_timeout_mins: int | None = None,
1911
1912
  ):
1912
- """Execute with graph index retry logic.
1913
+ raw_code_b64 = base64.b64encode(raw_code).decode("utf-8")
1913
1914
 
1914
- Attempts execution with gi_setup_skipped=True first. If an engine or database
1915
- issue occurs, polls use_index and retries with gi_setup_skipped=False.
1916
- """
1917
1915
  try:
1918
1916
  return self._exec_async_v2(
1919
- database, engine, raw_code, inputs, readonly, nowait_durable,
1920
- headers=headers, bypass_index=bypass_index, language=language,
1921
- query_timeout_mins=query_timeout_mins, gi_setup_skipped=True,
1917
+ database, engine, raw_code_b64, inputs, readonly, nowait_durable,
1918
+ headers=headers, bypass_index=bypass_index, language='lqp',
1919
+ query_timeout_mins=query_timeout_mins,
1922
1920
  )
1923
1921
  except Exception as e:
1924
1922
  err_message = str(e).lower()
@@ -1935,32 +1933,13 @@ Otherwise, remove it from your '{profile}' configuration profile.
1935
1933
  )
1936
1934
 
1937
1935
  return self._exec_async_v2(
1938
- database, engine, raw_code, inputs, readonly, nowait_durable,
1939
- headers=headers, bypass_index=bypass_index, language=language,
1940
- query_timeout_mins=query_timeout_mins, gi_setup_skipped=False,
1936
+ database, engine, raw_code_b64, inputs, readonly, nowait_durable,
1937
+ headers=headers, bypass_index=bypass_index, language='lqp',
1938
+ query_timeout_mins=query_timeout_mins,
1941
1939
  )
1942
1940
  else:
1943
1941
  raise e
1944
1942
 
1945
- def exec_lqp(
1946
- self,
1947
- database: str,
1948
- engine: str | None,
1949
- raw_code: bytes,
1950
- readonly=True,
1951
- *,
1952
- inputs: Dict | None = None,
1953
- nowait_durable=False,
1954
- headers: Dict | None = None,
1955
- bypass_index=False,
1956
- query_timeout_mins: int | None = None,
1957
- ):
1958
- raw_code_b64 = base64.b64encode(raw_code).decode("utf-8")
1959
- return self._exec_with_gi_retry(
1960
- database, engine, raw_code_b64, inputs, readonly, nowait_durable,
1961
- headers, bypass_index, 'lqp', query_timeout_mins
1962
- )
1963
-
1964
1943
 
1965
1944
  def exec_raw(
1966
1945
  self,
@@ -1976,10 +1955,45 @@ Otherwise, remove it from your '{profile}' configuration profile.
1976
1955
  query_timeout_mins: int | None = None,
1977
1956
  ):
1978
1957
  raw_code = raw_code.replace("'", "\\'")
1979
- return self._exec_with_gi_retry(
1980
- database, engine, raw_code, inputs, readonly, nowait_durable,
1981
- headers, bypass_index, 'rel', query_timeout_mins
1982
- )
1958
+
1959
+ try:
1960
+ return self._exec_async_v2(
1961
+ database,
1962
+ engine,
1963
+ raw_code,
1964
+ inputs,
1965
+ readonly,
1966
+ nowait_durable,
1967
+ headers=headers,
1968
+ bypass_index=bypass_index,
1969
+ query_timeout_mins=query_timeout_mins,
1970
+ )
1971
+ except Exception as e:
1972
+ err_message = str(e).lower()
1973
+ if _is_engine_issue(err_message) or _is_database_issue(err_message):
1974
+ engine_name = engine or self.get_default_engine_name()
1975
+ engine_size = self.config.get_default_engine_size()
1976
+ self._poll_use_index(
1977
+ app_name=self.get_app_name(),
1978
+ sources=self.sources,
1979
+ model=database,
1980
+ engine_name=engine_name,
1981
+ engine_size=engine_size,
1982
+ headers=headers,
1983
+ )
1984
+ return self._exec_async_v2(
1985
+ database,
1986
+ engine,
1987
+ raw_code,
1988
+ inputs,
1989
+ readonly,
1990
+ nowait_durable,
1991
+ headers=headers,
1992
+ bypass_index=bypass_index,
1993
+ query_timeout_mins=query_timeout_mins,
1994
+ )
1995
+ else:
1996
+ raise e
1983
1997
 
1984
1998
 
1985
1999
  def format_results(self, results, task:m.Task|None=None) -> Tuple[DataFrame, List[Any]]:
@@ -3300,10 +3314,19 @@ class DirectAccessResources(Resources):
3300
3314
  message = "" # Not used when we check status_code directly
3301
3315
 
3302
3316
  # fix engine on engine error and retry
3303
- # Skip auto-retry if skip_auto_create is True to avoid recursion or to let _exec_async_v2 poll the index.
3304
- if _is_engine_issue(message) and not skip_auto_create:
3305
- engine = payload.get("engine_name", "") if payload else ""
3306
- self.auto_create_engine(engine)
3317
+ # Skip auto-retry if skip_auto_create is True to avoid recursion
3318
+ if (_is_engine_issue(message) and not skip_auto_create) or _is_database_issue(message):
3319
+ engine_name = payload.get("caller_engine_name", "") if payload else ""
3320
+ engine_name = engine_name or self.get_default_engine_name()
3321
+ engine_size = self.config.get_default_engine_size()
3322
+ self._poll_use_index(
3323
+ app_name=self.get_app_name(),
3324
+ sources=self.sources,
3325
+ model=self.database,
3326
+ engine_name=engine_name,
3327
+ engine_size=engine_size,
3328
+ headers=headers,
3329
+ )
3307
3330
  response = _send_request()
3308
3331
  except requests.exceptions.ConnectionError as e:
3309
3332
  if "NameResolutionError" in str(e):
@@ -3317,48 +3340,6 @@ class DirectAccessResources(Resources):
3317
3340
  raise e
3318
3341
  return response
3319
3342
 
3320
- def _txn_request_with_gi_retry(
3321
- self,
3322
- payload: Dict,
3323
- headers: Dict[str, str],
3324
- query_params: Dict,
3325
- engine: Union[str, None],
3326
- ):
3327
- """Make request with graph index retry logic.
3328
-
3329
- Attempts request with gi_setup_skipped=True first. If an engine or database
3330
- issue occurs, polls use_index and retries with gi_setup_skipped=False.
3331
- """
3332
- response = self.request(
3333
- "create_txn", payload=payload, headers=headers, query_params=query_params, skip_auto_create=True
3334
- )
3335
-
3336
- if response.status_code != 200:
3337
- try:
3338
- message = response.json().get("message", "")
3339
- except requests.exceptions.JSONDecodeError:
3340
- message = ""
3341
-
3342
- if _is_engine_issue(message) or _is_database_issue(message):
3343
- engine_name = engine or self.get_default_engine_name()
3344
- engine_size = self.config.get_default_engine_size()
3345
- self._poll_use_index(
3346
- app_name=self.get_app_name(),
3347
- sources=self.sources,
3348
- model=self.database,
3349
- engine_name=engine_name,
3350
- engine_size=engine_size,
3351
- headers=headers,
3352
- )
3353
- headers['gi_setup_skipped'] = 'False'
3354
- response = self.request(
3355
- "create_txn", payload=payload, headers=headers, query_params=query_params, skip_auto_create=True
3356
- )
3357
- else:
3358
- raise ResponseStatusException("Failed to create transaction.", response)
3359
-
3360
- return response
3361
-
3362
3343
  def _exec_async_v2(
3363
3344
  self,
3364
3345
  database: str,
@@ -3371,7 +3352,6 @@ class DirectAccessResources(Resources):
3371
3352
  bypass_index=False,
3372
3353
  language: str = "rel",
3373
3354
  query_timeout_mins: int | None = None,
3374
- gi_setup_skipped: bool = False,
3375
3355
  ):
3376
3356
 
3377
3357
  with debugging.span("transaction") as txn_span:
@@ -3394,16 +3374,13 @@ class DirectAccessResources(Resources):
3394
3374
  payload["timeout_mins"] = query_timeout_mins
3395
3375
  query_params={"use_graph_index": str(use_graph_index and not bypass_index)}
3396
3376
 
3397
- # Add gi_setup_skipped to headers
3398
- if headers is None:
3399
- headers = {}
3400
- headers["gi_setup_skipped"] = str(gi_setup_skipped)
3401
- headers['pyrel_program_id'] = debugging.get_program_span_id() or ""
3402
-
3403
- response = self._txn_request_with_gi_retry(
3404
- payload, headers, query_params, engine
3377
+ response = self.request(
3378
+ "create_txn", payload=payload, headers=headers, query_params=query_params,
3405
3379
  )
3406
3380
 
3381
+ if response.status_code != 200:
3382
+ raise ResponseStatusException("Failed to create transaction.", response)
3383
+
3407
3384
  artifact_info = {}
3408
3385
  response_content = response.json()
3409
3386
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: relationalai
3
- Version: 0.12.10
3
+ Version: 0.12.11
4
4
  Summary: RelationalAI Library and CLI
5
5
  Author-email: RelationalAI <support@relational.ai>
6
6
  License-File: LICENSE
@@ -29,7 +29,7 @@ relationalai/clients/hash_util.py,sha256=pZVR1FX3q4G_19p_r6wpIR2tIM8_WUlfAR7AVZJ
29
29
  relationalai/clients/local.py,sha256=uX1Or2WO0juDuqa6TCCvm3G2ieP6p0PtYp_jfrCMlVc,23577
30
30
  relationalai/clients/profile_polling.py,sha256=pUH7WKH4nYDD0SlQtg3wsWdj0K7qt6nZqUw8jTthCBs,2565
31
31
  relationalai/clients/result_helpers.py,sha256=wDSD02Ngx6W-YQqBIGKnpXD4Ju3pA1e9Nz6ORRI6SRI,17808
32
- relationalai/clients/snowflake.py,sha256=_7VSYo_On4IGg6UvcAsdO3rnuGHGPQGWbcHUHBPBx9Y,166982
32
+ relationalai/clients/snowflake.py,sha256=QPJrRolINDkjZb8xyuvaLJIWOEYXdeALLSNqIAAXUEY,166006
33
33
  relationalai/clients/types.py,sha256=eNo6akcMTbnBFbBbHd5IgVeY-zuAgtXlOs8Bo1SWmVU,2890
34
34
  relationalai/clients/use_index_poller.py,sha256=rrkg35xiHqY0-2dZlPkgixEGENrIrl7bf_2TboX_qew,46794
35
35
  relationalai/clients/util.py,sha256=NJC8fnrWHR01NydwESPSetIHRWf7jQJURYpaWJjmDyE,12311
@@ -442,8 +442,8 @@ frontend/debugger/dist/index.html,sha256=0wIQ1Pm7BclVV1wna6Mj8OmgU73B9rSEGPVX-Wo
442
442
  frontend/debugger/dist/assets/favicon-Dy0ZgA6N.png,sha256=tPXOEhOrM4tJyZVJQVBO_yFgNAlgooY38ZsjyrFstgg,620
443
443
  frontend/debugger/dist/assets/index-Cssla-O7.js,sha256=MxgIGfdKQyBWgufck1xYggQNhW5nj6BPjCF6Wleo-f0,298886
444
444
  frontend/debugger/dist/assets/index-DlHsYx1V.css,sha256=21pZtAjKCcHLFjbjfBQTF6y7QmOic-4FYaKNmwdNZVE,60141
445
- relationalai-0.12.10.dist-info/METADATA,sha256=_bWuKvwJLUCSK_9jfVf3J8vdQHZAeJh-VwspBmj0bJE,2563
446
- relationalai-0.12.10.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
447
- relationalai-0.12.10.dist-info/entry_points.txt,sha256=fo_oLFJih3PUgYuHXsk7RnCjBm9cqRNR--ab6DgI6-0,88
448
- relationalai-0.12.10.dist-info/licenses/LICENSE,sha256=pPyTVXFYhirkEW9VsnHIgUjT0Vg8_xsE6olrF5SIgpc,11343
449
- relationalai-0.12.10.dist-info/RECORD,,
445
+ relationalai-0.12.11.dist-info/METADATA,sha256=Gaq2yLT7R1yQ5rf6a7IwR1fWRaFaZ-sMLV5cMdQmeWg,2563
446
+ relationalai-0.12.11.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
447
+ relationalai-0.12.11.dist-info/entry_points.txt,sha256=fo_oLFJih3PUgYuHXsk7RnCjBm9cqRNR--ab6DgI6-0,88
448
+ relationalai-0.12.11.dist-info/licenses/LICENSE,sha256=pPyTVXFYhirkEW9VsnHIgUjT0Vg8_xsE6olrF5SIgpc,11343
449
+ relationalai-0.12.11.dist-info/RECORD,,