dagster-k8s 0.24.9__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.

Files changed (29) hide show
  1. {dagster-k8s-0.24.9/dagster_k8s.egg-info → dagster-k8s-0.24.10}/PKG-INFO +1 -1
  2. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/client.py +41 -2
  3. dagster-k8s-0.24.10/dagster_k8s/kubernetes_version.py +1 -0
  4. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/models.py +13 -1
  5. dagster-k8s-0.24.10/dagster_k8s/version.py +1 -0
  6. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10/dagster_k8s.egg-info}/PKG-INFO +1 -1
  7. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s.egg-info/SOURCES.txt +1 -0
  8. dagster-k8s-0.24.10/dagster_k8s.egg-info/requires.txt +3 -0
  9. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/setup.py +14 -6
  10. dagster-k8s-0.24.9/dagster_k8s/version.py +0 -1
  11. dagster-k8s-0.24.9/dagster_k8s.egg-info/requires.txt +0 -3
  12. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/LICENSE +0 -0
  13. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/MANIFEST.in +0 -0
  14. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/README.md +0 -0
  15. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/__init__.py +0 -0
  16. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/container_context.py +0 -0
  17. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/executor.py +0 -0
  18. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/job.py +0 -0
  19. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/launcher.py +0 -0
  20. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/ops/__init__.py +0 -0
  21. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/ops/k8s_job_op.py +0 -0
  22. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/pipes.py +0 -0
  23. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/py.typed +0 -0
  24. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/test.py +0 -0
  25. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s/utils.py +0 -0
  26. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s.egg-info/dependency_links.txt +0 -0
  27. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s.egg-info/not-zip-safe +0 -0
  28. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/dagster_k8s.egg-info/top_level.txt +0 -0
  29. {dagster-k8s-0.24.9 → dagster-k8s-0.24.10}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dagster-k8s
3
- Version: 0.24.9
3
+ Version: 0.24.10
4
4
  Summary: A Dagster integration for k8s
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-k8s
6
6
  Author: Dagster Labs
@@ -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=batch_api_override or kubernetes.client.BatchV1Api(),
213
- core_api=core_api_override or kubernetes.client.CoreV1Api(),
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
- kwargs = {}
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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dagster-k8s
3
- Version: 0.24.9
3
+ Version: 0.24.10
4
4
  Summary: A Dagster integration for k8s
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-k8s
6
6
  Author: Dagster Labs
@@ -8,6 +8,7 @@ dagster_k8s/client.py
8
8
  dagster_k8s/container_context.py
9
9
  dagster_k8s/executor.py
10
10
  dagster_k8s/job.py
11
+ dagster_k8s/kubernetes_version.py
11
12
  dagster_k8s/launcher.py
12
13
  dagster_k8s/models.py
13
14
  dagster_k8s/pipes.py
@@ -0,0 +1,3 @@
1
+ dagster==1.8.10
2
+ kubernetes<32
3
+ google-auth!=2.23.1
@@ -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
- return version["__version__"]
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
- ver = get_version()
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.9",
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.9"
@@ -1,3 +0,0 @@
1
- dagster==1.8.9
2
- kubernetes
3
- google-auth!=2.23.1
File without changes
File without changes
File without changes
File without changes