ygg 0.1.39__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ygg
3
- Version: 0.1.39
3
+ Version: 0.1.41
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
@@ -1,9 +1,9 @@
1
- ygg-0.1.39.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
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=CJmriEgb-Ey3LByW34C3xKdLEpasYF_SIpGuURosS7U,22
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=mnNzjCx7X3iK22oZ7K3pqot0AXq9JTdg97kT61j2_UU,40729
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
@@ -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=euY7Kiy04i1tpWKuB0b2qQ1FokLC3nq0cv7PObWYUBE,21809
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.39.dist-info/METADATA,sha256=RfbFhLCQfG6s5EO95X0zwf40BZ3SatH5rF5FfoTdIxE,19204
59
- ygg-0.1.39.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
60
- ygg-0.1.39.dist-info/entry_points.txt,sha256=6q-vpWG3kvw2dhctQ0LALdatoeefkN855Ev02I1dKGY,70
61
- ygg-0.1.39.dist-info/top_level.txt,sha256=iBe9Kk4VIVbLpgv_p8OZUIfxgj4dgJ5wBg6vO3rigso,10
62
- ygg-0.1.39.dist-info/RECORD,,
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
- self.details = self.clusters_client().edit(**update_details)
703
- self.wait_for_status()
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
  ):
@@ -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
- call_payload_b64 = base64.b64encode(
563
- dill.dumps((args, kwargs), recurse=True)
564
- ).decode("ascii")
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
- args, kwargs = dill.loads(base64.b64decode(__CALL_PAYLOAD_B64__))
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.39"
1
+ __version__ = "0.1.41"
File without changes