konduktor-nightly 0.1.0.dev20250409105017__py3-none-any.whl → 0.1.0.dev20250410104738__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.
- konduktor/__init__.py +2 -2
- konduktor/adaptors/aws.py +221 -0
- konduktor/cli.py +3 -4
- konduktor/data/aws/__init__.py +15 -0
- konduktor/data/aws/s3.py +1114 -0
- konduktor/data/data_utils.py +46 -1
- konduktor/data/registry.py +2 -1
- konduktor/data/storage.py +22 -8
- konduktor/task.py +13 -0
- konduktor/templates/pod.yaml.j2 +5 -1
- konduktor/utils/common_utils.py +29 -0
- {konduktor_nightly-0.1.0.dev20250409105017.dist-info → konduktor_nightly-0.1.0.dev20250410104738.dist-info}/METADATA +5 -1
- {konduktor_nightly-0.1.0.dev20250409105017.dist-info → konduktor_nightly-0.1.0.dev20250410104738.dist-info}/RECORD +16 -13
- {konduktor_nightly-0.1.0.dev20250409105017.dist-info → konduktor_nightly-0.1.0.dev20250410104738.dist-info}/LICENSE +0 -0
- {konduktor_nightly-0.1.0.dev20250409105017.dist-info → konduktor_nightly-0.1.0.dev20250410104738.dist-info}/WHEEL +0 -0
- {konduktor_nightly-0.1.0.dev20250409105017.dist-info → konduktor_nightly-0.1.0.dev20250410104738.dist-info}/entry_points.txt +0 -0
konduktor/data/data_utils.py
CHANGED
@@ -16,7 +16,7 @@ from multiprocessing import pool
|
|
16
16
|
from typing import Any, Callable, Dict, List, Optional, Tuple
|
17
17
|
|
18
18
|
from konduktor import logging
|
19
|
-
from konduktor.adaptors import gcp
|
19
|
+
from konduktor.adaptors import aws, gcp
|
20
20
|
from konduktor.utils import exceptions, log_utils, ux_utils
|
21
21
|
|
22
22
|
Client = Any
|
@@ -36,6 +36,30 @@ def split_gcs_path(gcs_path: str) -> Tuple[str, str]:
|
|
36
36
|
return bucket, key
|
37
37
|
|
38
38
|
|
39
|
+
def split_s3_path(s3_path: str) -> Tuple[str, str]:
|
40
|
+
"""Splits S3 Path into Bucket name and Relative Path to Bucket
|
41
|
+
|
42
|
+
Args:
|
43
|
+
s3_path: str; S3 Path, e.g. s3://imagenet/train/
|
44
|
+
"""
|
45
|
+
path_parts = s3_path.replace('s3://', '').split('/')
|
46
|
+
bucket = path_parts.pop(0)
|
47
|
+
key = '/'.join(path_parts)
|
48
|
+
return bucket, key
|
49
|
+
|
50
|
+
|
51
|
+
def create_s3_client(region: Optional[str] = None) -> Client:
|
52
|
+
"""Helper method that connects to Boto3 client for S3 Bucket
|
53
|
+
|
54
|
+
Args:
|
55
|
+
region: str; Region name, e.g. us-west-1, us-east-2. If None, default
|
56
|
+
region us-east-1 is used.
|
57
|
+
"""
|
58
|
+
if region is None:
|
59
|
+
region = 'us-east-1'
|
60
|
+
return aws.client('s3', region_name=region)
|
61
|
+
|
62
|
+
|
39
63
|
def verify_gcs_bucket(name: str) -> bool:
|
40
64
|
"""Helper method that checks if the GCS bucket exists
|
41
65
|
|
@@ -49,6 +73,27 @@ def verify_gcs_bucket(name: str) -> bool:
|
|
49
73
|
return False
|
50
74
|
|
51
75
|
|
76
|
+
def verify_s3_bucket(name: str) -> bool:
|
77
|
+
"""Helper method that checks if the S3 bucket exists
|
78
|
+
|
79
|
+
Args:
|
80
|
+
name: str; Name of the S3 Bucket (without s3:// prefix)
|
81
|
+
"""
|
82
|
+
import boto3
|
83
|
+
from botocore.exceptions import ClientError
|
84
|
+
|
85
|
+
s3 = boto3.client('s3')
|
86
|
+
try:
|
87
|
+
s3.head_bucket(Bucket=name)
|
88
|
+
return True
|
89
|
+
except ClientError as e:
|
90
|
+
error_code = int(e.response['Error']['Code'])
|
91
|
+
if error_code == 404:
|
92
|
+
return False
|
93
|
+
# In case of permissions issues or other errors, you can log and assume False
|
94
|
+
return False
|
95
|
+
|
96
|
+
|
52
97
|
def is_cloud_store_url(url):
|
53
98
|
result = urllib.parse.urlsplit(url)
|
54
99
|
# '' means non-cloud URLs.
|
konduktor/data/registry.py
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
+
from konduktor.data.aws import S3CloudStorage
|
1
2
|
from konduktor.data.gcp import GcsCloudStorage
|
2
3
|
|
3
4
|
# Maps bucket's URIs prefix(scheme) to its corresponding storage class
|
4
5
|
|
5
6
|
_REGISTRY = {
|
6
7
|
'gs': GcsCloudStorage(),
|
8
|
+
's3': S3CloudStorage(),
|
7
9
|
# TODO(asaiacai): Add other cloud stores here
|
8
|
-
# 's3': S3CloudStorage(),
|
9
10
|
# 'r2': R2CloudStorage(),
|
10
11
|
# 'cos': IBMCosCloudStorage(),
|
11
12
|
# 'oci': OciCloudStorage(),
|
konduktor/data/storage.py
CHANGED
@@ -28,7 +28,7 @@ import urllib.parse
|
|
28
28
|
from typing import Any, Dict, List, Literal, Optional, Tuple, Type, Union
|
29
29
|
|
30
30
|
from konduktor import check, config, logging
|
31
|
-
from konduktor.data import constants, data_utils, gcp, registry, storage_utils
|
31
|
+
from konduktor.data import aws, constants, data_utils, gcp, registry, storage_utils
|
32
32
|
from konduktor.utils import annotations, common_utils, exceptions, schemas, ux_utils
|
33
33
|
|
34
34
|
logger = logging.get_logger(__file__)
|
@@ -79,12 +79,15 @@ class StoreType(enum.Enum):
|
|
79
79
|
"""Enum for the different types of stores."""
|
80
80
|
|
81
81
|
GCS = 'GCS'
|
82
|
+
S3 = 'S3'
|
82
83
|
|
83
84
|
@classmethod
|
84
85
|
def from_cloud(cls, cloud: str) -> 'StoreType':
|
85
86
|
# these need to match the cloud store classes in konduktor/cloud_stores.py
|
86
87
|
if cloud.lower() == 'gs':
|
87
88
|
return StoreType.GCS
|
89
|
+
elif cloud.lower() == 's3':
|
90
|
+
return StoreType.S3
|
88
91
|
else:
|
89
92
|
with ux_utils.print_exception_no_traceback():
|
90
93
|
raise ValueError(f'Unknown cloud: {cloud}')
|
@@ -93,6 +96,8 @@ class StoreType(enum.Enum):
|
|
93
96
|
def from_store(cls, store: 'storage_utils.AbstractStore') -> 'StoreType':
|
94
97
|
if store.__repr__() == 'GcsStore':
|
95
98
|
return StoreType.GCS
|
99
|
+
elif store.__repr__() == 'S3Store':
|
100
|
+
return StoreType.S3
|
96
101
|
else:
|
97
102
|
with ux_utils.print_exception_no_traceback():
|
98
103
|
raise ValueError(f'Unknown store type: {store}')
|
@@ -100,6 +105,8 @@ class StoreType(enum.Enum):
|
|
100
105
|
def store_prefix(self) -> str:
|
101
106
|
if self == StoreType.GCS:
|
102
107
|
return 'gs://'
|
108
|
+
elif self == StoreType.S3:
|
109
|
+
return 's3://'
|
103
110
|
else:
|
104
111
|
with ux_utils.print_exception_no_traceback():
|
105
112
|
raise ValueError(f'Unknown store type: {self}')
|
@@ -123,6 +130,8 @@ class StoreType(enum.Enum):
|
|
123
130
|
if store_url.startswith(store_type.store_prefix()):
|
124
131
|
if store_type == StoreType.GCS:
|
125
132
|
bucket_name, sub_path = data_utils.split_gcs_path(store_url)
|
133
|
+
elif store_type == StoreType.S3:
|
134
|
+
bucket_name, sub_path = data_utils.split_s3_path(store_url)
|
126
135
|
return store_type, bucket_name, sub_path, storage_account_name, region
|
127
136
|
raise ValueError(f'Unknown store URL: {store_url}')
|
128
137
|
|
@@ -143,7 +152,7 @@ class StoreType(enum.Enum):
|
|
143
152
|
|
144
153
|
|
145
154
|
# this should match the above StoreType enum
|
146
|
-
STORE_TYPES = Literal[StoreType.GCS]
|
155
|
+
STORE_TYPES = Literal[StoreType.GCS, StoreType.S3]
|
147
156
|
|
148
157
|
|
149
158
|
class Storage(object):
|
@@ -310,6 +319,8 @@ class Storage(object):
|
|
310
319
|
if isinstance(self.source, str):
|
311
320
|
if self.source.startswith('gs://'):
|
312
321
|
self.add_store(StoreType.GCS)
|
322
|
+
elif self.source.startswith('s3://'):
|
323
|
+
self.add_store(StoreType.S3)
|
313
324
|
|
314
325
|
@staticmethod
|
315
326
|
def _validate_source(
|
@@ -533,12 +544,13 @@ class Storage(object):
|
|
533
544
|
# When initializing from global_user_state, we override the
|
534
545
|
# source from the YAML
|
535
546
|
try:
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
547
|
+
if s_type == StoreType.S3:
|
548
|
+
store = aws.S3Store.from_metadata(
|
549
|
+
s_metadata,
|
550
|
+
source=self.source,
|
551
|
+
sync_on_reconstruction=self.sync_on_reconstruction,
|
552
|
+
)
|
553
|
+
elif s_type == StoreType.GCS:
|
542
554
|
store = gcp.GcsStore.from_metadata(
|
543
555
|
s_metadata,
|
544
556
|
source=self.source,
|
@@ -622,6 +634,8 @@ class Storage(object):
|
|
622
634
|
store_cls: Type['storage_utils.AbstractStore']
|
623
635
|
if store_type == StoreType.GCS:
|
624
636
|
store_cls = gcp.GcsStore
|
637
|
+
elif store_type == StoreType.S3:
|
638
|
+
store_cls = aws.S3Store
|
625
639
|
else:
|
626
640
|
with ux_utils.print_exception_no_traceback():
|
627
641
|
raise exceptions.StorageSpecError(
|
konduktor/task.py
CHANGED
@@ -653,6 +653,19 @@ class Task:
|
|
653
653
|
if storage.mode == storage_lib.StorageMode.COPY:
|
654
654
|
store_type = storage_plans[storage]
|
655
655
|
# TODO(asaiacai): add back other stores here
|
656
|
+
elif store_type is storage_lib.StoreType.S3:
|
657
|
+
if isinstance(storage.source, str) and storage.source.startswith(
|
658
|
+
's3://'
|
659
|
+
):
|
660
|
+
blob_path = storage.source
|
661
|
+
else:
|
662
|
+
assert storage.name is not None, storage
|
663
|
+
blob_path = 's3://' + storage.name
|
664
|
+
self.update_file_mounts(
|
665
|
+
{
|
666
|
+
mnt_path: blob_path,
|
667
|
+
}
|
668
|
+
)
|
656
669
|
elif store_type is storage_lib.StoreType.GCS:
|
657
670
|
if isinstance(storage.source, str) and storage.source.startswith(
|
658
671
|
'gs://'
|
konduktor/templates/pod.yaml.j2
CHANGED
@@ -79,7 +79,7 @@ kubernetes:
|
|
79
79
|
{% if 'curl' in run_cmd %}
|
80
80
|
PACKAGES="$PACKAGES curl";
|
81
81
|
{% endif %}
|
82
|
-
{% if 'gs' in mount_secrets %}
|
82
|
+
{% if 'gs' in mount_secrets or 's3' in mount_secrets %}
|
83
83
|
PACKAGES="$PACKAGES unzip wget";
|
84
84
|
{% endif %}
|
85
85
|
{% if 'git' in run_cmd %}
|
@@ -129,6 +129,10 @@ kubernetes:
|
|
129
129
|
$(prefix_cmd) echo "Unpacking GCP secret"
|
130
130
|
$(prefix_cmd) mkdir -p ~/.config
|
131
131
|
$(prefix_cmd) unzip /run/konduktor/gs-secret/gcpcredentials -d ~/.config/gcloud
|
132
|
+
{% elif secret_type == "s3" %}
|
133
|
+
$(prefix_cmd) echo "Unpacking AWS secret"
|
134
|
+
$(prefix_cmd) mkdir -p ~/.aws
|
135
|
+
$(prefix_cmd) unzip /run/konduktor/s3-secret/awscredentials -d ~/.aws
|
132
136
|
{% endif %}
|
133
137
|
{% endfor %}
|
134
138
|
end_epoch=$(date +%s);
|
konduktor/utils/common_utils.py
CHANGED
@@ -17,6 +17,7 @@ import getpass
|
|
17
17
|
import hashlib
|
18
18
|
import inspect
|
19
19
|
import os
|
20
|
+
import random
|
20
21
|
import re
|
21
22
|
import socket
|
22
23
|
import sys
|
@@ -391,3 +392,31 @@ def format_exception(
|
|
391
392
|
if use_bracket:
|
392
393
|
return f'[{class_fullname(e.__class__)}] {e}'
|
393
394
|
return f'{class_fullname(e.__class__)}: {e}'
|
395
|
+
|
396
|
+
|
397
|
+
class Backoff:
|
398
|
+
"""Exponential backoff with jittering."""
|
399
|
+
|
400
|
+
MULTIPLIER = 1.6
|
401
|
+
JITTER = 0.4
|
402
|
+
|
403
|
+
def __init__(self, initial_backoff: float = 5, max_backoff_factor: int = 5):
|
404
|
+
self._initial = True
|
405
|
+
self._backoff = 0.0
|
406
|
+
self._initial_backoff = initial_backoff
|
407
|
+
self._max_backoff = max_backoff_factor * self._initial_backoff
|
408
|
+
|
409
|
+
# https://github.com/grpc/grpc/blob/2d4f3c56001cd1e1f85734b2f7c5ce5f2797c38a/doc/connection-backoff.md
|
410
|
+
# https://github.com/grpc/grpc/blob/5fc3ff82032d0ebc4bf252a170ebe66aacf9ed9d/src/core/lib/backoff/backoff.cc
|
411
|
+
|
412
|
+
def current_backoff(self) -> float:
|
413
|
+
"""Backs off once and returns the current backoff in seconds."""
|
414
|
+
if self._initial:
|
415
|
+
self._initial = False
|
416
|
+
self._backoff = min(self._initial_backoff, self._max_backoff)
|
417
|
+
else:
|
418
|
+
self._backoff = min(self._backoff * self.MULTIPLIER, self._max_backoff)
|
419
|
+
self._backoff += random.uniform(
|
420
|
+
-self.JITTER * self._backoff, self.JITTER * self._backoff
|
421
|
+
)
|
422
|
+
return self._backoff
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: konduktor-nightly
|
3
|
-
Version: 0.1.0.
|
3
|
+
Version: 0.1.0.dev20250410104738
|
4
4
|
Summary: GPU Cluster Health Management
|
5
5
|
Author: Andrew Aikawa
|
6
6
|
Author-email: asai@berkeley.edu
|
@@ -10,6 +10,10 @@ Classifier: Programming Language :: Python :: 3.9
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
13
|
+
Provides-Extra: s3
|
14
|
+
Requires-Dist: awscli (>=1.32.84,<2.0.0) ; extra == "s3"
|
15
|
+
Requires-Dist: boto3 (>=1.34.84,<2.0.0) ; extra == "s3"
|
16
|
+
Requires-Dist: botocore (>=1.34.84,<2.0.0) ; extra == "s3"
|
13
17
|
Requires-Dist: click (>=8.1.7,<9.0.0)
|
14
18
|
Requires-Dist: colorama (>=0.4.6,<0.5.0)
|
15
19
|
Requires-Dist: filelock (>=3.18.0,<4.0.0)
|
@@ -1,5 +1,6 @@
|
|
1
|
-
konduktor/__init__.py,sha256=
|
1
|
+
konduktor/__init__.py,sha256=GTCKY5x_jINcGcz-nfNIu_QGaWttvSpxmiyltgOSLfs,1540
|
2
2
|
konduktor/adaptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
konduktor/adaptors/aws.py,sha256=s47Ra-GaqCQibzVfmD0pmwEWHif1EGO5opMbwkLxTCU,8244
|
3
4
|
konduktor/adaptors/common.py,sha256=mYb_6c3u5MghtiFfiW5OO-EH6t7cIR5npbkgUmz6FYE,3517
|
4
5
|
konduktor/adaptors/gcp.py,sha256=pOQA2q8fFyr97Htn8EqvNM0XT-Ao8UwvExviiLaDats,4746
|
5
6
|
konduktor/backends/__init__.py,sha256=1Q6sqqdeMYarpTX_U-QVywJYf7idiUTRsyP-E4BQSOw,129
|
@@ -7,7 +8,7 @@ konduktor/backends/backend.py,sha256=qh0bp94lzoTYZkzyQv2-CVrB5l91FkG2vclXg24UFC0
|
|
7
8
|
konduktor/backends/jobset.py,sha256=lh_PihQgM0tmVryCpjSsZjWug8hBnJr7ua9lqk0qEAM,8251
|
8
9
|
konduktor/backends/jobset_utils.py,sha256=NIwTvJdGhbDnXEceabiuUm9aHZ29LK3jVHfQzutB_ec,17297
|
9
10
|
konduktor/check.py,sha256=JennyWoaqSKhdyfUldd266KwVXTPJpcYQa4EED4a_BA,7569
|
10
|
-
konduktor/cli.py,sha256=
|
11
|
+
konduktor/cli.py,sha256=Ii9-2mrc-1f2ksLasA-xRb-JnEi_9ZeCXZ3lJ1GG8H8,23515
|
11
12
|
konduktor/config.py,sha256=J50JxC6MsXMnlrJPXdDUMr38C89xvOO7mR8KJ6fyils,15520
|
12
13
|
konduktor/constants.py,sha256=T3AeXXxuQHINW_bAWyztvDeS8r4g8kXBGIwIq13cys0,1814
|
13
14
|
konduktor/controller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -48,14 +49,16 @@ konduktor/dashboard/frontend/postcss.config.mjs,sha256=rDHiqV72T-J860Ek4QFnUnMQe
|
|
48
49
|
konduktor/dashboard/frontend/server.js,sha256=jcp6_Ww9YJD3uKY07jR3KMlAM6n1QZdxZnVY6Kh-J6A,1789
|
49
50
|
konduktor/dashboard/frontend/tailwind.config.js,sha256=fCnc48wvioIDOe5ldQ_6RE7F76cP7aU7pDrxBPJx-Fk,366
|
50
51
|
konduktor/data/__init__.py,sha256=KMR2i3E9YcIpiIuCxtRdS7BQ1w2vUAbbve7agziJrLo,213
|
52
|
+
konduktor/data/aws/__init__.py,sha256=_6zWfNNAK1QGgyKqg_yPYWcXlnffchyvIMErYa6tw_U,331
|
53
|
+
konduktor/data/aws/s3.py,sha256=E6JdT5K0nhy0ExQQN6M5vjemDSfBi6Cc3PCgjyCMJoQ,47777
|
51
54
|
konduktor/data/constants.py,sha256=yXVEoTI2we1xOjVSU-bjRCQCLpVvpEvJ0GedXvSwEfw,127
|
52
|
-
konduktor/data/data_utils.py,sha256=
|
55
|
+
konduktor/data/data_utils.py,sha256=yrnu8_cY63TXqfWfFG3yqY2w_tE9UQK9jIQAFQCDVg0,9668
|
53
56
|
konduktor/data/gcp/__init__.py,sha256=rlQxACBC_Vu36mdgPyJgUy4mGc_6Nt_a96JAuaPz2pQ,489
|
54
57
|
konduktor/data/gcp/constants.py,sha256=dMfOiFccM8O6rUi9kClJcbvw1K1VnS1JzzQk3apq8ho,1483
|
55
58
|
konduktor/data/gcp/gcs.py,sha256=kDbUzf8ALYzsw_G3sBRn_enQ8fjI-UKV0jeWuFZiULA,42018
|
56
59
|
konduktor/data/gcp/utils.py,sha256=FJQcMXZqtMIzjZ98b3lTTc0UbdPUKTDLsOsfJaaH5-s,214
|
57
|
-
konduktor/data/registry.py,sha256=
|
58
|
-
konduktor/data/storage.py,sha256=
|
60
|
+
konduktor/data/registry.py,sha256=CUbMsN_Q17Pf4wRHkqZrycErEjTP7cLEdgcfwVGcEpc,696
|
61
|
+
konduktor/data/storage.py,sha256=SDKRWDd7PCT9ytuz4cH0CejZj5QmWG_EZhUMVoTzWsc,35308
|
59
62
|
konduktor/data/storage_utils.py,sha256=n4GivkN0KMqmyOTDznF0Z-hzsJvm7KCEh5i5HgFAT-4,20806
|
60
63
|
konduktor/execution.py,sha256=UaHUdBmDaIYgiAXkRKJQOHniYPVIR4sr4yUbIqpgMrQ,18401
|
61
64
|
konduktor/kube_client.py,sha256=aqwjDfNSneB5NOxV6CtqhkBeNl0UQNUt730R3ujG9Ow,6156
|
@@ -65,16 +68,16 @@ konduktor/manifests/dashboard_deployment.yaml,sha256=xJLd4FbPMAosI0fIv5_8y7dV9bw
|
|
65
68
|
konduktor/manifests/dmesg_daemonset.yaml,sha256=pSWt7YOeTYjS0l0iki1fvHOs7MhY-sH-RQfVW6JJyno,1391
|
66
69
|
konduktor/manifests/pod_cleanup_controller.yaml,sha256=hziL1Ka1kCAEL9R7Tjvpb80iw1vcq9_3gwHCu75Bi0A,3939
|
67
70
|
konduktor/resource.py,sha256=68z8gC8Ivqktwv0R6ylMn9ZNocgkcRT0yIRGGKOdwcM,18491
|
68
|
-
konduktor/task.py,sha256=
|
71
|
+
konduktor/task.py,sha256=Vu1TzYtLvSBz-HyHY2gsM2cMcUhMNQu44L3CWmYRXKE,35232
|
69
72
|
konduktor/templates/jobset.yaml.j2,sha256=onYiHtXAgk-XBtji994hPu_g0hxnLzvmfxwjbdKdeZc,960
|
70
|
-
konduktor/templates/pod.yaml.j2,sha256=
|
73
|
+
konduktor/templates/pod.yaml.j2,sha256=q_kFyuYP-RlHocQUV8Vsnh-hYurWO7Y_pwl0gytGMl4,8728
|
71
74
|
konduktor/usage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
72
75
|
konduktor/usage/constants.py,sha256=gCL8afIHZhO0dcxbJGpESE9sCC1cBSbeRnQ8GwNOY4M,612
|
73
76
|
konduktor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
74
77
|
konduktor/utils/accelerator_registry.py,sha256=lzUqkod1U3hDo8ETFU0CBXESXhPNZI8e-CJt4Oqf3Ko,550
|
75
78
|
konduktor/utils/annotations.py,sha256=oy2-BLydkFt3KWkXDuaGY84d6b7iISuy4eAT9uXk0Fc,2225
|
76
79
|
konduktor/utils/base64_utils.py,sha256=mF-Tw98mFRG70YE4w6s9feuQSCYZHOb8YatBZwMugyI,3130
|
77
|
-
konduktor/utils/common_utils.py,sha256=
|
80
|
+
konduktor/utils/common_utils.py,sha256=F5x7k4AdBB44u8PYRkaugORnZKnK3JLqGn1jHOKgUYo,14960
|
78
81
|
konduktor/utils/constants.py,sha256=1DneiTR21lvKUcWdBGwC4I4fD4uPjbjLUilEnJS7rzA,216
|
79
82
|
konduktor/utils/env_options.py,sha256=T41Slzf4Mzl-n45CGXXqdy2fCrYhPNZQ7RP5vmnN4xc,2258
|
80
83
|
konduktor/utils/exceptions.py,sha256=GBOFIkk9nikqWGR0FXGXOWVVImoH7nWnMl_L3Oux3fo,6581
|
@@ -87,8 +90,8 @@ konduktor/utils/schemas.py,sha256=Gv7SEhFpv-eO5izqRz8d-eQ9z-lVmY05akm6HEXIIdc,17
|
|
87
90
|
konduktor/utils/subprocess_utils.py,sha256=WoFkoFhGecPR8-rF8WJxbIe-YtV94LXz9UG64SDhCY4,9448
|
88
91
|
konduktor/utils/ux_utils.py,sha256=NPNu3Igu2Z9Oq77ghJhy_fIxQZTXWr9BtKyxN3Wslzo,7164
|
89
92
|
konduktor/utils/validator.py,sha256=tgBghVyedyzGx84-U2Qfoh_cJBE3oUk9gclMW90ORks,691
|
90
|
-
konduktor_nightly-0.1.0.
|
91
|
-
konduktor_nightly-0.1.0.
|
92
|
-
konduktor_nightly-0.1.0.
|
93
|
-
konduktor_nightly-0.1.0.
|
94
|
-
konduktor_nightly-0.1.0.
|
93
|
+
konduktor_nightly-0.1.0.dev20250410104738.dist-info/LICENSE,sha256=MuuqTZbHvmqXR_aNKAXzggdV45ANd3wQ5YI7tnpZhm0,6586
|
94
|
+
konduktor_nightly-0.1.0.dev20250410104738.dist-info/METADATA,sha256=_EvP828hXwzUqFcjDyh5t-9HVMnsMqtp8UPDdxN2kSI,4303
|
95
|
+
konduktor_nightly-0.1.0.dev20250410104738.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
96
|
+
konduktor_nightly-0.1.0.dev20250410104738.dist-info/entry_points.txt,sha256=k3nG5wDFIJhNqsZWrHk4d0irIB2Ns9s47cjRWYsTCT8,48
|
97
|
+
konduktor_nightly-0.1.0.dev20250410104738.dist-info/RECORD,,
|
File without changes
|
File without changes
|