ygg 0.1.39__tar.gz → 0.1.42__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.39 → ygg-0.1.42}/PKG-INFO +1 -1
- {ygg-0.1.39 → ygg-0.1.42}/pyproject.toml +1 -1
- {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/PKG-INFO +1 -1
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/compute/cluster.py +12 -5
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/compute/execution_context.py +13 -5
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/callable_serde.py +47 -5
- ygg-0.1.42/src/yggdrasil/version.py +1 -0
- ygg-0.1.39/src/yggdrasil/version.py +0 -1
- {ygg-0.1.39 → ygg-0.1.42}/LICENSE +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/README.md +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/setup.cfg +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/SOURCES.txt +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/dependency_links.txt +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/entry_points.txt +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/requires.txt +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/top_level.txt +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/compute/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/compute/remote.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/jobs/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/jobs/config.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/sql/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/sql/engine.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/sql/exceptions.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/sql/statement_result.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/sql/types.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/filesytem.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/io.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/path.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/path_kind.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/workspace.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/dataclasses/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/dataclasses/dataclass.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/databrickslib.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/extensions/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/extensions/polars_extensions.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/extensions/spark_extensions.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/pandaslib.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/polarslib.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/sparklib.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/equality.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/exceptions.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/expiring_dict.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/modules.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/parallel.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/python_env.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/retry.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/requests/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/requests/msal.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/requests/session.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/__init__.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/arrow_cast.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/cast_options.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/pandas_cast.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/polars_cast.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/polars_pandas_cast.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/registry.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/spark_cast.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/spark_pandas_cast.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/spark_polars_cast.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/libs.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/python_arrow.py +0 -0
- {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/python_defaults.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ygg"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.42"
|
|
8
8
|
description = "Type-friendly utilities for moving data between Python objects, Arrow, Polars, Pandas, Spark, and Databricks"
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -390,6 +390,8 @@ class Cluster(WorkspaceService):
|
|
|
390
390
|
|
|
391
391
|
sleep_time = min(max_sleep_time, sleep_time * backoff)
|
|
392
392
|
|
|
393
|
+
self.wait_installed_libraries()
|
|
394
|
+
|
|
393
395
|
self.raise_for_status()
|
|
394
396
|
|
|
395
397
|
return self
|
|
@@ -667,6 +669,8 @@ class Cluster(WorkspaceService):
|
|
|
667
669
|
Returns:
|
|
668
670
|
The updated Cluster instance.
|
|
669
671
|
"""
|
|
672
|
+
self.install_libraries(libraries=libraries, wait_timeout=None, raise_error=False)
|
|
673
|
+
|
|
670
674
|
existing_details = {
|
|
671
675
|
k: v
|
|
672
676
|
for k, v in self.details.as_shallow_dict().items()
|
|
@@ -699,16 +703,20 @@ class Cluster(WorkspaceService):
|
|
|
699
703
|
)
|
|
700
704
|
|
|
701
705
|
self.wait_for_status()
|
|
702
|
-
|
|
703
|
-
|
|
706
|
+
try:
|
|
707
|
+
self.details = self.clusters_client().edit_and_wait(**update_details)
|
|
708
|
+
except Exception as e:
|
|
709
|
+
if self.state == State.TERMINATED:
|
|
710
|
+
self.start()
|
|
711
|
+
self.details = self.clusters_client().edit_and_wait(**update_details)
|
|
712
|
+
else:
|
|
713
|
+
raise e
|
|
704
714
|
|
|
705
715
|
logger.info(
|
|
706
716
|
"Updated %s",
|
|
707
717
|
self
|
|
708
718
|
)
|
|
709
719
|
|
|
710
|
-
self.install_libraries(libraries=libraries, wait_timeout=None, raise_error=False)
|
|
711
|
-
|
|
712
720
|
return self
|
|
713
721
|
|
|
714
722
|
def list_clusters(self) -> Iterator["Cluster"]:
|
|
@@ -816,7 +824,6 @@ class Cluster(WorkspaceService):
|
|
|
816
824
|
|
|
817
825
|
return self
|
|
818
826
|
|
|
819
|
-
@retry(tries=4)
|
|
820
827
|
def restart(
|
|
821
828
|
self,
|
|
822
829
|
):
|
|
@@ -149,11 +149,19 @@ meta["version_info"] = current_env.version_info
|
|
|
149
149
|
|
|
150
150
|
print(json.dumps(meta))"""
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
152
|
+
try:
|
|
153
|
+
content = self.execute_command(
|
|
154
|
+
command=cmd,
|
|
155
|
+
result_tag="<<RESULT>>",
|
|
156
|
+
print_stdout=False,
|
|
157
|
+
)
|
|
158
|
+
except ImportError:
|
|
159
|
+
self.cluster.wait_installed_libraries()
|
|
160
|
+
content = self.execute_command(
|
|
161
|
+
command=cmd,
|
|
162
|
+
result_tag="<<RESULT>>",
|
|
163
|
+
print_stdout=False,
|
|
164
|
+
)
|
|
157
165
|
|
|
158
166
|
self._remote_metadata = RemoteMetadata(**json.loads(content))
|
|
159
167
|
|
|
@@ -546,7 +546,15 @@ class CallableSerde:
|
|
|
546
546
|
Returns Python code string to execute in another interpreter.
|
|
547
547
|
Prints one line: "{result_tag}:{base64(blob)}"
|
|
548
548
|
where blob is raw dill bytes or framed+zlib.
|
|
549
|
+
|
|
550
|
+
Also compresses the input call payload (args/kwargs) using the same framing
|
|
551
|
+
scheme when it exceeds byte_limit.
|
|
549
552
|
"""
|
|
553
|
+
import base64
|
|
554
|
+
import json
|
|
555
|
+
import struct
|
|
556
|
+
import zlib
|
|
557
|
+
|
|
550
558
|
args = args or ()
|
|
551
559
|
kwargs = kwargs or {}
|
|
552
560
|
|
|
@@ -555,13 +563,32 @@ class CallableSerde:
|
|
|
555
563
|
dump_env=dump_env,
|
|
556
564
|
filter_used_globals=filter_used_globals,
|
|
557
565
|
env_keys=env_keys,
|
|
558
|
-
env_variables=env_variables
|
|
566
|
+
env_variables=env_variables,
|
|
559
567
|
)
|
|
560
568
|
serde_json = json.dumps(serde_dict, ensure_ascii=False)
|
|
561
569
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
570
|
+
# --- input payload compression (args/kwargs) ---
|
|
571
|
+
MAGIC = b"CS1"
|
|
572
|
+
FLAG_COMPRESSED = 1
|
|
573
|
+
|
|
574
|
+
def _pick_level(n: int, limit: int) -> int:
|
|
575
|
+
ratio = n / max(1, limit)
|
|
576
|
+
x = min(1.0, max(0.0, (ratio - 1.0) / 3.0))
|
|
577
|
+
return max(1, min(9, int(round(1 + 8 * x))))
|
|
578
|
+
|
|
579
|
+
def _encode_blob(raw: bytes, limit: int) -> bytes:
|
|
580
|
+
if len(raw) <= limit:
|
|
581
|
+
return raw
|
|
582
|
+
level = _pick_level(len(raw), limit)
|
|
583
|
+
compressed = zlib.compress(raw, level)
|
|
584
|
+
if len(compressed) >= len(raw):
|
|
585
|
+
return raw
|
|
586
|
+
header = MAGIC + struct.pack(">BIB", FLAG_COMPRESSED, len(raw), level)
|
|
587
|
+
return header + compressed
|
|
588
|
+
|
|
589
|
+
call_raw = dill.dumps((args, kwargs), recurse=True)
|
|
590
|
+
call_blob = _encode_blob(call_raw, int(byte_limit))
|
|
591
|
+
call_payload_b64 = base64.b64encode(call_blob).decode("ascii")
|
|
565
592
|
|
|
566
593
|
# NOTE: plain string template + replace. No f-string. No brace escaping.
|
|
567
594
|
template = r"""
|
|
@@ -595,6 +622,19 @@ def _encode_result(raw: bytes, byte_limit: int) -> bytes:
|
|
|
595
622
|
header = MAGIC + struct.pack(">BIB", FLAG_COMPRESSED, len(raw), level)
|
|
596
623
|
return header + compressed
|
|
597
624
|
|
|
625
|
+
def _decode_blob(blob: bytes) -> bytes:
|
|
626
|
+
# If it's framed (MAGIC + header), decompress; else return as-is.
|
|
627
|
+
if isinstance(blob, (bytes, bytearray)) and len(blob) >= 3 and blob[:3] == MAGIC:
|
|
628
|
+
if len(blob) >= 3 + 6:
|
|
629
|
+
flag, orig_len, level = struct.unpack(">BIB", blob[3:3+6])
|
|
630
|
+
if flag & FLAG_COMPRESSED:
|
|
631
|
+
raw = zlib.decompress(blob[3+6:])
|
|
632
|
+
# best-effort sanity check; don't hard-fail on mismatch
|
|
633
|
+
if isinstance(orig_len, int) and orig_len > 0 and len(raw) != orig_len:
|
|
634
|
+
return raw
|
|
635
|
+
return raw
|
|
636
|
+
return blob
|
|
637
|
+
|
|
598
638
|
def _needed_globals(fn) -> set[str]:
|
|
599
639
|
names = set()
|
|
600
640
|
try:
|
|
@@ -657,7 +697,9 @@ if env_b64:
|
|
|
657
697
|
meta = serde.get("env_meta") or {}
|
|
658
698
|
_apply_env(fn, env, bool(meta.get("filter_used_globals", True)))
|
|
659
699
|
|
|
660
|
-
|
|
700
|
+
call_blob = base64.b64decode(__CALL_PAYLOAD_B64__)
|
|
701
|
+
call_raw = _decode_blob(call_blob)
|
|
702
|
+
args, kwargs = dill.loads(call_raw)
|
|
661
703
|
|
|
662
704
|
res = fn(*args, **kwargs)
|
|
663
705
|
raw = dill.dumps(res, recurse=True)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.42"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.39"
|
|
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
|