ygg 0.1.55__py3-none-any.whl → 0.1.57__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,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ygg
3
- Version: 0.1.55
3
+ Version: 0.1.57
4
4
  Summary: Type-friendly utilities for moving data between Python objects, Arrow, Polars, Pandas, Spark, and Databricks
5
5
  Author: Yggdrasil contributors
6
6
  License: Apache License
@@ -1,9 +1,9 @@
1
- ygg-0.1.55.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
1
+ ygg-0.1.57.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
2
2
  yggdrasil/__init__.py,sha256=4-ghPak2S6zfMqmnlxW2GCgPb5s79znpKa2hGEGXcE4,24
3
- yggdrasil/version.py,sha256=RJcC5yver_ugtAU_HgwZ-2HWyszBXpsLZyyNma6G4Dc,22
3
+ yggdrasil/version.py,sha256=mM67BdyYZ17u9xAi4WRzFQM2e6yfmX4MPd36R3L920M,22
4
4
  yggdrasil/databricks/__init__.py,sha256=skctY2c8W-hI81upx9F_PWRe5ishL3hrdiTuizgDjdw,152
5
- yggdrasil/databricks/ai/__init__.py,sha256=Mkp70UOVBzDQvdPNsqncHcyzxe5PnSGYE_bHnYxA1eA,21
6
- yggdrasil/databricks/ai/loki.py,sha256=iyekxctP6393LBN0PJOZgHBxQs9vDyQeRXPrru_krF0,3661
5
+ yggdrasil/databricks/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ yggdrasil/databricks/ai/loki.py,sha256=1AhMOquMTsZZGYw5cGoXn-QQhdBRMXM9ZRPEUAv4Y3k,1216
7
7
  yggdrasil/databricks/compute/__init__.py,sha256=NvdzmaJSNYY1uJthv1hHdBuNu3bD_-Z65DWnaJt9yXg,289
8
8
  yggdrasil/databricks/compute/cluster.py,sha256=YomLfvB0oxbgl6WDgBRxI1UXsxwlEbR6gq3FUbPHscY,44199
9
9
  yggdrasil/databricks/compute/execution_context.py,sha256=jIV6uru2NeX3O5lg-3KEqmXtLxxq45CFgkBQgQIIOHQ,23327
@@ -18,11 +18,11 @@ yggdrasil/databricks/sql/types.py,sha256=5G-BM9_eOsRKEMzeDTWUsWW5g4Idvs-czVCpOCr
18
18
  yggdrasil/databricks/sql/warehouse.py,sha256=1J0dyQLJb-OS1_1xU1eAVZ4CoL2-FhFeowKSvU3RzFc,9773
19
19
  yggdrasil/databricks/workspaces/__init__.py,sha256=dv2zotoFVhNFlTCdRq6gwf5bEzeZkOZszoNZMs0k59g,114
20
20
  yggdrasil/databricks/workspaces/filesytem.py,sha256=Z8JXU7_XUEbw9fpTQT1avRQKi-IAP2KemXBMPkUoY4w,9805
21
- yggdrasil/databricks/workspaces/io.py,sha256=PAoxIxYvTC162Dx2qL2hk8oAdt8BnYrQ3jJHcJm4VkA,33116
21
+ yggdrasil/databricks/workspaces/io.py,sha256=hErGeSKJ9XpSUvlYAAckh_8IKQQmGeDOqbdl2rh9Fbs,33240
22
22
  yggdrasil/databricks/workspaces/path.py,sha256=KkvLFHrps3UFr4ogYdESbJHEMfQBcWfWfXjlrv_7rTU,55180
23
23
  yggdrasil/databricks/workspaces/path_kind.py,sha256=rhWe1ky7uPD0du0bZSv2S4fK4C5zWd7zAF3UeS2iiPU,283
24
24
  yggdrasil/databricks/workspaces/volumes_path.py,sha256=s8CA33cG3jpMVJy5MILLlkEBcFg_qInDCF2jozLj1Fg,2431
25
- yggdrasil/databricks/workspaces/workspace.py,sha256=5DCPz5io_rmrpGNi5I6RChmyZ8kjlNUFGQl8mzQJThg,25511
25
+ yggdrasil/databricks/workspaces/workspace.py,sha256=Tl1pYzTGNpjsPmHCJ62HoJvdzHGiZb43vQxrI3Sk7js,25233
26
26
  yggdrasil/dataclasses/__init__.py,sha256=_RkhfF3KC1eSORby1dzvBXQ0-UGG3u6wyUQWX2jq1Pc,108
27
27
  yggdrasil/dataclasses/dataclass.py,sha256=LxrCjwvmBnb8yRI_N-c31RHHxB4XoJPixmKg9iBIuaI,1148
28
28
  yggdrasil/libs/__init__.py,sha256=zdC9OU0Xy36CLY9mg2drxN6S7isPR8aTLzJA6xVIeLE,91
@@ -33,14 +33,14 @@ yggdrasil/libs/sparklib.py,sha256=FQ3W1iz2EIpQreorOiQuFt15rdhq2QhGEAWp8Zrbl9A,10
33
33
  yggdrasil/libs/extensions/__init__.py,sha256=mcXW5Li3Cbprbs4Ci-b5A0Ju0wmLcfvEiFusTx6xNjU,117
34
34
  yggdrasil/libs/extensions/polars_extensions.py,sha256=RTkGi8llhPJjX7x9egix7-yXWo2X24zIAPSKXV37SSA,12397
35
35
  yggdrasil/libs/extensions/spark_extensions.py,sha256=E64n-3SFTDgMuXwWitX6vOYP9ln2lpGKb0htoBLEZgc,16745
36
- yggdrasil/pyutils/__init__.py,sha256=a7LKg9xWZGtv2o5jr_7wrSZJ9ZmwolKWc--8iRgKlL4,225
36
+ yggdrasil/pyutils/__init__.py,sha256=tl-LapAc71TV7RMgf2ftKwrzr8iiLOGHeJgA3RvO93w,293
37
37
  yggdrasil/pyutils/callable_serde.py,sha256=1XckmFO-ThP0MedxgXwB71u9jWUuhM1btOzW9gJ8w9g,23117
38
38
  yggdrasil/pyutils/equality.py,sha256=Xyf8D1dLUCm3spDEir8Zyj7O4US_fBJwEylJCfJ9slI,3080
39
39
  yggdrasil/pyutils/exceptions.py,sha256=ssKNm-rjhavHUOZmGA7_1Gq9tSHDrb2EFI-cnBuWgng,3388
40
40
  yggdrasil/pyutils/expiring_dict.py,sha256=pr2u25LGwPVbLfsLptiHGovUtYRRo0AMjaJtCtJl7nQ,8477
41
41
  yggdrasil/pyutils/modules.py,sha256=B7IP99YqUMW6-DIESFzBx8-09V1d0a8qrIJUDFhhL2g,11424
42
42
  yggdrasil/pyutils/parallel.py,sha256=ubuq2m9dJzWYUyKCga4Y_9bpaeMYUrleYxdp49CHr44,6781
43
- yggdrasil/pyutils/python_env.py,sha256=nmXXcIUSSbpKWHBnYfCY1QIW-LQ8IILV9Ceijufu5Pg,51086
43
+ yggdrasil/pyutils/python_env.py,sha256=Gh5geFK9ABpyWEfyegGUfIJUoPxKwcH0pqLBiMrW9Rw,51103
44
44
  yggdrasil/pyutils/retry.py,sha256=gXBtn1DdmIYIUmGKOUr8-SUT7MOu97LykN2YR4uocgc,11917
45
45
  yggdrasil/requests/__init__.py,sha256=dMesyzq97_DmI765x0TwaDPEfsxFtgGNgchk8LvEN-o,103
46
46
  yggdrasil/requests/msal.py,sha256=s2GCyzbgFdgdlJ1JqMrZ4qYVbmoG46-ZOTcaVQhZ-sQ,9220
@@ -59,8 +59,8 @@ yggdrasil/types/cast/registry.py,sha256=OOqIfbIjPH-a3figvu-zTvEtUDTEWhe2xIl3cCA4
59
59
  yggdrasil/types/cast/spark_cast.py,sha256=_KAsl1DqmKMSfWxqhVE7gosjYdgiL1C5bDQv6eP3HtA,24926
60
60
  yggdrasil/types/cast/spark_pandas_cast.py,sha256=BuTiWrdCANZCdD_p2MAytqm74eq-rdRXd-LGojBRrfU,5023
61
61
  yggdrasil/types/cast/spark_polars_cast.py,sha256=btmZNHXn2NSt3fUuB4xg7coaE0RezIBdZD92H8NK0Jw,9073
62
- ygg-0.1.55.dist-info/METADATA,sha256=F84590C1dKd4ZllEbe1uzAsMuUw9we134qVVQmOcGNI,18528
63
- ygg-0.1.55.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
64
- ygg-0.1.55.dist-info/entry_points.txt,sha256=6q-vpWG3kvw2dhctQ0LALdatoeefkN855Ev02I1dKGY,70
65
- ygg-0.1.55.dist-info/top_level.txt,sha256=iBe9Kk4VIVbLpgv_p8OZUIfxgj4dgJ5wBg6vO3rigso,10
66
- ygg-0.1.55.dist-info/RECORD,,
62
+ ygg-0.1.57.dist-info/METADATA,sha256=0VEcri5fh3BUYJxxhQ_icTZfhkry6KgEhbKQEEDrKJ4,18528
63
+ ygg-0.1.57.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
64
+ ygg-0.1.57.dist-info/entry_points.txt,sha256=6q-vpWG3kvw2dhctQ0LALdatoeefkN855Ev02I1dKGY,70
65
+ ygg-0.1.57.dist-info/top_level.txt,sha256=iBe9Kk4VIVbLpgv_p8OZUIfxgj4dgJ5wBg6vO3rigso,10
66
+ ygg-0.1.57.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.10.1)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1 +0,0 @@
1
- from .loki import *
@@ -1,4 +1,4 @@
1
- from typing import Optional, Dict, Any, List
1
+ from typing import Optional
2
2
  from dataclasses import field, dataclass
3
3
 
4
4
  from ..workspaces.workspace import WorkspaceService
@@ -6,7 +6,7 @@ from ..workspaces.workspace import WorkspaceService
6
6
  try:
7
7
  from openai import OpenAI
8
8
 
9
- def make_ai_client(
9
+ def make_openai_client(
10
10
  api_key: str,
11
11
  base_url: str
12
12
  ):
@@ -18,7 +18,7 @@ except ImportError:
18
18
  class OpenAI:
19
19
  pass
20
20
 
21
- def make_ai_client(
21
+ def make_openai_client(
22
22
  api_key: str,
23
23
  base_url: str
24
24
  ):
@@ -38,85 +38,16 @@ __all__ = [
38
38
  class Loki(WorkspaceService):
39
39
  model: str = "databricks-gemini-2-5-flash"
40
40
 
41
- _ai_client: Optional[OpenAI] = field(repr=False, hash=False, default=None)
41
+ _openai_client: Optional[OpenAI] = field(repr=False, hash=False, default=None)
42
42
 
43
43
  @property
44
- def ai_client(self):
45
- if self._ai_client is None:
46
- self._ai_client = self.make_aiclient()
47
- return self._ai_client
44
+ def openai_client(self):
45
+ if self._openai_client is None:
46
+ self._openai_client = self.make_openai_client()
47
+ return self._openai_client
48
48
 
49
- def make_aiclient(self):
50
- return make_ai_client(
49
+ def make_openai_client(self):
50
+ return make_openai_client(
51
51
  api_key=self.workspace.current_token(),
52
52
  base_url=self.workspace.host + "/serving-endpoints"
53
53
  )
54
-
55
- def ask(
56
- self,
57
- command: str,
58
- *,
59
- system: Optional[str] = None,
60
- max_tokens: int = 5000,
61
- temperature: Optional[float] = None,
62
- extra_messages: Optional[List[Dict[str, str]]] = None,
63
- **kwargs,
64
- ) -> str:
65
- """
66
- Send a chat prompt to a Databricks Model Serving endpoint using the
67
- OpenAI-compatible Chat Completions API and return the assistant's text.
68
-
69
- This is a thin convenience wrapper around:
70
- self.ai_client.chat.completions.create(...)
71
-
72
- Parameters
73
- ----------
74
- command:
75
- The user prompt text to send.
76
- system:
77
- Optional system instruction (prepended as the first message).
78
- max_tokens:
79
- Upper bound on the number of tokens generated in the response.
80
- temperature:
81
- Optional sampling temperature. If None, the client/model default is used.
82
- extra_messages:
83
- Optional list of additional chat messages to insert before the user prompt.
84
- Each item should be a dict like {"role": "...", "content": "..."}.
85
- Useful for few-shot examples or carrying prior context.
86
- **kwargs:
87
- Any additional parameters forwarded directly to
88
- `chat.completions.create(...)` (e.g. top_p, presence_penalty, etc.).
89
-
90
- Returns
91
- -------
92
- str
93
- The assistant message content (empty string if the API returns no content).
94
-
95
- Raises
96
- ------
97
- Exception
98
- Propagates any exceptions raised by the OpenAI client (HTTP errors,
99
- auth errors, invalid request errors, timeouts, etc.).
100
- """
101
- messages: List[Dict[str, str]] = []
102
-
103
- if system:
104
- messages.append({"role": "system", "content": system})
105
-
106
- if extra_messages:
107
- messages.extend(extra_messages)
108
-
109
- messages.append({"role": "user", "content": command})
110
-
111
- # Build params cleanly (only include temperature if provided)
112
- params: Dict[str, Any] = dict(
113
- model=self.model,
114
- messages=messages,
115
- max_tokens=max_tokens,
116
- **kwargs,
117
- )
118
- if temperature is not None:
119
- params["temperature"] = temperature
120
-
121
- resp = self.ai_client.chat.completions.create(**params)
122
- return resp.choices[0].message.content or ""
@@ -20,6 +20,7 @@ from .path_kind import DatabricksPathKind
20
20
  from ...libs.databrickslib import databricks
21
21
  from ...libs.pandaslib import PandasDataFrame
22
22
  from ...libs.polarslib import polars, PolarsDataFrame
23
+ from ...pyutils import retry
23
24
  from ...types.cast.registry import convert
24
25
  from ...types.file_format import ExcelFileFormat
25
26
 
@@ -30,6 +31,7 @@ if databricks is not None:
30
31
  ResourceDoesNotExist,
31
32
  BadRequest,
32
33
  )
34
+ from databricks.sdk.errors import InternalError
33
35
 
34
36
  if TYPE_CHECKING:
35
37
  from .path import DatabricksPath
@@ -1036,6 +1038,7 @@ class DatabricksVolumeIO(DatabricksIO):
1036
1038
  end = start + length
1037
1039
  return data[start:end]
1038
1040
 
1041
+ @retry(exceptions=(InternalError,))
1039
1042
  def write_all_bytes(self, data: bytes):
1040
1043
  """Write bytes to a volume file.
1041
1044
 
@@ -652,9 +652,9 @@ class Workspace:
652
652
  """Return a Cluster helper bound to this workspace.
653
653
 
654
654
  Args:
655
- workspace: Optional workspace override.
656
655
  cluster_id: Optional cluster id.
657
656
  cluster_name: Optional cluster name.
657
+ **kwargs: Additional Cluster parameters.
658
658
 
659
659
  Returns:
660
660
  A Cluster instance.
@@ -662,7 +662,7 @@ class Workspace:
662
662
  from ..compute.cluster import Cluster
663
663
 
664
664
  return Cluster(
665
- workspace=self if workspace is None else workspace,
665
+ workspace=self,
666
666
  cluster_id=cluster_id,
667
667
  cluster_name=cluster_name,
668
668
  )
@@ -671,19 +671,10 @@ class Workspace:
671
671
  self,
672
672
  workspace: Optional["Workspace"] = None,
673
673
  ):
674
- """
675
- Return a Cluster helper bound to this workspace.
676
-
677
- Args:
678
- workspace: Optional workspace override.
679
-
680
- Returns:
681
- A Loki AI instance.
682
- """
683
674
  from ..ai.loki import Loki
684
675
 
685
676
  return Loki(
686
- workspace=self if workspace is None else workspace,
677
+ workspace=self,
687
678
  )
688
679
 
689
680
  # ---------------------------------------------------------------------------
@@ -4,3 +4,5 @@ from .retry import retry
4
4
  from .parallel import parallelize
5
5
  from .python_env import PythonEnv
6
6
  from .callable_serde import CallableSerde
7
+
8
+ __all__ = ["retry", "parallelize", "PythonEnv", "CallableSerde"]
@@ -20,7 +20,7 @@ from dataclasses import dataclass, field
20
20
  from pathlib import Path
21
21
  from typing import Any, Iterable, Iterator, Mapping, MutableMapping, Optional, Union, List, Tuple
22
22
 
23
- from .modules import PipIndexSettings
23
+ from yggdrasil.pyutils.modules import PipIndexSettings
24
24
 
25
25
  log = logging.getLogger(__name__)
26
26
 
yggdrasil/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.55"
1
+ __version__ = "0.1.57"