datacrunch 1.13.2__py3-none-any.whl → 1.15.0__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.
datacrunch/__version__.py CHANGED
@@ -1 +1 @@
1
- VERSION = '1.13.2'
1
+ VERSION = '1.15.0'
@@ -7,6 +7,8 @@ from .containers import (
7
7
  EntrypointOverridesSettings,
8
8
  VolumeMount,
9
9
  SecretMount,
10
+ SharedFileSystemMount,
11
+ GeneralStorageMount,
10
12
  VolumeMountType,
11
13
  Container,
12
14
  ContainerRegistryCredentials,
@@ -8,7 +8,7 @@ import base64
8
8
  import os
9
9
  from dataclasses import dataclass, field
10
10
  from dataclasses_json import dataclass_json, Undefined # type: ignore
11
- from typing import List, Optional, Dict, Any
11
+ from typing import List, Optional, Dict, Any, Union
12
12
  from enum import Enum
13
13
 
14
14
  from datacrunch.http_client.http_client import HTTPClient
@@ -43,6 +43,7 @@ class VolumeMountType(str, Enum):
43
43
  SCRATCH = "scratch"
44
44
  SECRET = "secret"
45
45
  MEMORY = "memory"
46
+ SHARED = "shared"
46
47
 
47
48
 
48
49
  class ContainerRegistryType(str, Enum):
@@ -119,25 +120,88 @@ class EnvVar:
119
120
  @dataclass_json(undefined=Undefined.EXCLUDE)
120
121
  @dataclass
121
122
  class VolumeMount:
122
- """Volume mount configuration for containers.
123
+ """Base class for volume mount configurations.
123
124
 
124
125
  Attributes:
125
126
  type: Type of volume mount.
126
127
  mount_path: Path where the volume should be mounted in the container.
127
- size_in_mb: Size of the memory volume in megabytes, only used for memory volume mounts
128
+ size_in_mb: Size of the volume in megabytes. Deprecated: use MemoryMount for memory volumes instead.
128
129
  """
129
130
 
130
131
  type: VolumeMountType
131
132
  mount_path: str
132
- size_in_mb: Optional[int] = None
133
+ # Deprecated: use MemoryMount for memory volumes instead.
134
+ size_in_mb: Optional[int] = field(default=None, kw_only=True)
133
135
 
134
136
 
135
- @dataclass_json
137
+ @dataclass_json(undefined=Undefined.EXCLUDE)
136
138
  @dataclass
137
- class SecretMount:
138
- mount_path: str
139
+ class GeneralStorageMount(VolumeMount):
140
+ """General storage volume mount configuration.
141
+ """
142
+
143
+ def __init__(self, mount_path: str):
144
+ """Initialize a general scratch volume mount.
145
+
146
+ Args:
147
+ mount_path: Path where the volume should be mounted in the container.
148
+ """
149
+ super().__init__(type=VolumeMountType.SCRATCH, mount_path=mount_path)
150
+
151
+
152
+ @dataclass_json(undefined=Undefined.EXCLUDE)
153
+ @dataclass
154
+ class SecretMount(VolumeMount):
155
+ """Secret volume mount configuration.
156
+
157
+ A secret volume mount allows mounting secret files into the container.
158
+
159
+ Attributes:
160
+ secret_name: The name of the fileset secret to mount. This secret must be created in advance, for example using `create_fileset_secret_from_file_paths`
161
+ file_names: List of file names that are part of the fileset secret.
162
+ """
163
+
139
164
  secret_name: str
140
- type: VolumeMountType = VolumeMountType.SECRET
165
+ file_names: Optional[List[str]] = None
166
+
167
+ def __init__(self, mount_path: str, secret_name: str, file_names: Optional[List[str]] = None):
168
+ self.secret_name = secret_name
169
+ self.file_names = file_names
170
+ super().__init__(type=VolumeMountType.SECRET, mount_path=mount_path)
171
+
172
+
173
+ @dataclass_json(undefined=Undefined.EXCLUDE)
174
+ @dataclass
175
+ class MemoryMount(VolumeMount):
176
+ """Memory volume mount configuration.
177
+
178
+ A memory volume mount provides high-speed, ephemeral in-memory storage inside your container.
179
+ The mount path is currently hardcoded to /dev/shm and cannot be changed.
180
+
181
+ Attributes:
182
+ size_in_mb: Size of the memory volume in megabytes.
183
+ """
184
+
185
+ size_in_mb: int
186
+
187
+ def __init__(self, size_in_mb: int):
188
+ super().__init__(type=VolumeMountType.MEMORY, mount_path='/dev/shm')
189
+ self.size_in_mb = size_in_mb
190
+
191
+
192
+ @dataclass_json(undefined=Undefined.EXCLUDE)
193
+ @dataclass
194
+ class SharedFileSystemMount(VolumeMount):
195
+ """Shared filesystem volume mount configuration.
196
+
197
+ A shared filesystem volume mount allows mounting a shared filesystem into the container.
198
+ """
199
+
200
+ volume_id: str # The ID of the shared filesystem volume to mount, needs to be created first
201
+
202
+ def __init__(self, mount_path: str, volume_id: str):
203
+ super().__init__(type=VolumeMountType.SHARED, mount_path=mount_path)
204
+ self.volume_id = volume_id
141
205
 
142
206
 
143
207
  @dataclass_json
@@ -155,7 +219,7 @@ class Container:
155
219
  volume_mounts: Optional list of volume mounts.
156
220
  """
157
221
 
158
- image: str
222
+ image: Union[str, dict]
159
223
  exposed_port: int
160
224
  name: Optional[str] = None
161
225
  healthcheck: Optional[HealthcheckSettings] = None
@@ -1,4 +1,5 @@
1
1
  import time
2
+ import itertools
2
3
  from typing import List, Union, Optional, Dict, Literal
3
4
  from dataclasses import dataclass
4
5
  from dataclasses_json import dataclass_json
@@ -123,7 +124,12 @@ class InstancesService:
123
124
  is_spot: bool = False,
124
125
  contract: Optional[Contract] = None,
125
126
  pricing: Optional[Pricing] = None,
126
- coupon: Optional[str] = None) -> Instance:
127
+ coupon: Optional[str] = None,
128
+ *,
129
+ max_wait_time: float = 180,
130
+ initial_interval: float = 0.5,
131
+ max_interval: float = 5,
132
+ backoff_coefficient: float = 2.0) -> Instance:
127
133
  """Creates and deploys a new cloud instance.
128
134
 
129
135
  Args:
@@ -141,6 +147,10 @@ class InstancesService:
141
147
  contract: Optional contract type for the instance.
142
148
  pricing: Optional pricing model for the instance.
143
149
  coupon: Optional coupon code for discounts.
150
+ max_wait_time: Maximum total wait for the instance to start provisioning, in seconds (default: 180)
151
+ initial_interval: Initial interval, in seconds (default: 0.5)
152
+ max_interval: The longest single delay allowed between retries, in seconds (default: 5)
153
+ backoff_coefficient: Coefficient to calculate the next retry interval (default 2.0)
144
154
 
145
155
  Returns:
146
156
  The newly created instance object.
@@ -169,20 +179,19 @@ class InstancesService:
169
179
  id = self._http_client.post(INSTANCES_ENDPOINT, json=payload).text
170
180
 
171
181
  # Wait for instance to enter provisioning state with timeout
172
- MAX_WAIT_TIME = 60 # Maximum wait time in seconds
173
- POLL_INTERVAL = 0.5 # Time between status checks
174
-
175
- start_time = time.time()
176
- while True:
182
+ deadline = time.monotonic() + max_wait_time
183
+ for i in itertools.count():
177
184
  instance = self.get_by_id(id)
178
185
  if instance.status != InstanceStatus.ORDERED:
179
186
  return instance
180
187
 
181
- if time.time() - start_time > MAX_WAIT_TIME:
188
+ now = time.monotonic()
189
+ if now >= deadline:
182
190
  raise TimeoutError(
183
- f"Instance {id} did not enter provisioning state within {MAX_WAIT_TIME} seconds")
191
+ f"Instance {id} did not enter provisioning state within {max_wait_time:.1f} seconds")
184
192
 
185
- time.sleep(POLL_INTERVAL)
193
+ interval = min(initial_interval * backoff_coefficient ** i, max_interval, deadline - now)
194
+ time.sleep(interval)
186
195
 
187
196
  def action(self, id_list: Union[List[str], str], action: str, volume_ids: Optional[List[str]] = None) -> None:
188
197
  """Performs an action on one or more instances.
@@ -1,12 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datacrunch
3
- Version: 1.13.2
3
+ Version: 1.15.0
4
4
  Summary: Official Python SDK for DataCrunch Public API
5
5
  Home-page: https://github.com/DataCrunch-io
6
6
  Author: DataCrunch Oy
7
7
  Author-email: info@datacrunch.io
8
8
  Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.9
10
9
  Classifier: Programming Language :: Python :: 3.10
11
10
  Classifier: Programming Language :: Python :: 3.11
12
11
  Classifier: Programming Language :: Python :: 3.12
@@ -16,7 +15,7 @@ Classifier: Intended Audience :: Developers
16
15
  Classifier: License :: OSI Approved :: MIT License
17
16
  Classifier: Operating System :: OS Independent
18
17
  Classifier: Natural Language :: English
19
- Requires-Python: >=3.9
18
+ Requires-Python: >=3.10
20
19
  Description-Content-Type: text/markdown
21
20
  License-File: LICENSE
22
21
  Requires-Dist: requests<3,>=2.25.1
@@ -1,5 +1,5 @@
1
1
  datacrunch/__init__.py,sha256=OG-5Avmuq3NXyBs_66GMwyzscUi0c-T6vWW5sRIfnZg,51
2
- datacrunch/__version__.py,sha256=8IckzI0uUmhYiB-ovZrtHma7D20LkhqldG1saLuXwus,19
2
+ datacrunch/__version__.py,sha256=v0NuAYy8C6njG7SDCjPG68hLvRFV00bt7g3lqwOYITU,19
3
3
  datacrunch/constants.py,sha256=i0jCX91H2lKp1Uvk4GDsaTeXk0WmjyeSGpMfPs69BB4,2378
4
4
  datacrunch/datacrunch.py,sha256=2IqrTY39sLuwtuQ_QP3jCI1d5AaCwriYgAUEFoZZzPU,3488
5
5
  datacrunch/exceptions.py,sha256=uOP_YU2HEUi_mcMxQ9WYrIjqWUuUrwdube-RdL1C4Ps,781
@@ -10,8 +10,8 @@ datacrunch/authentication/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
10
10
  datacrunch/authentication/authentication.py,sha256=CThTxA99jseh7TKIdUR1M9RErIJoXvTB8CbF1VGFPCE,3589
11
11
  datacrunch/balance/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  datacrunch/balance/balance.py,sha256=rkqqXC3MLVxk6ym9Hlp9tsLbLWJculIn8q3BYbsme28,1240
13
- datacrunch/containers/__init__.py,sha256=WxkSyF_O-K_V2aZA-fucfGmRgQmrHhPSpUjxp3ayzO0,692
14
- datacrunch/containers/containers.py,sha256=M7q6_XAgwiAbkD7FKI3QwTgDuHvFRFfCSNPYOSX3N9U,33276
13
+ datacrunch/containers/__init__.py,sha256=qNxgk3tS9Dx251ugXjmsDWeab2MO7EAFLd6aRo1XpmQ,744
14
+ datacrunch/containers/containers.py,sha256=BSjPQ-VGvc7z9CYwCKkjVuM5ZV4oVgfOUyTe56BvXMY,35604
15
15
  datacrunch/http_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  datacrunch/http_client/http_client.py,sha256=tmpVd3p7-NAIaTM4E13inFZWUetdVEFZnRE38p5eVk0,8285
17
17
  datacrunch/images/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -19,7 +19,7 @@ datacrunch/images/images.py,sha256=hCAtSzozHcAAJ_UZOvnAbQSEU7BfCuixpIsmcd2RM2k,2
19
19
  datacrunch/instance_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  datacrunch/instance_types/instance_types.py,sha256=NLkUI6UdfXg-zDkMu9j9RzVISLG8jdABhT_R7XpfBdA,5289
21
21
  datacrunch/instances/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- datacrunch/instances/instances.py,sha256=GKPpZshn5JBsduR5zyT57fonB0GDdOLkPfPmGqgJQow,9239
22
+ datacrunch/instances/instances.py,sha256=fHHQdJcdudE3-Nee3NWAeCjN2c43mlgtfpJ-1Lfm6x4,9862
23
23
  datacrunch/locations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  datacrunch/locations/locations.py,sha256=2f1OF2ObNaqGam_Mm0Btie1GymnAI9UzXulhqSSm7zo,404
25
25
  datacrunch/ssh_keys/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -30,7 +30,7 @@ datacrunch/volume_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
30
30
  datacrunch/volume_types/volume_types.py,sha256=CNJ8kfd_nxmF99x-UAJeku-uN4Gdh-yg15Aa8WGLgWU,1828
31
31
  datacrunch/volumes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  datacrunch/volumes/volumes.py,sha256=aAH4UIVG-7NehjHu-a_4MGSdZ1jmeApV-kKh-X6TB-s,11908
33
- datacrunch-1.13.2.dist-info/licenses/LICENSE,sha256=LkdhbR2MArjDfV8M0dySL5mG_kfzxF2ntMgbJvWGyUQ,1069
33
+ datacrunch-1.15.0.dist-info/licenses/LICENSE,sha256=LkdhbR2MArjDfV8M0dySL5mG_kfzxF2ntMgbJvWGyUQ,1069
34
34
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  tests/integration_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
36
  tests/integration_tests/conftest.py,sha256=PWf6K1G3NoddebmDIy_Pk02dHQrEKfrNxpWwqE8Eqrk,546
@@ -63,7 +63,7 @@ tests/unit_tests/volume_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
63
63
  tests/unit_tests/volume_types/test_volume_types.py,sha256=vGuC3dWjhQLD8bTYgw_we3dZ6vlUKRmKZbb9yCfhe0w,1386
64
64
  tests/unit_tests/volumes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
65
  tests/unit_tests/volumes/test_volumes.py,sha256=p53eSIHddWKL7U9oLLTnxo849LrJSoi6A5lpWF6ydHs,20672
66
- datacrunch-1.13.2.dist-info/METADATA,sha256=ALmti6J4zvesLEDW3Jzqq2VDhjAJAQZgNfQzmO_BzUQ,6261
67
- datacrunch-1.13.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
68
- datacrunch-1.13.2.dist-info/top_level.txt,sha256=FvH4EZJkbUxNm-aKx0RjmWwnduAMpfRT13Fo123i7yE,17
69
- datacrunch-1.13.2.dist-info/RECORD,,
66
+ datacrunch-1.15.0.dist-info/METADATA,sha256=NYPMZAHvH2JmTs7fY37EXJM8hIamIT9rlZ_UgEljito,6212
67
+ datacrunch-1.15.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
68
+ datacrunch-1.15.0.dist-info/top_level.txt,sha256=FvH4EZJkbUxNm-aKx0RjmWwnduAMpfRT13Fo123i7yE,17
69
+ datacrunch-1.15.0.dist-info/RECORD,,