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.
Files changed (68) hide show
  1. {ygg-0.1.39 → ygg-0.1.42}/PKG-INFO +1 -1
  2. {ygg-0.1.39 → ygg-0.1.42}/pyproject.toml +1 -1
  3. {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/PKG-INFO +1 -1
  4. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/compute/cluster.py +12 -5
  5. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/compute/execution_context.py +13 -5
  6. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/callable_serde.py +47 -5
  7. ygg-0.1.42/src/yggdrasil/version.py +1 -0
  8. ygg-0.1.39/src/yggdrasil/version.py +0 -1
  9. {ygg-0.1.39 → ygg-0.1.42}/LICENSE +0 -0
  10. {ygg-0.1.39 → ygg-0.1.42}/README.md +0 -0
  11. {ygg-0.1.39 → ygg-0.1.42}/setup.cfg +0 -0
  12. {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/SOURCES.txt +0 -0
  13. {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/dependency_links.txt +0 -0
  14. {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/entry_points.txt +0 -0
  15. {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/requires.txt +0 -0
  16. {ygg-0.1.39 → ygg-0.1.42}/src/ygg.egg-info/top_level.txt +0 -0
  17. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/__init__.py +0 -0
  18. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/__init__.py +0 -0
  19. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/compute/__init__.py +0 -0
  20. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/compute/remote.py +0 -0
  21. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/jobs/__init__.py +0 -0
  22. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/jobs/config.py +0 -0
  23. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/sql/__init__.py +0 -0
  24. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/sql/engine.py +0 -0
  25. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/sql/exceptions.py +0 -0
  26. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/sql/statement_result.py +0 -0
  27. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/sql/types.py +0 -0
  28. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/__init__.py +0 -0
  29. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/filesytem.py +0 -0
  30. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/io.py +0 -0
  31. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/path.py +0 -0
  32. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/path_kind.py +0 -0
  33. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/databricks/workspaces/workspace.py +0 -0
  34. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/dataclasses/__init__.py +0 -0
  35. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/dataclasses/dataclass.py +0 -0
  36. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/__init__.py +0 -0
  37. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/databrickslib.py +0 -0
  38. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/extensions/__init__.py +0 -0
  39. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/extensions/polars_extensions.py +0 -0
  40. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/extensions/spark_extensions.py +0 -0
  41. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/pandaslib.py +0 -0
  42. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/polarslib.py +0 -0
  43. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/libs/sparklib.py +0 -0
  44. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/__init__.py +0 -0
  45. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/equality.py +0 -0
  46. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/exceptions.py +0 -0
  47. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/expiring_dict.py +0 -0
  48. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/modules.py +0 -0
  49. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/parallel.py +0 -0
  50. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/python_env.py +0 -0
  51. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/pyutils/retry.py +0 -0
  52. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/requests/__init__.py +0 -0
  53. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/requests/msal.py +0 -0
  54. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/requests/session.py +0 -0
  55. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/__init__.py +0 -0
  56. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/__init__.py +0 -0
  57. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/arrow_cast.py +0 -0
  58. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/cast_options.py +0 -0
  59. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/pandas_cast.py +0 -0
  60. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/polars_cast.py +0 -0
  61. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/polars_pandas_cast.py +0 -0
  62. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/registry.py +0 -0
  63. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/spark_cast.py +0 -0
  64. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/spark_pandas_cast.py +0 -0
  65. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/cast/spark_polars_cast.py +0 -0
  66. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/libs.py +0 -0
  67. {ygg-0.1.39 → ygg-0.1.42}/src/yggdrasil/types/python_arrow.py +0 -0
  68. {ygg-0.1.39 → ygg-0.1.42}/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.39
3
+ Version: 0.1.42
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ygg"
7
- version = "0.1.39"
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" }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ygg
3
- Version: 0.1.39
3
+ Version: 0.1.42
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
@@ -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
- self.details = self.clusters_client().edit(**update_details)
703
- self.wait_for_status()
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
- content = self.execute_command(
153
- command=cmd,
154
- result_tag="<<RESULT>>",
155
- print_stdout=False,
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
- 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)
@@ -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