ygg 0.1.38__py3-none-any.whl → 0.1.41__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.38.dist-info → ygg-0.1.41.dist-info}/METADATA +1 -1
- {ygg-0.1.38.dist-info → ygg-0.1.41.dist-info}/RECORD +10 -10
- yggdrasil/databricks/compute/cluster.py +10 -5
- yggdrasil/databricks/sql/statement_result.py +9 -5
- yggdrasil/pyutils/callable_serde.py +47 -5
- yggdrasil/version.py +1 -1
- {ygg-0.1.38.dist-info → ygg-0.1.41.dist-info}/WHEEL +0 -0
- {ygg-0.1.38.dist-info → ygg-0.1.41.dist-info}/entry_points.txt +0 -0
- {ygg-0.1.38.dist-info → ygg-0.1.41.dist-info}/licenses/LICENSE +0 -0
- {ygg-0.1.38.dist-info → ygg-0.1.41.dist-info}/top_level.txt +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
ygg-0.1.
|
|
1
|
+
ygg-0.1.41.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
2
2
|
yggdrasil/__init__.py,sha256=PfH7Xwt6uue6oqe6S5V8NhDJcVQClkKrBE1KXhdelZc,117
|
|
3
|
-
yggdrasil/version.py,sha256=
|
|
3
|
+
yggdrasil/version.py,sha256=MW_v7YHPKwbcPR_PtCE3ALJ0csFwgMewFF071yAYGCE,22
|
|
4
4
|
yggdrasil/databricks/__init__.py,sha256=skctY2c8W-hI81upx9F_PWRe5ishL3hrdiTuizgDjdw,152
|
|
5
5
|
yggdrasil/databricks/compute/__init__.py,sha256=NvdzmaJSNYY1uJthv1hHdBuNu3bD_-Z65DWnaJt9yXg,289
|
|
6
|
-
yggdrasil/databricks/compute/cluster.py,sha256=
|
|
6
|
+
yggdrasil/databricks/compute/cluster.py,sha256=Ejc3VlS56QzyjFX1-wNXHC4BNc2MpDRfFFafVxPF8rE,40968
|
|
7
7
|
yggdrasil/databricks/compute/execution_context.py,sha256=nxrNXoarq_JAB-Cpj0udHhq2jx-DmMbRWJdAezLrPis,22347
|
|
8
8
|
yggdrasil/databricks/compute/remote.py,sha256=nEN_Fr1Ouul_iKOf4B5QjEGscYAcl7nHjGsl2toRzrU,2874
|
|
9
9
|
yggdrasil/databricks/jobs/__init__.py,sha256=snxGSJb0M5I39v0y3IR-uEeSlZR248cQ_4DJ1sYs-h8,154
|
|
@@ -11,7 +11,7 @@ yggdrasil/databricks/jobs/config.py,sha256=9LGeHD04hbfy0xt8_6oobC4moKJh4_DTjZiK4
|
|
|
11
11
|
yggdrasil/databricks/sql/__init__.py,sha256=y1n5yg-drZ8QVZbEgznsRG24kdJSnFis9l2YfYCsaCM,234
|
|
12
12
|
yggdrasil/databricks/sql/engine.py,sha256=Azx3gKtWOMy3D9I2FhkLmpthZPWAJZ9iZkaDivmt_0s,41002
|
|
13
13
|
yggdrasil/databricks/sql/exceptions.py,sha256=Jqd_gT_VyPL8klJEHYEzpv5eHtmdY43WiQ7HZBaEqSk,53
|
|
14
|
-
yggdrasil/databricks/sql/statement_result.py,sha256=
|
|
14
|
+
yggdrasil/databricks/sql/statement_result.py,sha256=_mBolHae0AASfe1Tlld1KTXs-K4-oy9dniHDyR2ILYc,16736
|
|
15
15
|
yggdrasil/databricks/sql/types.py,sha256=5G-BM9_eOsRKEMzeDTWUsWW5g4Idvs-czVCpOCrMhdA,6412
|
|
16
16
|
yggdrasil/databricks/workspaces/__init__.py,sha256=Ti1I99JTC3koYJaCy8WYvkAox4KdcuMRk8b2rHroWCY,133
|
|
17
17
|
yggdrasil/databricks/workspaces/filesytem.py,sha256=Z8JXU7_XUEbw9fpTQT1avRQKi-IAP2KemXBMPkUoY4w,9805
|
|
@@ -30,7 +30,7 @@ yggdrasil/libs/extensions/__init__.py,sha256=mcXW5Li3Cbprbs4Ci-b5A0Ju0wmLcfvEiFu
|
|
|
30
30
|
yggdrasil/libs/extensions/polars_extensions.py,sha256=RTkGi8llhPJjX7x9egix7-yXWo2X24zIAPSKXV37SSA,12397
|
|
31
31
|
yggdrasil/libs/extensions/spark_extensions.py,sha256=E64n-3SFTDgMuXwWitX6vOYP9ln2lpGKb0htoBLEZgc,16745
|
|
32
32
|
yggdrasil/pyutils/__init__.py,sha256=tl-LapAc71TV7RMgf2ftKwrzr8iiLOGHeJgA3RvO93w,293
|
|
33
|
-
yggdrasil/pyutils/callable_serde.py,sha256=
|
|
33
|
+
yggdrasil/pyutils/callable_serde.py,sha256=FtbY2PUBHwDe2IyX28gLJwQYjtrvhvqtTSIIBc5x-dk,23538
|
|
34
34
|
yggdrasil/pyutils/equality.py,sha256=Xyf8D1dLUCm3spDEir8Zyj7O4US_fBJwEylJCfJ9slI,3080
|
|
35
35
|
yggdrasil/pyutils/exceptions.py,sha256=ssKNm-rjhavHUOZmGA7_1Gq9tSHDrb2EFI-cnBuWgng,3388
|
|
36
36
|
yggdrasil/pyutils/expiring_dict.py,sha256=q9gb09-2EUN-jQZumUw5BXOQGYcj1wb85qKtQlciSxg,5825
|
|
@@ -55,8 +55,8 @@ yggdrasil/types/cast/registry.py,sha256=_zdFGmUBB7P-e_LIcJlOxMcxAkXoA-UXB6HqLMgT
|
|
|
55
55
|
yggdrasil/types/cast/spark_cast.py,sha256=_KAsl1DqmKMSfWxqhVE7gosjYdgiL1C5bDQv6eP3HtA,24926
|
|
56
56
|
yggdrasil/types/cast/spark_pandas_cast.py,sha256=BuTiWrdCANZCdD_p2MAytqm74eq-rdRXd-LGojBRrfU,5023
|
|
57
57
|
yggdrasil/types/cast/spark_polars_cast.py,sha256=btmZNHXn2NSt3fUuB4xg7coaE0RezIBdZD92H8NK0Jw,9073
|
|
58
|
-
ygg-0.1.
|
|
59
|
-
ygg-0.1.
|
|
60
|
-
ygg-0.1.
|
|
61
|
-
ygg-0.1.
|
|
62
|
-
ygg-0.1.
|
|
58
|
+
ygg-0.1.41.dist-info/METADATA,sha256=EYXc8625quuP-JkcUD5FIK-5AmgYMddSWj2t4mnN2bg,19204
|
|
59
|
+
ygg-0.1.41.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
60
|
+
ygg-0.1.41.dist-info/entry_points.txt,sha256=6q-vpWG3kvw2dhctQ0LALdatoeefkN855Ev02I1dKGY,70
|
|
61
|
+
ygg-0.1.41.dist-info/top_level.txt,sha256=iBe9Kk4VIVbLpgv_p8OZUIfxgj4dgJ5wBg6vO3rigso,10
|
|
62
|
+
ygg-0.1.41.dist-info/RECORD,,
|
|
@@ -667,6 +667,8 @@ class Cluster(WorkspaceService):
|
|
|
667
667
|
Returns:
|
|
668
668
|
The updated Cluster instance.
|
|
669
669
|
"""
|
|
670
|
+
self.install_libraries(libraries=libraries, wait_timeout=None, raise_error=False)
|
|
671
|
+
|
|
670
672
|
existing_details = {
|
|
671
673
|
k: v
|
|
672
674
|
for k, v in self.details.as_shallow_dict().items()
|
|
@@ -699,16 +701,20 @@ class Cluster(WorkspaceService):
|
|
|
699
701
|
)
|
|
700
702
|
|
|
701
703
|
self.wait_for_status()
|
|
702
|
-
|
|
703
|
-
|
|
704
|
+
try:
|
|
705
|
+
self.details = self.clusters_client().edit_and_wait(**update_details)
|
|
706
|
+
except Exception as e:
|
|
707
|
+
if self.state == State.TERMINATED:
|
|
708
|
+
self.start()
|
|
709
|
+
self.details = self.clusters_client().edit_and_wait(**update_details)
|
|
710
|
+
else:
|
|
711
|
+
raise e
|
|
704
712
|
|
|
705
713
|
logger.info(
|
|
706
714
|
"Updated %s",
|
|
707
715
|
self
|
|
708
716
|
)
|
|
709
717
|
|
|
710
|
-
self.install_libraries(libraries=libraries, wait_timeout=None, raise_error=False)
|
|
711
|
-
|
|
712
718
|
return self
|
|
713
719
|
|
|
714
720
|
def list_clusters(self) -> Iterator["Cluster"]:
|
|
@@ -816,7 +822,6 @@ class Cluster(WorkspaceService):
|
|
|
816
822
|
|
|
817
823
|
return self
|
|
818
824
|
|
|
819
|
-
@retry(tries=4)
|
|
820
825
|
def restart(
|
|
821
826
|
self,
|
|
822
827
|
):
|
|
@@ -195,6 +195,7 @@ class StatementResult:
|
|
|
195
195
|
Returns:
|
|
196
196
|
The result manifest or None for Spark SQL results.
|
|
197
197
|
"""
|
|
198
|
+
self.wait()
|
|
198
199
|
return self.response.manifest
|
|
199
200
|
|
|
200
201
|
@property
|
|
@@ -204,6 +205,7 @@ class StatementResult:
|
|
|
204
205
|
Returns:
|
|
205
206
|
The statement result payload from the API.
|
|
206
207
|
"""
|
|
208
|
+
self.wait()
|
|
207
209
|
return self.response.result
|
|
208
210
|
|
|
209
211
|
@property
|
|
@@ -253,7 +255,6 @@ class StatementResult:
|
|
|
253
255
|
self, self.disposition, Disposition.EXTERNAL_LINKS
|
|
254
256
|
)
|
|
255
257
|
|
|
256
|
-
self.wait()
|
|
257
258
|
result_data = self.result
|
|
258
259
|
wsdk = self.workspace.sdk()
|
|
259
260
|
|
|
@@ -320,6 +321,8 @@ class StatementResult:
|
|
|
320
321
|
f"Statement {self.statement_id} {self.state}: " + " | ".join(parts)
|
|
321
322
|
)
|
|
322
323
|
|
|
324
|
+
return self
|
|
325
|
+
|
|
323
326
|
def wait(
|
|
324
327
|
self,
|
|
325
328
|
timeout: Optional[int] = None,
|
|
@@ -339,20 +342,21 @@ class StatementResult:
|
|
|
339
342
|
|
|
340
343
|
start = time.time()
|
|
341
344
|
poll_interval = poll_interval or 1
|
|
342
|
-
current = self
|
|
343
345
|
|
|
344
346
|
while not self.done:
|
|
345
347
|
# still running / queued / pending
|
|
346
348
|
if timeout is not None and (time.time() - start) > timeout:
|
|
347
349
|
raise TimeoutError(
|
|
348
|
-
f"Statement {
|
|
349
|
-
f"(last state={
|
|
350
|
+
f"Statement {self.statement_id} did not finish within {timeout} seconds "
|
|
351
|
+
f"(last state={self.state})"
|
|
350
352
|
)
|
|
351
353
|
|
|
352
354
|
poll_interval = max(10, poll_interval * 1.2)
|
|
353
355
|
time.sleep(poll_interval)
|
|
354
356
|
|
|
355
|
-
|
|
357
|
+
self.raise_for_status()
|
|
358
|
+
|
|
359
|
+
return self
|
|
356
360
|
|
|
357
361
|
def arrow_schema(self):
|
|
358
362
|
"""Return the Arrow schema for the result.
|
|
@@ -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)
|
yggdrasil/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.41"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|