ygg 0.1.16__tar.gz → 0.1.18__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.
- {ygg-0.1.16 → ygg-0.1.18}/PKG-INFO +1 -1
- {ygg-0.1.16 → ygg-0.1.18}/pyproject.toml +1 -1
- {ygg-0.1.16 → ygg-0.1.18}/src/ygg.egg-info/PKG-INFO +1 -1
- {ygg-0.1.16 → ygg-0.1.18}/src/ygg.egg-info/SOURCES.txt +1 -1
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/compute/cluster.py +161 -39
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/compute/execution_context.py +153 -66
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/compute/remote.py +5 -1
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/pyutils/modules.py +6 -0
- ygg-0.1.18/src/yggdrasil/ser/__init__.py +1 -0
- ygg-0.1.18/src/yggdrasil/ser/callable_serde.py +653 -0
- ygg-0.1.16/src/yggdrasil/ser/__init__.py +0 -1
- ygg-0.1.16/src/yggdrasil/ser/method.py +0 -689
- {ygg-0.1.16 → ygg-0.1.18}/README.md +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/setup.cfg +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/ygg.egg-info/dependency_links.txt +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/ygg.egg-info/requires.txt +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/ygg.egg-info/top_level.txt +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/compute/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/jobs/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/jobs/config.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/sql/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/sql/engine.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/sql/exceptions.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/sql/statement_result.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/sql/types.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/workspaces/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/workspaces/databricks_path.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/databricks/workspaces/workspace.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/dataclasses/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/dataclasses/dataclass.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/libs/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/libs/databrickslib.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/libs/extensions/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/libs/extensions/polars_extensions.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/libs/extensions/spark_extensions.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/libs/pandaslib.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/libs/polarslib.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/libs/sparklib.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/pyutils/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/pyutils/exceptions.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/pyutils/parallel.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/pyutils/retry.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/requests/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/requests/msal.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/requests/session.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/cast/__init__.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/cast/arrow_cast.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/cast/cast_options.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/cast/pandas_cast.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/cast/polars_cast.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/cast/polars_pandas_cast.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/cast/registry.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/cast/spark_cast.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/cast/spark_pandas_cast.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/cast/spark_polars_cast.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/libs.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/src/yggdrasil/types/python_arrow.py +0 -0
- {ygg-0.1.16 → ygg-0.1.18}/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.
|
|
3
|
+
Version: 0.1.18
|
|
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
|
Project-URL: Homepage, https://github.com/Platob/Yggdrasil
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ygg"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.18"
|
|
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.
|
|
3
|
+
Version: 0.1.18
|
|
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
|
Project-URL: Homepage, https://github.com/Platob/Yggdrasil
|
|
@@ -40,7 +40,7 @@ src/yggdrasil/requests/__init__.py
|
|
|
40
40
|
src/yggdrasil/requests/msal.py
|
|
41
41
|
src/yggdrasil/requests/session.py
|
|
42
42
|
src/yggdrasil/ser/__init__.py
|
|
43
|
-
src/yggdrasil/ser/
|
|
43
|
+
src/yggdrasil/ser/callable_serde.py
|
|
44
44
|
src/yggdrasil/types/__init__.py
|
|
45
45
|
src/yggdrasil/types/libs.py
|
|
46
46
|
src/yggdrasil/types/python_arrow.py
|
|
@@ -26,7 +26,7 @@ from ..workspaces.workspace import WorkspaceService, Workspace
|
|
|
26
26
|
from ... import retry
|
|
27
27
|
from ...libs.databrickslib import databricks_sdk
|
|
28
28
|
from ...pyutils.modules import PipIndexSettings
|
|
29
|
-
from ...ser import
|
|
29
|
+
from ...ser import CallableSerdeMixin
|
|
30
30
|
|
|
31
31
|
if databricks_sdk is None: # pragma: no cover - import guard
|
|
32
32
|
ResourceDoesNotExist = Exception # type: ignore
|
|
@@ -154,10 +154,17 @@ class Cluster(WorkspaceService):
|
|
|
154
154
|
] if _ not in libraries
|
|
155
155
|
])
|
|
156
156
|
|
|
157
|
+
python_version = sys.version_info
|
|
158
|
+
|
|
159
|
+
if python_version[0] < 3:
|
|
160
|
+
python_version = None
|
|
161
|
+
elif python_version[1] < 11:
|
|
162
|
+
python_version = None
|
|
163
|
+
|
|
157
164
|
inst = self.create_or_update(
|
|
158
165
|
cluster_id=cluster_id,
|
|
159
166
|
cluster_name=cluster_name or self.cluster_name or self.workspace.current_user.user_name,
|
|
160
|
-
python_version=
|
|
167
|
+
python_version=python_version,
|
|
161
168
|
single_user_name=single_user_name or self.workspace.current_user.user_name,
|
|
162
169
|
runtime_engine=runtime_engine or RuntimeEngine.PHOTON,
|
|
163
170
|
libraries=libraries,
|
|
@@ -172,8 +179,11 @@ class Cluster(WorkspaceService):
|
|
|
172
179
|
self.details = self.clusters_client().get(cluster_id=self.cluster_id)
|
|
173
180
|
return self._details
|
|
174
181
|
|
|
175
|
-
def fresh_details(self, max_delay: float):
|
|
176
|
-
|
|
182
|
+
def fresh_details(self, max_delay: float | None = None):
|
|
183
|
+
max_delay = max_delay or 0
|
|
184
|
+
delay = time.time() - self._details_refresh_time
|
|
185
|
+
|
|
186
|
+
if self.cluster_id and delay > max_delay:
|
|
177
187
|
self.details = self.clusters_client().get(cluster_id=self.cluster_id)
|
|
178
188
|
return self._details
|
|
179
189
|
|
|
@@ -187,14 +197,59 @@ class Cluster(WorkspaceService):
|
|
|
187
197
|
|
|
188
198
|
@property
|
|
189
199
|
def state(self):
|
|
190
|
-
|
|
191
|
-
|
|
200
|
+
details = self.fresh_details(max_delay=10)
|
|
201
|
+
|
|
202
|
+
if details is not None:
|
|
203
|
+
return details.state
|
|
204
|
+
return State.UNKNOWN
|
|
205
|
+
|
|
206
|
+
def get_state(self, max_delay: float = None):
|
|
207
|
+
details = self.fresh_details(max_delay=max_delay)
|
|
208
|
+
|
|
209
|
+
if details is not None:
|
|
210
|
+
return details.state
|
|
192
211
|
return State.UNKNOWN
|
|
193
212
|
|
|
194
213
|
@property
|
|
195
214
|
def is_running(self):
|
|
196
215
|
return self.state == State.RUNNING
|
|
197
216
|
|
|
217
|
+
@property
|
|
218
|
+
def is_pending(self):
|
|
219
|
+
return self.state in (State.PENDING, State.RESIZING, State.RESTARTING, State.TERMINATING)
|
|
220
|
+
|
|
221
|
+
@property
|
|
222
|
+
def is_error(self):
|
|
223
|
+
return self.state == State.ERROR
|
|
224
|
+
|
|
225
|
+
def raise_for_status(self):
|
|
226
|
+
if self.is_error:
|
|
227
|
+
raise DatabricksError("Error in %s" % self)
|
|
228
|
+
|
|
229
|
+
return self
|
|
230
|
+
|
|
231
|
+
def wait_for_status(
|
|
232
|
+
self,
|
|
233
|
+
tick: float = 0.5,
|
|
234
|
+
timeout: float = 600,
|
|
235
|
+
backoff: int = 2,
|
|
236
|
+
max_sleep_time: float = 15
|
|
237
|
+
):
|
|
238
|
+
start = time.time()
|
|
239
|
+
sleep_time = tick
|
|
240
|
+
|
|
241
|
+
while self.is_pending:
|
|
242
|
+
time.sleep(sleep_time)
|
|
243
|
+
|
|
244
|
+
if time.time() - start > timeout:
|
|
245
|
+
raise TimeoutError("Waiting state for %s timed out")
|
|
246
|
+
|
|
247
|
+
sleep_time = min(max_sleep_time, sleep_time * backoff)
|
|
248
|
+
|
|
249
|
+
self.raise_for_status()
|
|
250
|
+
|
|
251
|
+
return self
|
|
252
|
+
|
|
198
253
|
@property
|
|
199
254
|
def spark_version(self) -> str:
|
|
200
255
|
d = self.details
|
|
@@ -276,7 +331,8 @@ class Cluster(WorkspaceService):
|
|
|
276
331
|
|
|
277
332
|
versions = [v for v in versions if py_for_key(v.key) == py_filter]
|
|
278
333
|
|
|
279
|
-
|
|
334
|
+
# Handle superior pyton versions
|
|
335
|
+
if not versions and py_filter[1] > 12:
|
|
280
336
|
return self.spark_versions(photon=photon)
|
|
281
337
|
|
|
282
338
|
return versions
|
|
@@ -402,7 +458,7 @@ class Cluster(WorkspaceService):
|
|
|
402
458
|
libraries: Optional[List[Union[str, "Library"]]] = None,
|
|
403
459
|
**cluster_spec: Any
|
|
404
460
|
) -> "Cluster":
|
|
405
|
-
self.install_libraries(libraries=libraries,
|
|
461
|
+
self.install_libraries(libraries=libraries, wait_timeout=None, raise_error=False)
|
|
406
462
|
|
|
407
463
|
existing_details = {
|
|
408
464
|
k: v
|
|
@@ -482,24 +538,29 @@ class Cluster(WorkspaceService):
|
|
|
482
538
|
) -> "Cluster":
|
|
483
539
|
return self.start()
|
|
484
540
|
|
|
485
|
-
@retry(tries=4)
|
|
486
541
|
def start(
|
|
487
542
|
self,
|
|
488
543
|
) -> "Cluster":
|
|
544
|
+
self.wait_for_status()
|
|
545
|
+
|
|
489
546
|
if not self.is_running:
|
|
490
547
|
logger.info("Starting %s", self)
|
|
491
548
|
self.details = self.clusters_client().start_and_wait(cluster_id=self.cluster_id)
|
|
492
549
|
return self.wait_installed_libraries()
|
|
550
|
+
|
|
493
551
|
return self
|
|
494
552
|
|
|
495
553
|
@retry(tries=4)
|
|
496
554
|
def restart(
|
|
497
555
|
self,
|
|
498
556
|
):
|
|
557
|
+
self.wait_for_status()
|
|
558
|
+
|
|
499
559
|
if self.is_running:
|
|
500
560
|
logger.info("Restarting %s", self)
|
|
501
561
|
self.details = self.clusters_client().restart_and_wait(cluster_id=self.cluster_id)
|
|
502
562
|
return self.wait_installed_libraries()
|
|
563
|
+
|
|
503
564
|
return self.start()
|
|
504
565
|
|
|
505
566
|
def delete(
|
|
@@ -530,15 +591,14 @@ class Cluster(WorkspaceService):
|
|
|
530
591
|
timeout: Optional[dt.timedelta] = None,
|
|
531
592
|
result_tag: Optional[str] = None,
|
|
532
593
|
):
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
)
|
|
594
|
+
return self.execution_context(language=language).execute(
|
|
595
|
+
obj=obj,
|
|
596
|
+
args=args,
|
|
597
|
+
kwargs=kwargs,
|
|
598
|
+
env_keys=env_keys,
|
|
599
|
+
timeout=timeout,
|
|
600
|
+
result_tag=result_tag
|
|
601
|
+
)
|
|
542
602
|
|
|
543
603
|
# ------------------------------------------------------------------
|
|
544
604
|
# decorator that routes function calls via `execute`
|
|
@@ -551,6 +611,7 @@ class Cluster(WorkspaceService):
|
|
|
551
611
|
env_keys: Optional[List[str]] = None,
|
|
552
612
|
timeout: Optional[dt.timedelta] = None,
|
|
553
613
|
result_tag: Optional[str] = None,
|
|
614
|
+
**options
|
|
554
615
|
):
|
|
555
616
|
"""
|
|
556
617
|
Decorator to run a function via Workspace.execute instead of locally.
|
|
@@ -570,7 +631,7 @@ class Cluster(WorkspaceService):
|
|
|
570
631
|
"""
|
|
571
632
|
def decorator(func: Callable):
|
|
572
633
|
context = self.execution_context(language=language or Language.PYTHON)
|
|
573
|
-
serialized =
|
|
634
|
+
serialized = CallableSerdeMixin.from_callable(func)
|
|
574
635
|
|
|
575
636
|
@functools.wraps(func)
|
|
576
637
|
def wrapper(*args, **kwargs):
|
|
@@ -584,6 +645,7 @@ class Cluster(WorkspaceService):
|
|
|
584
645
|
env_keys=env_keys,
|
|
585
646
|
timeout=timeout,
|
|
586
647
|
result_tag=result_tag,
|
|
648
|
+
**options
|
|
587
649
|
)
|
|
588
650
|
|
|
589
651
|
return wrapper
|
|
@@ -597,39 +659,96 @@ class Cluster(WorkspaceService):
|
|
|
597
659
|
def install_libraries(
|
|
598
660
|
self,
|
|
599
661
|
libraries: Optional[List[Union[str, "Library"]]] = None,
|
|
600
|
-
|
|
662
|
+
wait_timeout: Optional[dt.timedelta] = dt.timedelta(minutes=20),
|
|
601
663
|
pip_settings: Optional[PipIndexSettings] = None,
|
|
602
|
-
raise_error: bool = True
|
|
664
|
+
raise_error: bool = True,
|
|
665
|
+
restart: bool = True,
|
|
603
666
|
) -> "Cluster":
|
|
604
667
|
if not libraries:
|
|
605
668
|
return self
|
|
606
669
|
|
|
607
670
|
wsdk = self.workspace.sdk()
|
|
608
671
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
libraries
|
|
612
|
-
|
|
613
|
-
|
|
672
|
+
libraries = [
|
|
673
|
+
self._check_library(_, pip_settings=pip_settings)
|
|
674
|
+
for _ in libraries if _
|
|
675
|
+
]
|
|
676
|
+
|
|
677
|
+
if libraries:
|
|
678
|
+
wsdk.libraries.install(
|
|
679
|
+
cluster_id=self.cluster_id,
|
|
680
|
+
libraries=[
|
|
681
|
+
self._check_library(_, pip_settings=pip_settings)
|
|
682
|
+
for _ in libraries if _
|
|
683
|
+
]
|
|
684
|
+
)
|
|
685
|
+
|
|
686
|
+
if wait_timeout is not None:
|
|
687
|
+
self.wait_installed_libraries(
|
|
688
|
+
timeout=wait_timeout, pip_settings=pip_settings, raise_error=raise_error
|
|
689
|
+
)
|
|
690
|
+
|
|
691
|
+
return self
|
|
692
|
+
|
|
693
|
+
def installed_library_statuses(self):
|
|
694
|
+
return self.workspace.sdk().libraries.cluster_status(cluster_id=self.cluster_id)
|
|
695
|
+
|
|
696
|
+
def uninstall_libraries(
|
|
697
|
+
self,
|
|
698
|
+
pypi_packages: Optional[list[str]] = None,
|
|
699
|
+
libraries: Optional[list["Library"]] = None,
|
|
700
|
+
restart: bool = True
|
|
701
|
+
):
|
|
702
|
+
if libraries is None:
|
|
703
|
+
to_remove = [
|
|
704
|
+
lib.library
|
|
705
|
+
for lib in self.installed_library_statuses()
|
|
706
|
+
if self._filter_lib(
|
|
707
|
+
lib,
|
|
708
|
+
pypi_packages=pypi_packages,
|
|
709
|
+
default_filter=False
|
|
710
|
+
)
|
|
614
711
|
]
|
|
615
|
-
|
|
712
|
+
else:
|
|
713
|
+
to_remove = libraries
|
|
714
|
+
|
|
715
|
+
if to_remove:
|
|
716
|
+
self.workspace.sdk().libraries.uninstall(
|
|
717
|
+
cluster_id=self.cluster_id,
|
|
718
|
+
libraries=to_remove
|
|
719
|
+
)
|
|
616
720
|
|
|
617
|
-
|
|
618
|
-
|
|
721
|
+
if restart:
|
|
722
|
+
self.restart()
|
|
619
723
|
|
|
620
724
|
return self
|
|
621
725
|
|
|
726
|
+
@staticmethod
|
|
727
|
+
def _filter_lib(
|
|
728
|
+
lib: Optional["Library"],
|
|
729
|
+
pypi_packages: Optional[list[str]] = None,
|
|
730
|
+
default_filter: bool = False
|
|
731
|
+
):
|
|
732
|
+
if lib is None:
|
|
733
|
+
return False
|
|
734
|
+
|
|
735
|
+
if lib.pypi:
|
|
736
|
+
if lib.pypi.package and pypi_packages:
|
|
737
|
+
return lib.pypi.package in pypi_packages
|
|
738
|
+
|
|
739
|
+
return default_filter
|
|
740
|
+
|
|
622
741
|
def wait_installed_libraries(
|
|
623
742
|
self,
|
|
624
|
-
timeout: dt.timedelta = dt.timedelta(minutes=
|
|
743
|
+
timeout: dt.timedelta = dt.timedelta(minutes=20),
|
|
625
744
|
pip_settings: Optional[PipIndexSettings] = None,
|
|
626
|
-
raise_error: bool = True
|
|
745
|
+
raise_error: bool = True,
|
|
627
746
|
):
|
|
628
747
|
if not self.is_running:
|
|
629
748
|
return self
|
|
630
749
|
|
|
631
|
-
|
|
632
|
-
|
|
750
|
+
statuses = list(self.installed_library_statuses())
|
|
751
|
+
|
|
633
752
|
max_time = time.time() + timeout.total_seconds()
|
|
634
753
|
|
|
635
754
|
while True:
|
|
@@ -641,6 +760,7 @@ class Cluster(WorkspaceService):
|
|
|
641
760
|
if failed:
|
|
642
761
|
if raise_error:
|
|
643
762
|
raise DatabricksError("Libraries %s in %s failed to install" % (failed, self))
|
|
763
|
+
|
|
644
764
|
logger.warning(
|
|
645
765
|
"Libraries %s in %s failed to install",
|
|
646
766
|
failed, self
|
|
@@ -662,7 +782,7 @@ class Cluster(WorkspaceService):
|
|
|
662
782
|
)
|
|
663
783
|
|
|
664
784
|
time.sleep(10)
|
|
665
|
-
statuses = list(
|
|
785
|
+
statuses = list(self.installed_library_statuses())
|
|
666
786
|
|
|
667
787
|
return self
|
|
668
788
|
|
|
@@ -680,6 +800,8 @@ class Cluster(WorkspaceService):
|
|
|
680
800
|
if isinstance(value, Library):
|
|
681
801
|
return value
|
|
682
802
|
|
|
803
|
+
pip_settings = PipIndexSettings.default_settings() if pip_settings is None else pip_settings
|
|
804
|
+
|
|
683
805
|
if isinstance(value, str):
|
|
684
806
|
if os.path.exists(value):
|
|
685
807
|
target_path = self.workspace.shared_cache_path(
|
|
@@ -698,11 +820,11 @@ class Cluster(WorkspaceService):
|
|
|
698
820
|
elif value.endswith(".whl"):
|
|
699
821
|
return Library(whl=value)
|
|
700
822
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
823
|
+
repo = None
|
|
824
|
+
|
|
825
|
+
if pip_settings.extra_index_url:
|
|
826
|
+
if value.startswith("datamanagement") or value.startswith("TSSecrets") or value.startswith("tgp_"):
|
|
827
|
+
repo = pip_settings.extra_index_url
|
|
706
828
|
|
|
707
829
|
return Library(
|
|
708
830
|
pypi=PythonPyPiLibrary(
|