ygg 0.1.54__tar.gz → 0.1.55__tar.gz
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.54 → ygg-0.1.55}/PKG-INFO +1 -1
- {ygg-0.1.54 → ygg-0.1.55}/pyproject.toml +1 -1
- {ygg-0.1.54 → ygg-0.1.55}/src/ygg.egg-info/PKG-INFO +1 -1
- ygg-0.1.55/src/yggdrasil/databricks/ai/__init__.py +1 -0
- ygg-0.1.55/src/yggdrasil/databricks/ai/loki.py +122 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/workspaces/workspace.py +12 -3
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/pyutils/__init__.py +0 -2
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/pyutils/python_env.py +1 -1
- ygg-0.1.55/src/yggdrasil/version.py +1 -0
- ygg-0.1.54/src/yggdrasil/databricks/ai/__init__.py +0 -0
- ygg-0.1.54/src/yggdrasil/databricks/ai/loki.py +0 -53
- ygg-0.1.54/src/yggdrasil/version.py +0 -1
- {ygg-0.1.54 → ygg-0.1.55}/LICENSE +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/README.md +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/setup.cfg +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/ygg.egg-info/SOURCES.txt +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/ygg.egg-info/dependency_links.txt +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/ygg.egg-info/entry_points.txt +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/ygg.egg-info/requires.txt +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/ygg.egg-info/top_level.txt +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/compute/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/compute/cluster.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/compute/execution_context.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/compute/remote.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/jobs/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/jobs/config.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/sql/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/sql/engine.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/sql/exceptions.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/sql/statement_result.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/sql/types.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/sql/warehouse.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/workspaces/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/workspaces/filesytem.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/workspaces/io.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/workspaces/path.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/workspaces/path_kind.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/databricks/workspaces/volumes_path.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/dataclasses/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/dataclasses/dataclass.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/libs/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/libs/databrickslib.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/libs/extensions/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/libs/extensions/polars_extensions.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/libs/extensions/spark_extensions.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/libs/pandaslib.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/libs/polarslib.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/libs/sparklib.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/pyutils/callable_serde.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/pyutils/equality.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/pyutils/exceptions.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/pyutils/expiring_dict.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/pyutils/modules.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/pyutils/parallel.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/pyutils/retry.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/requests/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/requests/msal.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/requests/session.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/cast/__init__.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/cast/arrow_cast.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/cast/cast_options.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/cast/pandas_cast.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/cast/polars_cast.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/cast/polars_pandas_cast.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/cast/registry.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/cast/spark_cast.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/cast/spark_pandas_cast.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/cast/spark_polars_cast.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/file_format.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/python_arrow.py +0 -0
- {ygg-0.1.54 → ygg-0.1.55}/src/yggdrasil/types/python_defaults.py +0 -0
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "ygg"
|
|
8
|
-
version = "0.1.
|
|
8
|
+
version = "0.1.55"
|
|
9
9
|
description = "Type-friendly utilities for moving data between Python objects, Arrow, Polars, Pandas, Spark, and Databricks"
|
|
10
10
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
11
11
|
license = { file = "LICENSE" }
|
|
@@ -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 ""
|
|
@@ -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.
|
|
655
656
|
cluster_id: Optional cluster id.
|
|
656
657
|
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,
|
|
665
|
+
workspace=self if workspace is None else workspace,
|
|
666
666
|
cluster_id=cluster_id,
|
|
667
667
|
cluster_name=cluster_name,
|
|
668
668
|
)
|
|
@@ -671,10 +671,19 @@ 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
|
+
"""
|
|
674
683
|
from ..ai.loki import Loki
|
|
675
684
|
|
|
676
685
|
return Loki(
|
|
677
|
-
workspace=self,
|
|
686
|
+
workspace=self if workspace is None else workspace,
|
|
678
687
|
)
|
|
679
688
|
|
|
680
689
|
# ---------------------------------------------------------------------------
|
|
@@ -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
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.55"
|
|
File without changes
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
from typing import Optional
|
|
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_openai_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_openai_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
|
-
_openai_client: Optional[OpenAI] = field(repr=False, hash=False, default=None)
|
|
42
|
-
|
|
43
|
-
@property
|
|
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
|
-
|
|
49
|
-
def make_openai_client(self):
|
|
50
|
-
return make_openai_client(
|
|
51
|
-
api_key=self.workspace.current_token(),
|
|
52
|
-
base_url=self.workspace.host + "/serving-endpoints"
|
|
53
|
-
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.54"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|