ygg 0.1.53__py3-none-any.whl → 0.1.55__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.
- {ygg-0.1.53.dist-info → ygg-0.1.55.dist-info}/METADATA +1 -1
- {ygg-0.1.53.dist-info → ygg-0.1.55.dist-info}/RECORD +13 -11
- {ygg-0.1.53.dist-info → ygg-0.1.55.dist-info}/WHEEL +1 -1
- yggdrasil/databricks/ai/__init__.py +1 -0
- yggdrasil/databricks/ai/loki.py +122 -0
- yggdrasil/databricks/workspaces/io.py +11 -6
- yggdrasil/databricks/workspaces/workspace.py +24 -4
- yggdrasil/pyutils/__init__.py +0 -2
- yggdrasil/pyutils/python_env.py +1 -1
- yggdrasil/version.py +1 -1
- {ygg-0.1.53.dist-info → ygg-0.1.55.dist-info}/entry_points.txt +0 -0
- {ygg-0.1.53.dist-info → ygg-0.1.55.dist-info}/licenses/LICENSE +0 -0
- {ygg-0.1.53.dist-info → ygg-0.1.55.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
ygg-0.1.
|
|
1
|
+
ygg-0.1.55.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
2
2
|
yggdrasil/__init__.py,sha256=4-ghPak2S6zfMqmnlxW2GCgPb5s79znpKa2hGEGXcE4,24
|
|
3
|
-
yggdrasil/version.py,sha256=
|
|
3
|
+
yggdrasil/version.py,sha256=RJcC5yver_ugtAU_HgwZ-2HWyszBXpsLZyyNma6G4Dc,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
7
|
yggdrasil/databricks/compute/__init__.py,sha256=NvdzmaJSNYY1uJthv1hHdBuNu3bD_-Z65DWnaJt9yXg,289
|
|
6
8
|
yggdrasil/databricks/compute/cluster.py,sha256=YomLfvB0oxbgl6WDgBRxI1UXsxwlEbR6gq3FUbPHscY,44199
|
|
7
9
|
yggdrasil/databricks/compute/execution_context.py,sha256=jIV6uru2NeX3O5lg-3KEqmXtLxxq45CFgkBQgQIIOHQ,23327
|
|
@@ -16,11 +18,11 @@ yggdrasil/databricks/sql/types.py,sha256=5G-BM9_eOsRKEMzeDTWUsWW5g4Idvs-czVCpOCr
|
|
|
16
18
|
yggdrasil/databricks/sql/warehouse.py,sha256=1J0dyQLJb-OS1_1xU1eAVZ4CoL2-FhFeowKSvU3RzFc,9773
|
|
17
19
|
yggdrasil/databricks/workspaces/__init__.py,sha256=dv2zotoFVhNFlTCdRq6gwf5bEzeZkOZszoNZMs0k59g,114
|
|
18
20
|
yggdrasil/databricks/workspaces/filesytem.py,sha256=Z8JXU7_XUEbw9fpTQT1avRQKi-IAP2KemXBMPkUoY4w,9805
|
|
19
|
-
yggdrasil/databricks/workspaces/io.py,sha256=
|
|
21
|
+
yggdrasil/databricks/workspaces/io.py,sha256=PAoxIxYvTC162Dx2qL2hk8oAdt8BnYrQ3jJHcJm4VkA,33116
|
|
20
22
|
yggdrasil/databricks/workspaces/path.py,sha256=KkvLFHrps3UFr4ogYdESbJHEMfQBcWfWfXjlrv_7rTU,55180
|
|
21
23
|
yggdrasil/databricks/workspaces/path_kind.py,sha256=rhWe1ky7uPD0du0bZSv2S4fK4C5zWd7zAF3UeS2iiPU,283
|
|
22
24
|
yggdrasil/databricks/workspaces/volumes_path.py,sha256=s8CA33cG3jpMVJy5MILLlkEBcFg_qInDCF2jozLj1Fg,2431
|
|
23
|
-
yggdrasil/databricks/workspaces/workspace.py,sha256=
|
|
25
|
+
yggdrasil/databricks/workspaces/workspace.py,sha256=5DCPz5io_rmrpGNi5I6RChmyZ8kjlNUFGQl8mzQJThg,25511
|
|
24
26
|
yggdrasil/dataclasses/__init__.py,sha256=_RkhfF3KC1eSORby1dzvBXQ0-UGG3u6wyUQWX2jq1Pc,108
|
|
25
27
|
yggdrasil/dataclasses/dataclass.py,sha256=LxrCjwvmBnb8yRI_N-c31RHHxB4XoJPixmKg9iBIuaI,1148
|
|
26
28
|
yggdrasil/libs/__init__.py,sha256=zdC9OU0Xy36CLY9mg2drxN6S7isPR8aTLzJA6xVIeLE,91
|
|
@@ -31,14 +33,14 @@ yggdrasil/libs/sparklib.py,sha256=FQ3W1iz2EIpQreorOiQuFt15rdhq2QhGEAWp8Zrbl9A,10
|
|
|
31
33
|
yggdrasil/libs/extensions/__init__.py,sha256=mcXW5Li3Cbprbs4Ci-b5A0Ju0wmLcfvEiFusTx6xNjU,117
|
|
32
34
|
yggdrasil/libs/extensions/polars_extensions.py,sha256=RTkGi8llhPJjX7x9egix7-yXWo2X24zIAPSKXV37SSA,12397
|
|
33
35
|
yggdrasil/libs/extensions/spark_extensions.py,sha256=E64n-3SFTDgMuXwWitX6vOYP9ln2lpGKb0htoBLEZgc,16745
|
|
34
|
-
yggdrasil/pyutils/__init__.py,sha256=
|
|
36
|
+
yggdrasil/pyutils/__init__.py,sha256=a7LKg9xWZGtv2o5jr_7wrSZJ9ZmwolKWc--8iRgKlL4,225
|
|
35
37
|
yggdrasil/pyutils/callable_serde.py,sha256=1XckmFO-ThP0MedxgXwB71u9jWUuhM1btOzW9gJ8w9g,23117
|
|
36
38
|
yggdrasil/pyutils/equality.py,sha256=Xyf8D1dLUCm3spDEir8Zyj7O4US_fBJwEylJCfJ9slI,3080
|
|
37
39
|
yggdrasil/pyutils/exceptions.py,sha256=ssKNm-rjhavHUOZmGA7_1Gq9tSHDrb2EFI-cnBuWgng,3388
|
|
38
40
|
yggdrasil/pyutils/expiring_dict.py,sha256=pr2u25LGwPVbLfsLptiHGovUtYRRo0AMjaJtCtJl7nQ,8477
|
|
39
41
|
yggdrasil/pyutils/modules.py,sha256=B7IP99YqUMW6-DIESFzBx8-09V1d0a8qrIJUDFhhL2g,11424
|
|
40
42
|
yggdrasil/pyutils/parallel.py,sha256=ubuq2m9dJzWYUyKCga4Y_9bpaeMYUrleYxdp49CHr44,6781
|
|
41
|
-
yggdrasil/pyutils/python_env.py,sha256=
|
|
43
|
+
yggdrasil/pyutils/python_env.py,sha256=nmXXcIUSSbpKWHBnYfCY1QIW-LQ8IILV9Ceijufu5Pg,51086
|
|
42
44
|
yggdrasil/pyutils/retry.py,sha256=gXBtn1DdmIYIUmGKOUr8-SUT7MOu97LykN2YR4uocgc,11917
|
|
43
45
|
yggdrasil/requests/__init__.py,sha256=dMesyzq97_DmI765x0TwaDPEfsxFtgGNgchk8LvEN-o,103
|
|
44
46
|
yggdrasil/requests/msal.py,sha256=s2GCyzbgFdgdlJ1JqMrZ4qYVbmoG46-ZOTcaVQhZ-sQ,9220
|
|
@@ -57,8 +59,8 @@ yggdrasil/types/cast/registry.py,sha256=OOqIfbIjPH-a3figvu-zTvEtUDTEWhe2xIl3cCA4
|
|
|
57
59
|
yggdrasil/types/cast/spark_cast.py,sha256=_KAsl1DqmKMSfWxqhVE7gosjYdgiL1C5bDQv6eP3HtA,24926
|
|
58
60
|
yggdrasil/types/cast/spark_pandas_cast.py,sha256=BuTiWrdCANZCdD_p2MAytqm74eq-rdRXd-LGojBRrfU,5023
|
|
59
61
|
yggdrasil/types/cast/spark_polars_cast.py,sha256=btmZNHXn2NSt3fUuB4xg7coaE0RezIBdZD92H8NK0Jw,9073
|
|
60
|
-
ygg-0.1.
|
|
61
|
-
ygg-0.1.
|
|
62
|
-
ygg-0.1.
|
|
63
|
-
ygg-0.1.
|
|
64
|
-
ygg-0.1.
|
|
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,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .loki import *
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
from typing import Optional, Dict, Any, List
|
|
2
|
+
from dataclasses import field, dataclass
|
|
3
|
+
|
|
4
|
+
from ..workspaces.workspace import WorkspaceService
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
from openai import OpenAI
|
|
8
|
+
|
|
9
|
+
def make_ai_client(
|
|
10
|
+
api_key: str,
|
|
11
|
+
base_url: str
|
|
12
|
+
):
|
|
13
|
+
return OpenAI(
|
|
14
|
+
api_key=api_key,
|
|
15
|
+
base_url=base_url
|
|
16
|
+
)
|
|
17
|
+
except ImportError:
|
|
18
|
+
class OpenAI:
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
def make_ai_client(
|
|
22
|
+
api_key: str,
|
|
23
|
+
base_url: str
|
|
24
|
+
):
|
|
25
|
+
from openai import OpenAI
|
|
26
|
+
|
|
27
|
+
return OpenAI(
|
|
28
|
+
api_key=api_key,
|
|
29
|
+
base_url=base_url
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
__all__ = [
|
|
33
|
+
"Loki"
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass
|
|
38
|
+
class Loki(WorkspaceService):
|
|
39
|
+
model: str = "databricks-gemini-2-5-flash"
|
|
40
|
+
|
|
41
|
+
_ai_client: Optional[OpenAI] = field(repr=False, hash=False, default=None)
|
|
42
|
+
|
|
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
|
|
48
|
+
|
|
49
|
+
def make_aiclient(self):
|
|
50
|
+
return make_ai_client(
|
|
51
|
+
api_key=self.workspace.current_token(),
|
|
52
|
+
base_url=self.workspace.host + "/serving-endpoints"
|
|
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 ""
|
|
@@ -12,7 +12,8 @@ import pyarrow.csv as pcsv
|
|
|
12
12
|
import pyarrow.parquet as pq
|
|
13
13
|
from pyarrow.dataset import (
|
|
14
14
|
FileFormat,
|
|
15
|
-
ParquetFileFormat,
|
|
15
|
+
ParquetFileFormat,
|
|
16
|
+
CsvFileFormat,
|
|
16
17
|
)
|
|
17
18
|
|
|
18
19
|
from .path_kind import DatabricksPathKind
|
|
@@ -71,10 +72,11 @@ class DatabricksIO(ABC, IO):
|
|
|
71
72
|
self.close()
|
|
72
73
|
|
|
73
74
|
def __del__(self):
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
if self._need_flush():
|
|
76
|
+
try:
|
|
77
|
+
Thread(target=self.close).start()
|
|
78
|
+
except BaseException:
|
|
79
|
+
pass
|
|
78
80
|
|
|
79
81
|
def __next__(self):
|
|
80
82
|
"""Iterate over lines in the file."""
|
|
@@ -533,13 +535,16 @@ class DatabricksIO(ABC, IO):
|
|
|
533
535
|
|
|
534
536
|
return size
|
|
535
537
|
|
|
538
|
+
def _need_flush(self):
|
|
539
|
+
return self._write_flag and self._buffer is not None
|
|
540
|
+
|
|
536
541
|
def flush(self):
|
|
537
542
|
"""Flush buffered data to the remote path.
|
|
538
543
|
|
|
539
544
|
Returns:
|
|
540
545
|
None.
|
|
541
546
|
"""
|
|
542
|
-
if self.
|
|
547
|
+
if self._need_flush():
|
|
543
548
|
self.write_all_bytes(data=self._buffer.getvalue())
|
|
544
549
|
self._write_flag = False
|
|
545
550
|
|
|
@@ -645,15 +645,16 @@ class Workspace:
|
|
|
645
645
|
|
|
646
646
|
def clusters(
|
|
647
647
|
self,
|
|
648
|
+
workspace: Optional["Workspace"] = None,
|
|
648
649
|
cluster_id: Optional[str] = None,
|
|
649
650
|
cluster_name: Optional[str] = None,
|
|
650
651
|
) -> "Cluster":
|
|
651
652
|
"""Return a Cluster helper bound to this workspace.
|
|
652
653
|
|
|
653
654
|
Args:
|
|
655
|
+
workspace: Optional workspace override.
|
|
654
656
|
cluster_id: Optional cluster id.
|
|
655
657
|
cluster_name: Optional cluster name.
|
|
656
|
-
**kwargs: Additional Cluster parameters.
|
|
657
658
|
|
|
658
659
|
Returns:
|
|
659
660
|
A Cluster instance.
|
|
@@ -661,11 +662,30 @@ class Workspace:
|
|
|
661
662
|
from ..compute.cluster import Cluster
|
|
662
663
|
|
|
663
664
|
return Cluster(
|
|
664
|
-
workspace=self,
|
|
665
|
+
workspace=self if workspace is None else workspace,
|
|
665
666
|
cluster_id=cluster_id,
|
|
666
667
|
cluster_name=cluster_name,
|
|
667
668
|
)
|
|
668
669
|
|
|
670
|
+
def loki(
|
|
671
|
+
self,
|
|
672
|
+
workspace: Optional["Workspace"] = None,
|
|
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
|
+
from ..ai.loki import Loki
|
|
684
|
+
|
|
685
|
+
return Loki(
|
|
686
|
+
workspace=self if workspace is None else workspace,
|
|
687
|
+
)
|
|
688
|
+
|
|
669
689
|
# ---------------------------------------------------------------------------
|
|
670
690
|
# Workspace-bound base class
|
|
671
691
|
# ---------------------------------------------------------------------------
|
|
@@ -717,13 +737,13 @@ class WorkspaceService(ABC):
|
|
|
717
737
|
"""
|
|
718
738
|
return self.workspace.is_in_databricks_environment()
|
|
719
739
|
|
|
720
|
-
def connect(self):
|
|
740
|
+
def connect(self, clone: bool = False):
|
|
721
741
|
"""Connect the underlying workspace.
|
|
722
742
|
|
|
723
743
|
Returns:
|
|
724
744
|
The current WorkspaceService instance.
|
|
725
745
|
"""
|
|
726
|
-
self.workspace = self.workspace.connect()
|
|
746
|
+
self.workspace = self.workspace.connect(clone=clone)
|
|
727
747
|
return self
|
|
728
748
|
|
|
729
749
|
def dbfs_path(
|
yggdrasil/pyutils/__init__.py
CHANGED
yggdrasil/pyutils/python_env.py
CHANGED
|
@@ -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
|
|
23
|
+
from .modules import PipIndexSettings
|
|
24
24
|
|
|
25
25
|
log = logging.getLogger(__name__)
|
|
26
26
|
|
yggdrasil/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.55"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|