dstack 0.18.43__py3-none-any.whl → 0.19.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.
Files changed (278) hide show
  1. dstack/_internal/cli/commands/gateway.py +15 -3
  2. dstack/_internal/cli/commands/logs.py +0 -22
  3. dstack/_internal/cli/commands/stats.py +8 -17
  4. dstack/_internal/cli/main.py +1 -5
  5. dstack/_internal/cli/services/configurators/fleet.py +4 -39
  6. dstack/_internal/cli/services/configurators/run.py +22 -20
  7. dstack/_internal/cli/services/profile.py +34 -83
  8. dstack/_internal/cli/utils/gateway.py +1 -1
  9. dstack/_internal/cli/utils/run.py +11 -0
  10. dstack/_internal/core/backends/__init__.py +56 -39
  11. dstack/_internal/core/backends/aws/__init__.py +0 -25
  12. dstack/_internal/core/backends/aws/auth.py +1 -10
  13. dstack/_internal/core/backends/aws/backend.py +26 -0
  14. dstack/_internal/core/backends/aws/compute.py +21 -45
  15. dstack/_internal/{server/services/backends/configurators/aws.py → core/backends/aws/configurator.py} +46 -85
  16. dstack/_internal/core/backends/aws/models.py +135 -0
  17. dstack/_internal/core/backends/aws/resources.py +1 -1
  18. dstack/_internal/core/backends/azure/__init__.py +0 -20
  19. dstack/_internal/core/backends/azure/auth.py +2 -11
  20. dstack/_internal/core/backends/azure/backend.py +21 -0
  21. dstack/_internal/core/backends/azure/compute.py +14 -28
  22. dstack/_internal/{server/services/backends/configurators/azure.py → core/backends/azure/configurator.py} +141 -210
  23. dstack/_internal/core/backends/azure/models.py +89 -0
  24. dstack/_internal/core/backends/base/__init__.py +0 -12
  25. dstack/_internal/core/backends/base/backend.py +18 -0
  26. dstack/_internal/core/backends/base/compute.py +153 -33
  27. dstack/_internal/core/backends/base/configurator.py +105 -0
  28. dstack/_internal/core/backends/base/models.py +14 -0
  29. dstack/_internal/core/backends/configurators.py +138 -0
  30. dstack/_internal/core/backends/cudo/__init__.py +0 -15
  31. dstack/_internal/core/backends/cudo/backend.py +16 -0
  32. dstack/_internal/core/backends/cudo/compute.py +8 -26
  33. dstack/_internal/core/backends/cudo/configurator.py +72 -0
  34. dstack/_internal/core/backends/cudo/models.py +37 -0
  35. dstack/_internal/core/backends/datacrunch/__init__.py +0 -15
  36. dstack/_internal/core/backends/datacrunch/backend.py +16 -0
  37. dstack/_internal/core/backends/datacrunch/compute.py +8 -25
  38. dstack/_internal/core/backends/datacrunch/configurator.py +66 -0
  39. dstack/_internal/core/backends/datacrunch/models.py +38 -0
  40. dstack/_internal/core/{models/backends/dstack.py → backends/dstack/models.py} +7 -7
  41. dstack/_internal/core/backends/gcp/__init__.py +0 -16
  42. dstack/_internal/core/backends/gcp/auth.py +2 -11
  43. dstack/_internal/core/backends/gcp/backend.py +17 -0
  44. dstack/_internal/core/backends/gcp/compute.py +14 -44
  45. dstack/_internal/{server/services/backends/configurators/gcp.py → core/backends/gcp/configurator.py} +46 -103
  46. dstack/_internal/core/backends/gcp/models.py +125 -0
  47. dstack/_internal/core/backends/kubernetes/__init__.py +0 -15
  48. dstack/_internal/core/backends/kubernetes/backend.py +16 -0
  49. dstack/_internal/core/backends/kubernetes/compute.py +16 -5
  50. dstack/_internal/core/backends/kubernetes/configurator.py +55 -0
  51. dstack/_internal/core/backends/kubernetes/models.py +72 -0
  52. dstack/_internal/core/backends/lambdalabs/__init__.py +0 -16
  53. dstack/_internal/core/backends/lambdalabs/backend.py +17 -0
  54. dstack/_internal/core/backends/lambdalabs/compute.py +7 -28
  55. dstack/_internal/core/backends/lambdalabs/configurator.py +82 -0
  56. dstack/_internal/core/backends/lambdalabs/models.py +37 -0
  57. dstack/_internal/core/backends/local/__init__.py +0 -13
  58. dstack/_internal/core/backends/local/backend.py +14 -0
  59. dstack/_internal/core/backends/local/compute.py +16 -2
  60. dstack/_internal/core/backends/models.py +128 -0
  61. dstack/_internal/core/backends/oci/__init__.py +0 -15
  62. dstack/_internal/core/backends/oci/auth.py +1 -5
  63. dstack/_internal/core/backends/oci/backend.py +16 -0
  64. dstack/_internal/core/backends/oci/compute.py +9 -23
  65. dstack/_internal/{server/services/backends/configurators/oci.py → core/backends/oci/configurator.py} +40 -85
  66. dstack/_internal/core/{models/backends/oci.py → backends/oci/models.py} +24 -25
  67. dstack/_internal/core/backends/oci/region.py +1 -1
  68. dstack/_internal/core/backends/runpod/__init__.py +0 -15
  69. dstack/_internal/core/backends/runpod/backend.py +16 -0
  70. dstack/_internal/core/backends/runpod/compute.py +28 -6
  71. dstack/_internal/core/backends/runpod/configurator.py +59 -0
  72. dstack/_internal/core/backends/runpod/models.py +54 -0
  73. dstack/_internal/core/backends/template/__init__.py +0 -0
  74. dstack/_internal/core/backends/tensordock/__init__.py +0 -15
  75. dstack/_internal/core/backends/tensordock/backend.py +16 -0
  76. dstack/_internal/core/backends/tensordock/compute.py +8 -27
  77. dstack/_internal/core/backends/tensordock/configurator.py +68 -0
  78. dstack/_internal/core/backends/tensordock/models.py +38 -0
  79. dstack/_internal/core/backends/vastai/__init__.py +0 -15
  80. dstack/_internal/core/backends/vastai/backend.py +16 -0
  81. dstack/_internal/core/backends/vastai/compute.py +2 -2
  82. dstack/_internal/core/backends/vastai/configurator.py +66 -0
  83. dstack/_internal/core/backends/vastai/models.py +37 -0
  84. dstack/_internal/core/backends/vultr/__init__.py +0 -15
  85. dstack/_internal/core/backends/vultr/backend.py +16 -0
  86. dstack/_internal/core/backends/vultr/compute.py +10 -24
  87. dstack/_internal/core/backends/vultr/configurator.py +64 -0
  88. dstack/_internal/core/backends/vultr/models.py +34 -0
  89. dstack/_internal/core/models/backends/__init__.py +0 -184
  90. dstack/_internal/core/models/backends/base.py +0 -19
  91. dstack/_internal/core/models/configurations.py +22 -16
  92. dstack/_internal/core/models/envs.py +4 -3
  93. dstack/_internal/core/models/fleets.py +17 -22
  94. dstack/_internal/core/models/gateways.py +3 -3
  95. dstack/_internal/core/models/instances.py +24 -0
  96. dstack/_internal/core/models/profiles.py +85 -45
  97. dstack/_internal/core/models/projects.py +1 -1
  98. dstack/_internal/core/models/repos/base.py +0 -5
  99. dstack/_internal/core/models/repos/local.py +3 -3
  100. dstack/_internal/core/models/repos/remote.py +26 -12
  101. dstack/_internal/core/models/repos/virtual.py +1 -1
  102. dstack/_internal/core/models/resources.py +45 -76
  103. dstack/_internal/core/models/runs.py +21 -19
  104. dstack/_internal/core/models/volumes.py +1 -3
  105. dstack/_internal/core/services/profiles.py +7 -16
  106. dstack/_internal/core/services/repos.py +0 -4
  107. dstack/_internal/server/app.py +11 -4
  108. dstack/_internal/server/background/__init__.py +10 -0
  109. dstack/_internal/server/background/tasks/process_gateways.py +4 -8
  110. dstack/_internal/server/background/tasks/process_instances.py +14 -9
  111. dstack/_internal/server/background/tasks/process_metrics.py +1 -1
  112. dstack/_internal/server/background/tasks/process_placement_groups.py +5 -1
  113. dstack/_internal/server/background/tasks/process_prometheus_metrics.py +135 -0
  114. dstack/_internal/server/background/tasks/process_running_jobs.py +80 -24
  115. dstack/_internal/server/background/tasks/process_runs.py +1 -0
  116. dstack/_internal/server/background/tasks/process_submitted_jobs.py +20 -38
  117. dstack/_internal/server/background/tasks/process_volumes.py +5 -2
  118. dstack/_internal/server/migrations/versions/60e444118b6d_add_jobprometheusmetrics.py +40 -0
  119. dstack/_internal/server/migrations/versions/7bc2586e8b9e_make_instancemodel_pool_id_optional.py +36 -0
  120. dstack/_internal/server/migrations/versions/98d1b92988bc_add_jobterminationreason_terminated_due_.py +140 -0
  121. dstack/_internal/server/migrations/versions/bc8ca4a505c6_store_backendtype_as_string.py +171 -0
  122. dstack/_internal/server/models.py +59 -9
  123. dstack/_internal/server/routers/backends.py +14 -23
  124. dstack/_internal/server/routers/instances.py +3 -4
  125. dstack/_internal/server/routers/metrics.py +31 -10
  126. dstack/_internal/server/routers/prometheus.py +36 -0
  127. dstack/_internal/server/routers/repos.py +1 -2
  128. dstack/_internal/server/routers/runs.py +13 -59
  129. dstack/_internal/server/schemas/gateways.py +14 -23
  130. dstack/_internal/server/schemas/projects.py +7 -2
  131. dstack/_internal/server/schemas/repos.py +2 -38
  132. dstack/_internal/server/schemas/runner.py +1 -0
  133. dstack/_internal/server/schemas/runs.py +1 -24
  134. dstack/_internal/server/security/permissions.py +1 -1
  135. dstack/_internal/server/services/backends/__init__.py +85 -158
  136. dstack/_internal/server/services/config.py +53 -567
  137. dstack/_internal/server/services/fleets.py +9 -103
  138. dstack/_internal/server/services/gateways/__init__.py +13 -4
  139. dstack/_internal/server/services/{pools.py → instances.py} +22 -329
  140. dstack/_internal/server/services/jobs/__init__.py +9 -6
  141. dstack/_internal/server/services/jobs/configurators/base.py +25 -1
  142. dstack/_internal/server/services/jobs/configurators/dev.py +9 -1
  143. dstack/_internal/server/services/jobs/configurators/extensions/cursor.py +42 -0
  144. dstack/_internal/server/services/metrics.py +131 -72
  145. dstack/_internal/server/services/offers.py +1 -1
  146. dstack/_internal/server/services/projects.py +23 -14
  147. dstack/_internal/server/services/prometheus.py +245 -0
  148. dstack/_internal/server/services/runner/client.py +14 -3
  149. dstack/_internal/server/services/runs.py +67 -31
  150. dstack/_internal/server/services/volumes.py +9 -4
  151. dstack/_internal/server/settings.py +3 -0
  152. dstack/_internal/server/statics/index.html +1 -1
  153. dstack/_internal/server/statics/{main-fe8fd9db55df8d10e648.js → main-4a0fe83e84574654e397.js} +76 -19
  154. dstack/_internal/server/statics/{main-fe8fd9db55df8d10e648.js.map → main-4a0fe83e84574654e397.js.map} +1 -1
  155. dstack/_internal/server/statics/{main-7510e71dfa9749a4e70e.css → main-da9f8c06a69c20dac23e.css} +1 -1
  156. dstack/_internal/server/statics/static/media/entraID.d65d1f3e9486a8e56d24fc07b3230885.svg +9 -0
  157. dstack/_internal/server/testing/common.py +75 -32
  158. dstack/_internal/utils/json_schema.py +6 -0
  159. dstack/_internal/utils/ssh.py +2 -1
  160. dstack/api/__init__.py +4 -0
  161. dstack/api/_public/__init__.py +16 -20
  162. dstack/api/_public/backends.py +1 -1
  163. dstack/api/_public/repos.py +36 -36
  164. dstack/api/_public/runs.py +170 -83
  165. dstack/api/server/__init__.py +11 -13
  166. dstack/api/server/_backends.py +12 -16
  167. dstack/api/server/_fleets.py +15 -55
  168. dstack/api/server/_gateways.py +3 -14
  169. dstack/api/server/_repos.py +1 -4
  170. dstack/api/server/_runs.py +21 -96
  171. dstack/api/server/_volumes.py +10 -5
  172. dstack/api/utils.py +3 -0
  173. dstack/version.py +1 -1
  174. {dstack-0.18.43.dist-info → dstack-0.19.0.dist-info}/METADATA +10 -1
  175. {dstack-0.18.43.dist-info → dstack-0.19.0.dist-info}/RECORD +229 -206
  176. tests/_internal/cli/services/configurators/test_profile.py +6 -6
  177. tests/_internal/core/backends/aws/test_configurator.py +35 -0
  178. tests/_internal/core/backends/aws/test_resources.py +1 -1
  179. tests/_internal/core/backends/azure/test_configurator.py +61 -0
  180. tests/_internal/core/backends/cudo/__init__.py +0 -0
  181. tests/_internal/core/backends/cudo/test_configurator.py +37 -0
  182. tests/_internal/core/backends/datacrunch/__init__.py +0 -0
  183. tests/_internal/core/backends/datacrunch/test_configurator.py +17 -0
  184. tests/_internal/core/backends/gcp/test_configurator.py +42 -0
  185. tests/_internal/core/backends/kubernetes/test_configurator.py +43 -0
  186. tests/_internal/core/backends/lambdalabs/__init__.py +0 -0
  187. tests/_internal/core/backends/lambdalabs/test_configurator.py +38 -0
  188. tests/_internal/core/backends/oci/test_configurator.py +55 -0
  189. tests/_internal/core/backends/runpod/__init__.py +0 -0
  190. tests/_internal/core/backends/runpod/test_configurator.py +33 -0
  191. tests/_internal/core/backends/tensordock/__init__.py +0 -0
  192. tests/_internal/core/backends/tensordock/test_configurator.py +38 -0
  193. tests/_internal/core/backends/vastai/__init__.py +0 -0
  194. tests/_internal/core/backends/vastai/test_configurator.py +33 -0
  195. tests/_internal/core/backends/vultr/__init__.py +0 -0
  196. tests/_internal/core/backends/vultr/test_configurator.py +33 -0
  197. tests/_internal/server/background/tasks/test_process_gateways.py +4 -0
  198. tests/_internal/server/background/tasks/test_process_instances.py +49 -48
  199. tests/_internal/server/background/tasks/test_process_metrics.py +0 -3
  200. tests/_internal/server/background/tasks/test_process_placement_groups.py +2 -0
  201. tests/_internal/server/background/tasks/test_process_prometheus_metrics.py +186 -0
  202. tests/_internal/server/background/tasks/test_process_running_jobs.py +123 -19
  203. tests/_internal/server/background/tasks/test_process_runs.py +8 -22
  204. tests/_internal/server/background/tasks/test_process_submitted_jobs.py +3 -40
  205. tests/_internal/server/background/tasks/test_process_submitted_volumes.py +2 -0
  206. tests/_internal/server/background/tasks/test_process_terminating_jobs.py +10 -15
  207. tests/_internal/server/routers/test_backends.py +6 -764
  208. tests/_internal/server/routers/test_fleets.py +2 -26
  209. tests/_internal/server/routers/test_gateways.py +27 -3
  210. tests/_internal/server/routers/test_instances.py +0 -10
  211. tests/_internal/server/routers/test_metrics.py +42 -0
  212. tests/_internal/server/routers/test_projects.py +56 -0
  213. tests/_internal/server/routers/test_prometheus.py +333 -0
  214. tests/_internal/server/routers/test_repos.py +0 -15
  215. tests/_internal/server/routers/test_runs.py +83 -275
  216. tests/_internal/server/routers/test_volumes.py +2 -3
  217. tests/_internal/server/services/backends/__init__.py +0 -0
  218. tests/_internal/server/services/jobs/configurators/test_task.py +35 -0
  219. tests/_internal/server/services/test_config.py +7 -4
  220. tests/_internal/server/services/test_fleets.py +1 -4
  221. tests/_internal/server/services/{test_pools.py → test_instances.py} +11 -49
  222. tests/_internal/server/services/test_metrics.py +167 -0
  223. tests/_internal/server/services/test_repos.py +1 -14
  224. tests/_internal/server/services/test_runs.py +0 -4
  225. dstack/_internal/cli/commands/pool.py +0 -581
  226. dstack/_internal/cli/commands/run.py +0 -75
  227. dstack/_internal/core/backends/aws/config.py +0 -18
  228. dstack/_internal/core/backends/azure/config.py +0 -12
  229. dstack/_internal/core/backends/base/config.py +0 -5
  230. dstack/_internal/core/backends/cudo/config.py +0 -9
  231. dstack/_internal/core/backends/datacrunch/config.py +0 -9
  232. dstack/_internal/core/backends/gcp/config.py +0 -22
  233. dstack/_internal/core/backends/kubernetes/config.py +0 -6
  234. dstack/_internal/core/backends/lambdalabs/config.py +0 -9
  235. dstack/_internal/core/backends/nebius/__init__.py +0 -15
  236. dstack/_internal/core/backends/nebius/api_client.py +0 -319
  237. dstack/_internal/core/backends/nebius/compute.py +0 -220
  238. dstack/_internal/core/backends/nebius/config.py +0 -6
  239. dstack/_internal/core/backends/nebius/types.py +0 -37
  240. dstack/_internal/core/backends/oci/config.py +0 -6
  241. dstack/_internal/core/backends/runpod/config.py +0 -9
  242. dstack/_internal/core/backends/tensordock/config.py +0 -9
  243. dstack/_internal/core/backends/vastai/config.py +0 -6
  244. dstack/_internal/core/backends/vultr/config.py +0 -9
  245. dstack/_internal/core/models/backends/aws.py +0 -86
  246. dstack/_internal/core/models/backends/azure.py +0 -68
  247. dstack/_internal/core/models/backends/cudo.py +0 -43
  248. dstack/_internal/core/models/backends/datacrunch.py +0 -44
  249. dstack/_internal/core/models/backends/gcp.py +0 -67
  250. dstack/_internal/core/models/backends/kubernetes.py +0 -40
  251. dstack/_internal/core/models/backends/lambdalabs.py +0 -43
  252. dstack/_internal/core/models/backends/nebius.py +0 -54
  253. dstack/_internal/core/models/backends/runpod.py +0 -40
  254. dstack/_internal/core/models/backends/tensordock.py +0 -44
  255. dstack/_internal/core/models/backends/vastai.py +0 -43
  256. dstack/_internal/core/models/backends/vultr.py +0 -40
  257. dstack/_internal/core/models/pools.py +0 -43
  258. dstack/_internal/server/routers/pools.py +0 -142
  259. dstack/_internal/server/schemas/pools.py +0 -38
  260. dstack/_internal/server/services/backends/configurators/base.py +0 -72
  261. dstack/_internal/server/services/backends/configurators/cudo.py +0 -87
  262. dstack/_internal/server/services/backends/configurators/datacrunch.py +0 -79
  263. dstack/_internal/server/services/backends/configurators/kubernetes.py +0 -63
  264. dstack/_internal/server/services/backends/configurators/lambdalabs.py +0 -98
  265. dstack/_internal/server/services/backends/configurators/nebius.py +0 -85
  266. dstack/_internal/server/services/backends/configurators/runpod.py +0 -97
  267. dstack/_internal/server/services/backends/configurators/tensordock.py +0 -82
  268. dstack/_internal/server/services/backends/configurators/vastai.py +0 -80
  269. dstack/_internal/server/services/backends/configurators/vultr.py +0 -80
  270. dstack/api/_public/pools.py +0 -41
  271. dstack/api/_public/resources.py +0 -105
  272. dstack/api/server/_pools.py +0 -63
  273. tests/_internal/server/routers/test_pools.py +0 -612
  274. /dstack/_internal/{server/services/backends/configurators → core/backends/dstack}/__init__.py +0 -0
  275. {dstack-0.18.43.dist-info → dstack-0.19.0.dist-info}/LICENSE.md +0 -0
  276. {dstack-0.18.43.dist-info → dstack-0.19.0.dist-info}/WHEEL +0 -0
  277. {dstack-0.18.43.dist-info → dstack-0.19.0.dist-info}/entry_points.txt +0 -0
  278. {dstack-0.18.43.dist-info → dstack-0.19.0.dist-info}/top_level.txt +0 -0
@@ -1,36 +1,22 @@
1
1
  from datetime import datetime
2
- from typing import Any, List, Optional, Union
2
+ from typing import Any, Dict, List, Optional, Union
3
3
  from uuid import UUID
4
4
 
5
5
  from pydantic import parse_obj_as
6
6
 
7
- from dstack._internal.core.models.common import is_core_model_instance
8
- from dstack._internal.core.models.configurations import (
9
- STRIP_PREFIX_DEFAULT,
10
- DevEnvironmentConfiguration,
11
- ServiceConfiguration,
12
- )
13
- from dstack._internal.core.models.pools import Instance
14
- from dstack._internal.core.models.profiles import Profile
15
7
  from dstack._internal.core.models.runs import (
16
8
  ApplyRunPlanInput,
17
- PoolInstanceOffers,
18
- Requirements,
19
9
  Run,
20
10
  RunPlan,
21
11
  RunSpec,
22
12
  )
23
- from dstack._internal.core.models.volumes import InstanceMountPoint
24
13
  from dstack._internal.server.schemas.runs import (
25
14
  ApplyRunPlanRequest,
26
- CreateInstanceRequest,
27
15
  DeleteRunsRequest,
28
- GetOffersRequest,
29
16
  GetRunPlanRequest,
30
17
  GetRunRequest,
31
18
  ListRunsRequest,
32
19
  StopRunsRequest,
33
- SubmitRunRequest,
34
20
  )
35
21
  from dstack.api.server._group import APIClientGroup
36
22
 
@@ -62,8 +48,7 @@ class RunsAPIClient(APIClientGroup):
62
48
 
63
49
  def get(self, project_name: str, run_name: str) -> Run:
64
50
  body = GetRunRequest(run_name=run_name)
65
- # dstack versions prior to 0.18.34 don't support id field, and we don't use it here either
66
- json_body = body.json(exclude={"id"})
51
+ json_body = body.json()
67
52
  resp = self._request(f"/api/project/{project_name}/runs/get", body=json_body)
68
53
  return parse_obj_as(Run.__response__, resp.json())
69
54
 
@@ -89,14 +74,6 @@ class RunsAPIClient(APIClientGroup):
89
74
  )
90
75
  return parse_obj_as(Run.__response__, resp.json())
91
76
 
92
- def submit(self, project_name: str, run_spec: RunSpec) -> Run:
93
- body = SubmitRunRequest(run_spec=run_spec)
94
- resp = self._request(
95
- f"/api/project/{project_name}/runs/submit",
96
- body=body.json(exclude=_get_run_spec_excludes(run_spec)),
97
- )
98
- return parse_obj_as(Run.__response__, resp.json())
99
-
100
77
  def stop(self, project_name: str, runs_names: List[str], abort: bool):
101
78
  body = StopRunsRequest(runs_names=runs_names, abort=abort)
102
79
  self._request(f"/api/project/{project_name}/runs/stop", body=body.json())
@@ -105,87 +82,35 @@ class RunsAPIClient(APIClientGroup):
105
82
  body = DeleteRunsRequest(runs_names=runs_names)
106
83
  self._request(f"/api/project/{project_name}/runs/delete", body=body.json())
107
84
 
108
- # FIXME: get_offers and create_instance do not belong runs api
109
-
110
- def get_offers(
111
- self, project_name: str, profile: Profile, requirements: Requirements
112
- ) -> PoolInstanceOffers:
113
- body = GetOffersRequest(profile=profile, requirements=requirements)
114
- resp = self._request(f"/api/project/{project_name}/runs/get_offers", body=body.json())
115
- return parse_obj_as(PoolInstanceOffers.__response__, resp.json())
116
85
 
117
- def create_instance(
118
- self,
119
- project_name: str,
120
- profile: Profile,
121
- requirements: Requirements,
122
- ) -> Instance:
123
- body = CreateInstanceRequest(profile=profile, requirements=requirements)
124
- resp = self._request(f"/api/project/{project_name}/runs/create_instance", body=body.json())
125
- return parse_obj_as(Instance.__response__, resp.json())
126
-
127
-
128
- def _get_apply_plan_excludes(plan: ApplyRunPlanInput) -> Optional[dict]:
86
+ def _get_apply_plan_excludes(plan: ApplyRunPlanInput) -> Optional[Dict]:
87
+ """
88
+ Returns `plan` exclude mapping to exclude certain fields from the request.
89
+ Use this method to exclude new fields when they are not set to keep
90
+ clients backward-compatibility with older servers.
91
+ """
129
92
  run_spec_excludes = _get_run_spec_excludes(plan.run_spec)
130
93
  if run_spec_excludes is not None:
131
94
  return {"plan": run_spec_excludes}
132
95
  return None
133
96
 
134
97
 
135
- def _get_run_spec_excludes(run_spec: RunSpec) -> Optional[dict]:
98
+ def _get_run_spec_excludes(run_spec: RunSpec) -> Optional[Dict]:
99
+ """
100
+ Returns `run_spec` exclude mapping to exclude certain fields from the request.
101
+ Use this method to exclude new fields when they are not set to keep
102
+ clients backward-compatibility with older servers.
103
+ """
136
104
  spec_excludes: dict[str, Any] = {}
137
105
  configuration_excludes: dict[str, Any] = {}
138
106
  profile_excludes: set[str] = set()
139
- configuration = run_spec.configuration
140
- profile = run_spec.profile
141
-
142
- # client >= 0.18.18 / server <= 0.18.17 compatibility tweak
143
- if not configuration.privileged:
144
- configuration_excludes["privileged"] = True
145
- # client >= 0.18.23 / server <= 0.18.22 compatibility tweak
146
- if configuration.type == "service" and configuration.gateway is None:
147
- configuration_excludes["gateway"] = True
148
- # client >= 0.18.30 / server <= 0.18.29 compatibility tweak
149
- if run_spec.configuration.user is None:
150
- configuration_excludes["user"] = True
151
- # client >= 0.18.30 / server <= 0.18.29 compatibility tweak
152
- if configuration.reservation is None:
153
- configuration_excludes["reservation"] = True
154
- if profile is not None and profile.reservation is None:
155
- profile_excludes.add("reservation")
156
- if configuration.idle_duration is None:
157
- configuration_excludes["idle_duration"] = True
158
- if profile is not None and profile.idle_duration is None:
159
- profile_excludes.add("idle_duration")
160
- # client >= 0.18.38 / server <= 0.18.37 compatibility tweak
161
- if configuration.stop_duration is None:
162
- configuration_excludes["stop_duration"] = True
163
- if profile is not None and profile.stop_duration is None:
164
- profile_excludes.add("stop_duration")
165
- # client >= 0.18.40 / server <= 0.18.39 compatibility tweak
166
- if (
167
- is_core_model_instance(configuration, ServiceConfiguration)
168
- and configuration.strip_prefix == STRIP_PREFIX_DEFAULT
169
- ):
170
- configuration_excludes["strip_prefix"] = True
171
- if configuration.single_branch is None:
172
- configuration_excludes["single_branch"] = True
173
- if all(
174
- not is_core_model_instance(v, InstanceMountPoint) or not v.optional
175
- for v in configuration.volumes
176
- ):
177
- configuration_excludes["volumes"] = {"__all__": {"optional"}}
178
- # client >= 0.18.41 / server <= 0.18.40 compatibility tweak
179
- if configuration.availability_zones is None:
180
- configuration_excludes["availability_zones"] = True
181
- if profile is not None and profile.availability_zones is None:
182
- profile_excludes.add("availability_zones")
183
- if (
184
- is_core_model_instance(configuration, DevEnvironmentConfiguration)
185
- and configuration.inactivity_duration is None
186
- ):
187
- configuration_excludes["inactivity_duration"] = True
188
-
107
+ # configuration = run_spec.configuration
108
+ # profile = run_spec.profile
109
+ # Fields can be excluded like this:
110
+ # if configuration.availability_zones is None:
111
+ # configuration_excludes["availability_zones"] = True
112
+ # if profile is not None and profile.availability_zones is None:
113
+ # profile_excludes.add("availability_zones")
189
114
  if configuration_excludes:
190
115
  spec_excludes["configuration"] = configuration_excludes
191
116
  if profile_excludes:
@@ -1,4 +1,4 @@
1
- from typing import List
1
+ from typing import Dict, List
2
2
 
3
3
  from pydantic import parse_obj_as
4
4
 
@@ -38,9 +38,14 @@ class VolumesAPIClient(APIClientGroup):
38
38
  self._request(f"/api/project/{project_name}/volumes/delete", body=body.json())
39
39
 
40
40
 
41
- def _get_volume_configuration_excludes(configuration: VolumeConfiguration) -> dict:
41
+ def _get_volume_configuration_excludes(configuration: VolumeConfiguration) -> Dict:
42
+ """
43
+ Returns `configuration` exclude mapping to exclude certain fields from the request.
44
+ Use this method to exclude new fields when they are not set to keep
45
+ clients backward-compatibility with older servers.
46
+ """
42
47
  configuration_excludes = {}
43
- # client >= 0.18.41 / server <= 0.18.40 compatibility tweak
44
- if configuration.availability_zone is None:
45
- configuration_excludes["availability_zone"] = True
48
+ # Fields can be excluded like this:
49
+ # if configuration.availability_zone is None:
50
+ # configuration_excludes["availability_zone"] = True
46
51
  return {"configuration": configuration_excludes}
dstack/api/utils.py CHANGED
@@ -2,6 +2,7 @@ from pathlib import Path
2
2
  from typing import Optional, Tuple
3
3
 
4
4
  import yaml
5
+ from pydantic import ValidationError
5
6
 
6
7
  from dstack._internal.core.errors import ConfigurationError
7
8
  from dstack._internal.core.models.configurations import AnyRunConfiguration
@@ -96,6 +97,8 @@ def _load_profile_from_path(profiles_path: Path, profile_name: Optional[str]) ->
96
97
  config = ProfilesConfig.parse_obj(yaml.safe_load(f))
97
98
  except FileNotFoundError:
98
99
  return None
100
+ except ValidationError as e:
101
+ raise ConfigurationError(e)
99
102
 
100
103
  if profile_name is None:
101
104
  return config.default()
dstack/version.py CHANGED
@@ -1,3 +1,3 @@
1
- __version__ = "0.18.43"
1
+ __version__ = "0.19.0"
2
2
  __is_release__ = True
3
3
  base_image = "0.7"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dstack
3
- Version: 0.18.43
3
+ Version: 0.19.0
4
4
  Summary: dstack is an open-source orchestration engine for running AI workloads on any cloud or on-premises.
5
5
  Home-page: https://dstack.ai
6
6
  Author: Andrey Cheptsov
@@ -60,6 +60,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "all"
60
60
  Requires-Dist: asyncpg; extra == "all"
61
61
  Requires-Dist: cachetools; extra == "all"
62
62
  Requires-Dist: python-json-logger>=3.1.0; extra == "all"
63
+ Requires-Dist: prometheus-client; extra == "all"
63
64
  Requires-Dist: grpcio>=1.50; extra == "all"
64
65
  Requires-Dist: boto3; extra == "all"
65
66
  Requires-Dist: botocore; extra == "all"
@@ -100,6 +101,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "aws"
100
101
  Requires-Dist: asyncpg; extra == "aws"
101
102
  Requires-Dist: cachetools; extra == "aws"
102
103
  Requires-Dist: python-json-logger>=3.1.0; extra == "aws"
104
+ Requires-Dist: prometheus-client; extra == "aws"
103
105
  Requires-Dist: grpcio>=1.50; extra == "aws"
104
106
  Requires-Dist: boto3; extra == "aws"
105
107
  Requires-Dist: botocore; extra == "aws"
@@ -124,6 +126,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "azure"
124
126
  Requires-Dist: asyncpg; extra == "azure"
125
127
  Requires-Dist: cachetools; extra == "azure"
126
128
  Requires-Dist: python-json-logger>=3.1.0; extra == "azure"
129
+ Requires-Dist: prometheus-client; extra == "azure"
127
130
  Requires-Dist: grpcio>=1.50; extra == "azure"
128
131
  Requires-Dist: azure-identity>=1.12.0; extra == "azure"
129
132
  Requires-Dist: azure-mgmt-subscription>=3.1.1; extra == "azure"
@@ -152,6 +155,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "datacrunch"
152
155
  Requires-Dist: asyncpg; extra == "datacrunch"
153
156
  Requires-Dist: cachetools; extra == "datacrunch"
154
157
  Requires-Dist: python-json-logger>=3.1.0; extra == "datacrunch"
158
+ Requires-Dist: prometheus-client; extra == "datacrunch"
155
159
  Requires-Dist: grpcio>=1.50; extra == "datacrunch"
156
160
  Requires-Dist: datacrunch; extra == "datacrunch"
157
161
  Provides-Extra: gateway
@@ -183,6 +187,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "gcp"
183
187
  Requires-Dist: asyncpg; extra == "gcp"
184
188
  Requires-Dist: cachetools; extra == "gcp"
185
189
  Requires-Dist: python-json-logger>=3.1.0; extra == "gcp"
190
+ Requires-Dist: prometheus-client; extra == "gcp"
186
191
  Requires-Dist: grpcio>=1.50; extra == "gcp"
187
192
  Requires-Dist: google-auth>=2.3.0; extra == "gcp"
188
193
  Requires-Dist: google-cloud-storage>=2.0.0; extra == "gcp"
@@ -212,6 +217,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "kubernetes"
212
217
  Requires-Dist: asyncpg; extra == "kubernetes"
213
218
  Requires-Dist: cachetools; extra == "kubernetes"
214
219
  Requires-Dist: python-json-logger>=3.1.0; extra == "kubernetes"
220
+ Requires-Dist: prometheus-client; extra == "kubernetes"
215
221
  Requires-Dist: grpcio>=1.50; extra == "kubernetes"
216
222
  Requires-Dist: kubernetes; extra == "kubernetes"
217
223
  Provides-Extra: lambda
@@ -235,6 +241,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "lambda"
235
241
  Requires-Dist: asyncpg; extra == "lambda"
236
242
  Requires-Dist: cachetools; extra == "lambda"
237
243
  Requires-Dist: python-json-logger>=3.1.0; extra == "lambda"
244
+ Requires-Dist: prometheus-client; extra == "lambda"
238
245
  Requires-Dist: grpcio>=1.50; extra == "lambda"
239
246
  Requires-Dist: boto3; extra == "lambda"
240
247
  Requires-Dist: botocore; extra == "lambda"
@@ -259,6 +266,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "oci"
259
266
  Requires-Dist: asyncpg; extra == "oci"
260
267
  Requires-Dist: cachetools; extra == "oci"
261
268
  Requires-Dist: python-json-logger>=3.1.0; extra == "oci"
269
+ Requires-Dist: prometheus-client; extra == "oci"
262
270
  Requires-Dist: grpcio>=1.50; extra == "oci"
263
271
  Requires-Dist: oci; extra == "oci"
264
272
  Provides-Extra: server
@@ -282,6 +290,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "server"
282
290
  Requires-Dist: asyncpg; extra == "server"
283
291
  Requires-Dist: cachetools; extra == "server"
284
292
  Requires-Dist: python-json-logger>=3.1.0; extra == "server"
293
+ Requires-Dist: prometheus-client; extra == "server"
285
294
  Requires-Dist: grpcio>=1.50; extra == "server"
286
295
 
287
296
  <div style="text-align: center;">