ygg 0.1.55__tar.gz → 0.1.57__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.
Files changed (74) hide show
  1. {ygg-0.1.55 → ygg-0.1.57}/PKG-INFO +1 -1
  2. {ygg-0.1.55 → ygg-0.1.57}/pyproject.toml +1 -1
  3. {ygg-0.1.55 → ygg-0.1.57}/src/ygg.egg-info/PKG-INFO +1 -1
  4. ygg-0.1.57/src/yggdrasil/databricks/ai/__init__.py +0 -0
  5. ygg-0.1.57/src/yggdrasil/databricks/ai/loki.py +53 -0
  6. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/workspaces/io.py +3 -0
  7. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/workspaces/workspace.py +3 -12
  8. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/pyutils/__init__.py +2 -0
  9. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/pyutils/python_env.py +1 -1
  10. ygg-0.1.57/src/yggdrasil/version.py +1 -0
  11. ygg-0.1.55/src/yggdrasil/databricks/ai/__init__.py +0 -1
  12. ygg-0.1.55/src/yggdrasil/databricks/ai/loki.py +0 -122
  13. ygg-0.1.55/src/yggdrasil/version.py +0 -1
  14. {ygg-0.1.55 → ygg-0.1.57}/LICENSE +0 -0
  15. {ygg-0.1.55 → ygg-0.1.57}/README.md +0 -0
  16. {ygg-0.1.55 → ygg-0.1.57}/setup.cfg +0 -0
  17. {ygg-0.1.55 → ygg-0.1.57}/src/ygg.egg-info/SOURCES.txt +0 -0
  18. {ygg-0.1.55 → ygg-0.1.57}/src/ygg.egg-info/dependency_links.txt +0 -0
  19. {ygg-0.1.55 → ygg-0.1.57}/src/ygg.egg-info/entry_points.txt +0 -0
  20. {ygg-0.1.55 → ygg-0.1.57}/src/ygg.egg-info/requires.txt +0 -0
  21. {ygg-0.1.55 → ygg-0.1.57}/src/ygg.egg-info/top_level.txt +0 -0
  22. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/__init__.py +0 -0
  23. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/__init__.py +0 -0
  24. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/compute/__init__.py +0 -0
  25. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/compute/cluster.py +0 -0
  26. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/compute/execution_context.py +0 -0
  27. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/compute/remote.py +0 -0
  28. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/jobs/__init__.py +0 -0
  29. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/jobs/config.py +0 -0
  30. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/sql/__init__.py +0 -0
  31. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/sql/engine.py +0 -0
  32. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/sql/exceptions.py +0 -0
  33. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/sql/statement_result.py +0 -0
  34. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/sql/types.py +0 -0
  35. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/sql/warehouse.py +0 -0
  36. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/workspaces/__init__.py +0 -0
  37. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/workspaces/filesytem.py +0 -0
  38. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/workspaces/path.py +0 -0
  39. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/workspaces/path_kind.py +0 -0
  40. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/databricks/workspaces/volumes_path.py +0 -0
  41. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/dataclasses/__init__.py +0 -0
  42. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/dataclasses/dataclass.py +0 -0
  43. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/libs/__init__.py +0 -0
  44. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/libs/databrickslib.py +0 -0
  45. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/libs/extensions/__init__.py +0 -0
  46. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/libs/extensions/polars_extensions.py +0 -0
  47. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/libs/extensions/spark_extensions.py +0 -0
  48. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/libs/pandaslib.py +0 -0
  49. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/libs/polarslib.py +0 -0
  50. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/libs/sparklib.py +0 -0
  51. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/pyutils/callable_serde.py +0 -0
  52. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/pyutils/equality.py +0 -0
  53. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/pyutils/exceptions.py +0 -0
  54. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/pyutils/expiring_dict.py +0 -0
  55. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/pyutils/modules.py +0 -0
  56. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/pyutils/parallel.py +0 -0
  57. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/pyutils/retry.py +0 -0
  58. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/requests/__init__.py +0 -0
  59. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/requests/msal.py +0 -0
  60. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/requests/session.py +0 -0
  61. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/__init__.py +0 -0
  62. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/cast/__init__.py +0 -0
  63. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/cast/arrow_cast.py +0 -0
  64. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/cast/cast_options.py +0 -0
  65. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/cast/pandas_cast.py +0 -0
  66. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/cast/polars_cast.py +0 -0
  67. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/cast/polars_pandas_cast.py +0 -0
  68. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/cast/registry.py +0 -0
  69. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/cast/spark_cast.py +0 -0
  70. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/cast/spark_pandas_cast.py +0 -0
  71. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/cast/spark_polars_cast.py +0 -0
  72. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/file_format.py +0 -0
  73. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/python_arrow.py +0 -0
  74. {ygg-0.1.55 → ygg-0.1.57}/src/yggdrasil/types/python_defaults.py +0 -0
@@ -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
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "ygg"
8
- version = "0.1.55"
8
+ version = "0.1.57"
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" }
@@ -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
File without changes
@@ -0,0 +1,53 @@
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
+ )
@@ -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
 
@@ -0,0 +1 @@
1
+ __version__ = "0.1.57"
@@ -1 +0,0 @@
1
- from .loki import *
@@ -1,122 +0,0 @@
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 ""
@@ -1 +0,0 @@
1
- __version__ = "0.1.55"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes