dagster-k8s 0.24.8__tar.gz → 0.24.10__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.
Potentially problematic release.
This version of dagster-k8s might be problematic. Click here for more details.
- {dagster-k8s-0.24.8/dagster_k8s.egg-info → dagster-k8s-0.24.10}/PKG-INFO +1 -1
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/client.py +41 -2
- dagster-k8s-0.24.10/dagster_k8s/kubernetes_version.py +1 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/models.py +13 -1
- dagster-k8s-0.24.10/dagster_k8s/version.py +1 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10/dagster_k8s.egg-info}/PKG-INFO +1 -1
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s.egg-info/SOURCES.txt +1 -0
- dagster-k8s-0.24.10/dagster_k8s.egg-info/requires.txt +3 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/setup.py +14 -6
- dagster-k8s-0.24.8/dagster_k8s/version.py +0 -1
- dagster-k8s-0.24.8/dagster_k8s.egg-info/requires.txt +0 -3
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/LICENSE +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/MANIFEST.in +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/README.md +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/__init__.py +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/container_context.py +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/executor.py +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/job.py +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/launcher.py +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/ops/__init__.py +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/ops/k8s_job_op.py +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/pipes.py +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/py.typed +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/test.py +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s/utils.py +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s.egg-info/dependency_links.txt +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s.egg-info/not-zip-safe +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/dagster_k8s.egg-info/top_level.txt +0 -0
- {dagster-k8s-0.24.8 → dagster-k8s-0.24.10}/setup.cfg +0 -0
|
@@ -6,11 +6,13 @@ from typing import Any, Callable, List, Optional, Set, TypeVar
|
|
|
6
6
|
|
|
7
7
|
import kubernetes.client
|
|
8
8
|
import kubernetes.client.rest
|
|
9
|
+
import six
|
|
9
10
|
from dagster import (
|
|
10
11
|
DagsterInstance,
|
|
11
12
|
_check as check,
|
|
12
13
|
)
|
|
13
14
|
from dagster._core.storage.dagster_run import DagsterRunStatus
|
|
15
|
+
from kubernetes.client.api_client import ApiClient
|
|
14
16
|
from kubernetes.client.models import V1Job, V1JobStatus
|
|
15
17
|
|
|
16
18
|
try:
|
|
@@ -91,6 +93,39 @@ WHITELISTED_TRANSIENT_K8S_STATUS_CODES = [
|
|
|
91
93
|
]
|
|
92
94
|
|
|
93
95
|
|
|
96
|
+
class PatchedApiClient(ApiClient):
|
|
97
|
+
# Forked from ApiClient implementation to pass configuration object down into created model
|
|
98
|
+
# objects, avoiding lock contention issues. See https://github.com/kubernetes-client/python/issues/2284
|
|
99
|
+
def __deserialize_model(self, data, klass):
|
|
100
|
+
"""Deserializes list or dict to model.
|
|
101
|
+
|
|
102
|
+
:param data: dict, list.
|
|
103
|
+
:param klass: class literal.
|
|
104
|
+
:return: model object.
|
|
105
|
+
"""
|
|
106
|
+
if not klass.openapi_types and not hasattr(klass, "get_real_child_model"):
|
|
107
|
+
return data
|
|
108
|
+
|
|
109
|
+
# Below is the only change from the base ApiClient implementation - pass through the
|
|
110
|
+
# Configuration object to each newly created model so that each one does not have to create
|
|
111
|
+
# one and acquire a lock
|
|
112
|
+
kwargs = {"local_vars_configuration": self.configuration}
|
|
113
|
+
|
|
114
|
+
if data is not None and klass.openapi_types is not None and isinstance(data, (list, dict)):
|
|
115
|
+
for attr, attr_type in six.iteritems(klass.openapi_types):
|
|
116
|
+
if klass.attribute_map[attr] in data:
|
|
117
|
+
value = data[klass.attribute_map[attr]]
|
|
118
|
+
kwargs[attr] = self.__deserialize(value, attr_type)
|
|
119
|
+
|
|
120
|
+
instance = klass(**kwargs)
|
|
121
|
+
|
|
122
|
+
if hasattr(instance, "get_real_child_model"):
|
|
123
|
+
klass_name = instance.get_real_child_model(data)
|
|
124
|
+
if klass_name:
|
|
125
|
+
instance = self.__deserialize(data, klass_name)
|
|
126
|
+
return instance
|
|
127
|
+
|
|
128
|
+
|
|
94
129
|
def k8s_api_retry(
|
|
95
130
|
fn: Callable[..., T],
|
|
96
131
|
max_retries: int,
|
|
@@ -209,8 +244,12 @@ class DagsterKubernetesClient:
|
|
|
209
244
|
@staticmethod
|
|
210
245
|
def production_client(batch_api_override=None, core_api_override=None):
|
|
211
246
|
return DagsterKubernetesClient(
|
|
212
|
-
batch_api=
|
|
213
|
-
|
|
247
|
+
batch_api=(
|
|
248
|
+
batch_api_override or kubernetes.client.BatchV1Api(api_client=PatchedApiClient())
|
|
249
|
+
),
|
|
250
|
+
core_api=(
|
|
251
|
+
core_api_override or kubernetes.client.CoreV1Api(api_client=PatchedApiClient())
|
|
252
|
+
),
|
|
214
253
|
logger=logging.info,
|
|
215
254
|
sleeper=time.sleep,
|
|
216
255
|
timer=time.time,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
KUBERNETES_VERSION_UPPER_BOUND = "32"
|
|
@@ -7,11 +7,20 @@ import kubernetes
|
|
|
7
7
|
import kubernetes.client.models
|
|
8
8
|
from dagster._vendored.dateutil.parser import parse
|
|
9
9
|
from kubernetes.client.api_client import ApiClient
|
|
10
|
+
from kubernetes.client.configuration import Configuration
|
|
10
11
|
|
|
11
12
|
# Unclear what the correct type is to use for a bound here.
|
|
12
13
|
T_KubernetesModel = TypeVar("T_KubernetesModel")
|
|
13
14
|
|
|
14
15
|
|
|
16
|
+
# Create a single Configuration object to pass through to each model creation -
|
|
17
|
+
# the default otherwise in the OpenAPI version currently in use by the k8s
|
|
18
|
+
# client will create one on each model creation otherwise, which can cause
|
|
19
|
+
# lock contention since it acquires the global python logger lock
|
|
20
|
+
# see: https://github.com/kubernetes-client/python/issues/1921
|
|
21
|
+
shared_k8s_model_configuration = Configuration()
|
|
22
|
+
|
|
23
|
+
|
|
15
24
|
def _get_k8s_class(classname: str) -> Type[Any]:
|
|
16
25
|
if classname in ApiClient.NATIVE_TYPES_MAPPING:
|
|
17
26
|
return ApiClient.NATIVE_TYPES_MAPPING[classname]
|
|
@@ -149,7 +158,10 @@ def k8s_model_from_dict(
|
|
|
149
158
|
if len(invalid_keys):
|
|
150
159
|
raise Exception(f"Unexpected keys in model class {model_class.__name__}: {invalid_keys}")
|
|
151
160
|
|
|
152
|
-
|
|
161
|
+
# Pass through the configuration object since the default implementation creates a new one
|
|
162
|
+
# in the constructor, which can create lock contention if multiple threads are calling this
|
|
163
|
+
# simultaneously
|
|
164
|
+
kwargs = {"local_vars_configuration": shared_k8s_model_configuration}
|
|
153
165
|
for attr, attr_type in model_class.openapi_types.items(): # type: ignore
|
|
154
166
|
# e.g. config_map => configMap
|
|
155
167
|
if attr in model_dict:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.24.10"
|
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
-
from typing import Dict
|
|
2
|
+
from typing import Dict, Tuple
|
|
3
3
|
|
|
4
4
|
from setuptools import find_packages, setup
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def get_version() -> str:
|
|
7
|
+
def get_version() -> Tuple[str, str]:
|
|
8
8
|
version: Dict[str, str] = {}
|
|
9
|
+
kubernetes_version: Dict[str, str] = {}
|
|
10
|
+
|
|
9
11
|
with open(Path(__file__).parent / "dagster_k8s/version.py", encoding="utf8") as fp:
|
|
10
12
|
exec(fp.read(), version)
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
with open(Path(__file__).parent / "dagster_k8s/kubernetes_version.py", encoding="utf8") as fp:
|
|
15
|
+
exec(fp.read(), kubernetes_version)
|
|
16
|
+
|
|
17
|
+
return version["__version__"], kubernetes_version["KUBERNETES_VERSION_UPPER_BOUND"]
|
|
13
18
|
|
|
14
19
|
|
|
15
|
-
|
|
20
|
+
(
|
|
21
|
+
ver,
|
|
22
|
+
KUBERNETES_VERSION_UPPER_BOUND,
|
|
23
|
+
) = get_version()
|
|
16
24
|
# dont pin dev installs to avoid pip dep resolver issues
|
|
17
25
|
pin = "" if ver == "1!0+dev" else f"=={ver}"
|
|
18
26
|
setup(
|
|
@@ -36,8 +44,8 @@ setup(
|
|
|
36
44
|
include_package_data=True,
|
|
37
45
|
python_requires=">=3.8,<3.13",
|
|
38
46
|
install_requires=[
|
|
39
|
-
"dagster==1.8.
|
|
40
|
-
"kubernetes",
|
|
47
|
+
"dagster==1.8.10",
|
|
48
|
+
f"kubernetes<{KUBERNETES_VERSION_UPPER_BOUND}",
|
|
41
49
|
# exclude a google-auth release that added an overly restrictive urllib3 pin that confuses dependency resolvers
|
|
42
50
|
"google-auth!=2.23.1",
|
|
43
51
|
],
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.24.8"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|