ygg 0.1.51__py3-none-any.whl → 0.1.52__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.51.dist-info → ygg-0.1.52.dist-info}/METADATA +1 -1
- {ygg-0.1.51.dist-info → ygg-0.1.52.dist-info}/RECORD +18 -16
- yggdrasil/databricks/sql/engine.py +288 -84
- yggdrasil/databricks/sql/exceptions.py +3 -1
- yggdrasil/databricks/workspaces/io.py +78 -69
- yggdrasil/databricks/workspaces/path.py +367 -166
- yggdrasil/databricks/workspaces/path_kind.py +3 -3
- yggdrasil/databricks/workspaces/volumes_path.py +85 -0
- yggdrasil/libs/databrickslib.py +5 -0
- yggdrasil/pyutils/callable_serde.py +10 -10
- yggdrasil/pyutils/retry.py +2 -2
- yggdrasil/types/cast/registry.py +0 -14
- yggdrasil/types/file_format.py +10 -0
- yggdrasil/version.py +1 -1
- {ygg-0.1.51.dist-info → ygg-0.1.52.dist-info}/WHEEL +0 -0
- {ygg-0.1.51.dist-info → ygg-0.1.52.dist-info}/entry_points.txt +0 -0
- {ygg-0.1.51.dist-info → ygg-0.1.52.dist-info}/licenses/LICENSE +0 -0
- {ygg-0.1.51.dist-info → ygg-0.1.52.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import datetime as dt
|
|
2
|
+
from typing import Tuple, Optional
|
|
3
|
+
|
|
4
|
+
from ...libs.databrickslib import databricks_sdk, WorkspaceClient
|
|
5
|
+
|
|
6
|
+
if databricks_sdk is not None:
|
|
7
|
+
from databricks.sdk.errors.platform import (
|
|
8
|
+
NotFound,
|
|
9
|
+
ResourceDoesNotExist,
|
|
10
|
+
BadRequest,
|
|
11
|
+
PermissionDenied,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"get_volume_status",
|
|
17
|
+
"get_volume_metadata"
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_volume_status(
|
|
22
|
+
sdk: WorkspaceClient,
|
|
23
|
+
full_path: str,
|
|
24
|
+
check_file_first: bool = True,
|
|
25
|
+
raise_error: bool = True,
|
|
26
|
+
) -> Tuple[Optional[bool], Optional[bool], Optional[int], Optional[dt.datetime]]:
|
|
27
|
+
client = sdk.files
|
|
28
|
+
|
|
29
|
+
if check_file_first:
|
|
30
|
+
try:
|
|
31
|
+
info = client.get_metadata(full_path)
|
|
32
|
+
return True, False, info.content_length, _parse_mtime(info)
|
|
33
|
+
except (NotFound, ResourceDoesNotExist, BadRequest, PermissionDenied) as e:
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
info = client.get_directory_metadata(full_path)
|
|
38
|
+
return False, True, 0, _parse_mtime(info)
|
|
39
|
+
except (NotFound, ResourceDoesNotExist, BadRequest, PermissionDenied) as e:
|
|
40
|
+
last_exception = e
|
|
41
|
+
else:
|
|
42
|
+
try:
|
|
43
|
+
info = client.get_directory_metadata(full_path)
|
|
44
|
+
return False, True, 0, _parse_mtime(info)
|
|
45
|
+
except (NotFound, ResourceDoesNotExist, BadRequest, PermissionDenied) as e:
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
info = client.get_metadata(full_path)
|
|
50
|
+
return True, False, info.content_length, _parse_mtime(info)
|
|
51
|
+
except (NotFound, ResourceDoesNotExist, BadRequest, PermissionDenied) as e:
|
|
52
|
+
last_exception = e
|
|
53
|
+
|
|
54
|
+
if raise_error and last_exception is not None:
|
|
55
|
+
raise last_exception
|
|
56
|
+
|
|
57
|
+
return None, None, None, None
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_volume_metadata(
|
|
61
|
+
sdk: WorkspaceClient,
|
|
62
|
+
full_name: str,
|
|
63
|
+
include_browse: bool = False,
|
|
64
|
+
raise_error: bool = True,
|
|
65
|
+
):
|
|
66
|
+
client = sdk.volumes
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
return client.read(
|
|
70
|
+
name=full_name,
|
|
71
|
+
include_browse=include_browse
|
|
72
|
+
)
|
|
73
|
+
except (NotFound, ResourceDoesNotExist, BadRequest, PermissionDenied):
|
|
74
|
+
if raise_error:
|
|
75
|
+
raise
|
|
76
|
+
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _parse_mtime(info):
|
|
82
|
+
if not info:
|
|
83
|
+
return dt.datetime.now(tz=dt.timezone.utc)
|
|
84
|
+
|
|
85
|
+
return dt.datetime.strptime(info.last_modified, "%a, %d %b %Y %H:%M:%S %Z").replace(tzinfo=dt.timezone.utc)
|
yggdrasil/libs/databrickslib.py
CHANGED
|
@@ -4,6 +4,8 @@ try:
|
|
|
4
4
|
import databricks
|
|
5
5
|
import databricks.sdk # type: ignore
|
|
6
6
|
|
|
7
|
+
from databricks.sdk import WorkspaceClient
|
|
8
|
+
|
|
7
9
|
databricks = databricks
|
|
8
10
|
databricks_sdk = databricks.sdk
|
|
9
11
|
except ImportError:
|
|
@@ -16,6 +18,8 @@ except ImportError:
|
|
|
16
18
|
databricks = _DatabricksDummy
|
|
17
19
|
databricks_sdk = _DatabricksDummy
|
|
18
20
|
|
|
21
|
+
WorkspaceClient = _DatabricksDummy
|
|
22
|
+
|
|
19
23
|
|
|
20
24
|
def require_databricks_sdk():
|
|
21
25
|
"""Ensure the Databricks SDK is available before use.
|
|
@@ -34,4 +38,5 @@ __all__ = [
|
|
|
34
38
|
"databricks",
|
|
35
39
|
"databricks_sdk",
|
|
36
40
|
"require_databricks_sdk",
|
|
41
|
+
"WorkspaceClient"
|
|
37
42
|
]
|
|
@@ -27,7 +27,6 @@ import dis
|
|
|
27
27
|
import importlib
|
|
28
28
|
import inspect
|
|
29
29
|
import io
|
|
30
|
-
import lzma
|
|
31
30
|
import os
|
|
32
31
|
import secrets
|
|
33
32
|
import struct
|
|
@@ -66,6 +65,14 @@ def _try_import_zstd():
|
|
|
66
65
|
return None
|
|
67
66
|
|
|
68
67
|
|
|
68
|
+
def _try_import_lzma():
|
|
69
|
+
try:
|
|
70
|
+
import lzma # type: ignore
|
|
71
|
+
return lzma
|
|
72
|
+
except Exception:
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
|
|
69
76
|
def _pick_zlib_level(n: int, limit: int) -> int:
|
|
70
77
|
"""Ramp compression level 1..9 based on how far we exceed the byte_limit."""
|
|
71
78
|
ratio = n / max(1, limit)
|
|
@@ -94,13 +101,6 @@ def _encode_with_candidates(raw: bytes, *, byte_limit: int, allow_zstd: bool) ->
|
|
|
94
101
|
except Exception:
|
|
95
102
|
pass
|
|
96
103
|
|
|
97
|
-
for preset in (6, 9):
|
|
98
|
-
try:
|
|
99
|
-
c = lzma.compress(raw, preset=preset)
|
|
100
|
-
candidates.append(_frame(_CODEC_LZMA, len(raw), preset, c))
|
|
101
|
-
except Exception:
|
|
102
|
-
pass
|
|
103
|
-
|
|
104
104
|
lvl = _pick_zlib_level(len(raw), byte_limit)
|
|
105
105
|
try:
|
|
106
106
|
c = zlib.compress(raw, lvl)
|
|
@@ -143,8 +143,8 @@ def _decode_result_blob(blob: bytes) -> bytes:
|
|
|
143
143
|
raw = data
|
|
144
144
|
elif codec == _CODEC_ZLIB:
|
|
145
145
|
raw = zlib.decompress(data)
|
|
146
|
-
elif codec == _CODEC_LZMA:
|
|
147
|
-
|
|
146
|
+
# elif codec == _CODEC_LZMA:
|
|
147
|
+
# raw = lzma.decompress(data)
|
|
148
148
|
elif codec == _CODEC_ZSTD:
|
|
149
149
|
zstd = _try_import_zstd()
|
|
150
150
|
if zstd is None:
|
yggdrasil/pyutils/retry.py
CHANGED
|
@@ -82,14 +82,14 @@ def retry(
|
|
|
82
82
|
logger:
|
|
83
83
|
Optional logger for debug/info messages.
|
|
84
84
|
reraise:
|
|
85
|
-
If True,
|
|
85
|
+
If True, reraise the last exception after exhausting retries or timeout.
|
|
86
86
|
If False, returns None after all retries fail or timeout is hit.
|
|
87
87
|
timeout:
|
|
88
88
|
Optional max total time in seconds across all attempts. The timeout is
|
|
89
89
|
checked after each failed attempt. In-flight attempts are not forcibly
|
|
90
90
|
cancelled; we just stop scheduling new retries when the timeout is hit.
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
Example
|
|
93
93
|
-----
|
|
94
94
|
@retry(exceptions=(ValueError,), tries=5, delay=0.1, backoff=2)
|
|
95
95
|
def flaky():
|
yggdrasil/types/cast/registry.py
CHANGED
|
@@ -68,20 +68,6 @@ def register_converter(
|
|
|
68
68
|
Returns:
|
|
69
69
|
Registered converter.
|
|
70
70
|
"""
|
|
71
|
-
sig = inspect.signature(func)
|
|
72
|
-
params = list(sig.parameters.values())
|
|
73
|
-
if any(
|
|
74
|
-
param.kind in {inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD}
|
|
75
|
-
for param in params
|
|
76
|
-
):
|
|
77
|
-
raise TypeError(
|
|
78
|
-
"Converters must accept exactly two positional arguments: (value, options)"
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
if len(params) < 2:
|
|
82
|
-
raise TypeError(
|
|
83
|
-
"Converters must accept at least two positional arguments: (value, options)"
|
|
84
|
-
)
|
|
85
71
|
|
|
86
72
|
if from_hint in (Any, object):
|
|
87
73
|
_any_registry[to_hint] = func
|
yggdrasil/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.52"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|