dstack 0.19.25rc1__py3-none-any.whl → 0.19.26__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.
Potentially problematic release.
This version of dstack might be problematic. Click here for more details.
- dstack/_internal/cli/commands/__init__.py +2 -2
- dstack/_internal/cli/commands/apply.py +3 -61
- dstack/_internal/cli/commands/attach.py +1 -1
- dstack/_internal/cli/commands/completion.py +1 -1
- dstack/_internal/cli/commands/delete.py +2 -2
- dstack/_internal/cli/commands/fleet.py +1 -1
- dstack/_internal/cli/commands/gateway.py +2 -2
- dstack/_internal/cli/commands/init.py +56 -24
- dstack/_internal/cli/commands/logs.py +1 -1
- dstack/_internal/cli/commands/metrics.py +1 -1
- dstack/_internal/cli/commands/offer.py +45 -7
- dstack/_internal/cli/commands/project.py +2 -2
- dstack/_internal/cli/commands/secrets.py +2 -2
- dstack/_internal/cli/commands/server.py +1 -1
- dstack/_internal/cli/commands/stop.py +1 -1
- dstack/_internal/cli/commands/volume.py +1 -1
- dstack/_internal/cli/main.py +2 -2
- dstack/_internal/cli/services/completion.py +2 -2
- dstack/_internal/cli/services/configurators/__init__.py +6 -2
- dstack/_internal/cli/services/configurators/base.py +6 -7
- dstack/_internal/cli/services/configurators/fleet.py +1 -3
- dstack/_internal/cli/services/configurators/gateway.py +2 -4
- dstack/_internal/cli/services/configurators/run.py +195 -58
- dstack/_internal/cli/services/configurators/volume.py +2 -4
- dstack/_internal/cli/services/profile.py +1 -1
- dstack/_internal/cli/services/repos.py +51 -47
- dstack/_internal/core/backends/aws/configurator.py +11 -7
- dstack/_internal/core/backends/azure/configurator.py +11 -7
- dstack/_internal/core/backends/base/configurator.py +25 -13
- dstack/_internal/core/backends/cloudrift/configurator.py +13 -7
- dstack/_internal/core/backends/cudo/configurator.py +11 -7
- dstack/_internal/core/backends/datacrunch/compute.py +5 -1
- dstack/_internal/core/backends/datacrunch/configurator.py +13 -7
- dstack/_internal/core/backends/gcp/configurator.py +11 -7
- dstack/_internal/core/backends/hotaisle/configurator.py +13 -7
- dstack/_internal/core/backends/kubernetes/configurator.py +13 -7
- dstack/_internal/core/backends/lambdalabs/configurator.py +11 -7
- dstack/_internal/core/backends/nebius/compute.py +1 -1
- dstack/_internal/core/backends/nebius/configurator.py +11 -7
- dstack/_internal/core/backends/nebius/resources.py +21 -11
- dstack/_internal/core/backends/oci/configurator.py +11 -7
- dstack/_internal/core/backends/runpod/configurator.py +11 -7
- dstack/_internal/core/backends/template/configurator.py.jinja +11 -7
- dstack/_internal/core/backends/tensordock/configurator.py +13 -7
- dstack/_internal/core/backends/vastai/configurator.py +11 -7
- dstack/_internal/core/backends/vultr/configurator.py +11 -4
- dstack/_internal/core/compatibility/gpus.py +13 -0
- dstack/_internal/core/compatibility/runs.py +1 -0
- dstack/_internal/core/models/common.py +3 -3
- dstack/_internal/core/models/configurations.py +172 -27
- dstack/_internal/core/models/files.py +1 -1
- dstack/_internal/core/models/fleets.py +5 -1
- dstack/_internal/core/models/profiles.py +41 -11
- dstack/_internal/core/models/resources.py +46 -42
- dstack/_internal/core/models/runs.py +4 -0
- dstack/_internal/core/services/configs/__init__.py +6 -3
- dstack/_internal/core/services/profiles.py +2 -2
- dstack/_internal/core/services/repos.py +5 -3
- dstack/_internal/core/services/ssh/ports.py +1 -1
- dstack/_internal/proxy/lib/deps.py +6 -2
- dstack/_internal/server/app.py +22 -17
- dstack/_internal/server/background/tasks/process_gateways.py +4 -1
- dstack/_internal/server/background/tasks/process_instances.py +10 -2
- dstack/_internal/server/background/tasks/process_probes.py +1 -1
- dstack/_internal/server/background/tasks/process_running_jobs.py +10 -4
- dstack/_internal/server/background/tasks/process_runs.py +1 -1
- dstack/_internal/server/background/tasks/process_submitted_jobs.py +54 -43
- dstack/_internal/server/background/tasks/process_terminating_jobs.py +2 -2
- dstack/_internal/server/background/tasks/process_volumes.py +1 -1
- dstack/_internal/server/db.py +8 -4
- dstack/_internal/server/models.py +1 -0
- dstack/_internal/server/routers/gpus.py +1 -6
- dstack/_internal/server/schemas/runner.py +10 -0
- dstack/_internal/server/services/backends/__init__.py +14 -8
- dstack/_internal/server/services/backends/handlers.py +6 -1
- dstack/_internal/server/services/docker.py +5 -5
- dstack/_internal/server/services/fleets.py +14 -13
- dstack/_internal/server/services/gateways/__init__.py +2 -0
- dstack/_internal/server/services/gateways/client.py +5 -2
- dstack/_internal/server/services/gateways/connection.py +1 -1
- dstack/_internal/server/services/gpus.py +50 -49
- dstack/_internal/server/services/instances.py +41 -1
- dstack/_internal/server/services/jobs/__init__.py +15 -4
- dstack/_internal/server/services/jobs/configurators/base.py +7 -11
- dstack/_internal/server/services/jobs/configurators/dev.py +5 -0
- dstack/_internal/server/services/jobs/configurators/extensions/cursor.py +3 -3
- dstack/_internal/server/services/jobs/configurators/extensions/vscode.py +3 -3
- dstack/_internal/server/services/jobs/configurators/service.py +1 -0
- dstack/_internal/server/services/jobs/configurators/task.py +3 -0
- dstack/_internal/server/services/locking.py +5 -5
- dstack/_internal/server/services/logging.py +10 -2
- dstack/_internal/server/services/logs/__init__.py +8 -6
- dstack/_internal/server/services/logs/aws.py +330 -327
- dstack/_internal/server/services/logs/filelog.py +7 -6
- dstack/_internal/server/services/logs/gcp.py +141 -139
- dstack/_internal/server/services/plugins.py +1 -1
- dstack/_internal/server/services/projects.py +2 -5
- dstack/_internal/server/services/proxy/repo.py +5 -1
- dstack/_internal/server/services/requirements/__init__.py +0 -0
- dstack/_internal/server/services/requirements/combine.py +259 -0
- dstack/_internal/server/services/runner/client.py +7 -0
- dstack/_internal/server/services/runs.py +1 -1
- dstack/_internal/server/services/services/__init__.py +8 -2
- dstack/_internal/server/services/services/autoscalers.py +2 -0
- dstack/_internal/server/services/ssh.py +2 -1
- dstack/_internal/server/services/storage/__init__.py +5 -6
- dstack/_internal/server/services/storage/gcs.py +49 -49
- dstack/_internal/server/services/storage/s3.py +52 -52
- dstack/_internal/server/statics/index.html +1 -1
- dstack/_internal/server/testing/common.py +1 -1
- dstack/_internal/server/utils/logging.py +3 -3
- dstack/_internal/server/utils/provisioning.py +3 -3
- dstack/_internal/utils/json_schema.py +3 -1
- dstack/_internal/utils/typing.py +14 -0
- dstack/api/_public/repos.py +21 -2
- dstack/api/_public/runs.py +5 -7
- dstack/api/server/__init__.py +17 -19
- dstack/api/server/_gpus.py +2 -1
- dstack/api/server/_group.py +4 -3
- dstack/api/server/_repos.py +20 -3
- dstack/plugins/builtin/rest_plugin/_plugin.py +1 -0
- dstack/version.py +1 -1
- {dstack-0.19.25rc1.dist-info → dstack-0.19.26.dist-info}/METADATA +1 -1
- {dstack-0.19.25rc1.dist-info → dstack-0.19.26.dist-info}/RECORD +127 -124
- dstack/api/huggingface/__init__.py +0 -73
- {dstack-0.19.25rc1.dist-info → dstack-0.19.26.dist-info}/WHEEL +0 -0
- {dstack-0.19.25rc1.dist-info → dstack-0.19.26.dist-info}/entry_points.txt +0 -0
- {dstack-0.19.25rc1.dist-info → dstack-0.19.26.dist-info}/licenses/LICENSE.md +0 -0
dstack/api/server/__init__.py
CHANGED
|
@@ -27,9 +27,6 @@ from dstack.api.server._secrets import SecretsAPIClient
|
|
|
27
27
|
from dstack.api.server._users import UsersAPIClient
|
|
28
28
|
from dstack.api.server._volumes import VolumesAPIClient
|
|
29
29
|
|
|
30
|
-
logger = get_logger(__name__)
|
|
31
|
-
|
|
32
|
-
|
|
33
30
|
_MAX_RETRIES = 3
|
|
34
31
|
_RETRY_INTERVAL = 1
|
|
35
32
|
|
|
@@ -66,6 +63,7 @@ class APIClient:
|
|
|
66
63
|
client_api_version = os.getenv("DSTACK_CLIENT_API_VERSION", version.__version__)
|
|
67
64
|
if client_api_version is not None:
|
|
68
65
|
self._s.headers.update({"X-API-VERSION": client_api_version})
|
|
66
|
+
self._logger = get_logger(__name__)
|
|
69
67
|
|
|
70
68
|
@property
|
|
71
69
|
def base_url(self) -> str:
|
|
@@ -73,55 +71,55 @@ class APIClient:
|
|
|
73
71
|
|
|
74
72
|
@property
|
|
75
73
|
def users(self) -> UsersAPIClient:
|
|
76
|
-
return UsersAPIClient(self._request)
|
|
74
|
+
return UsersAPIClient(self._request, self._logger)
|
|
77
75
|
|
|
78
76
|
@property
|
|
79
77
|
def projects(self) -> ProjectsAPIClient:
|
|
80
|
-
return ProjectsAPIClient(self._request)
|
|
78
|
+
return ProjectsAPIClient(self._request, self._logger)
|
|
81
79
|
|
|
82
80
|
@property
|
|
83
81
|
def backends(self) -> BackendsAPIClient:
|
|
84
|
-
return BackendsAPIClient(self._request)
|
|
82
|
+
return BackendsAPIClient(self._request, self._logger)
|
|
85
83
|
|
|
86
84
|
@property
|
|
87
85
|
def fleets(self) -> FleetsAPIClient:
|
|
88
|
-
return FleetsAPIClient(self._request)
|
|
86
|
+
return FleetsAPIClient(self._request, self._logger)
|
|
89
87
|
|
|
90
88
|
@property
|
|
91
89
|
def repos(self) -> ReposAPIClient:
|
|
92
|
-
return ReposAPIClient(self._request)
|
|
90
|
+
return ReposAPIClient(self._request, self._logger)
|
|
93
91
|
|
|
94
92
|
@property
|
|
95
93
|
def runs(self) -> RunsAPIClient:
|
|
96
|
-
return RunsAPIClient(self._request)
|
|
94
|
+
return RunsAPIClient(self._request, self._logger)
|
|
97
95
|
|
|
98
96
|
@property
|
|
99
97
|
def gpus(self) -> GpusAPIClient:
|
|
100
|
-
return GpusAPIClient(self._request)
|
|
98
|
+
return GpusAPIClient(self._request, self._logger)
|
|
101
99
|
|
|
102
100
|
@property
|
|
103
101
|
def metrics(self) -> MetricsAPIClient:
|
|
104
|
-
return MetricsAPIClient(self._request)
|
|
102
|
+
return MetricsAPIClient(self._request, self._logger)
|
|
105
103
|
|
|
106
104
|
@property
|
|
107
105
|
def logs(self) -> LogsAPIClient:
|
|
108
|
-
return LogsAPIClient(self._request)
|
|
106
|
+
return LogsAPIClient(self._request, self._logger)
|
|
109
107
|
|
|
110
108
|
@property
|
|
111
109
|
def secrets(self) -> SecretsAPIClient:
|
|
112
|
-
return SecretsAPIClient(self._request)
|
|
110
|
+
return SecretsAPIClient(self._request, self._logger)
|
|
113
111
|
|
|
114
112
|
@property
|
|
115
113
|
def gateways(self) -> GatewaysAPIClient:
|
|
116
|
-
return GatewaysAPIClient(self._request)
|
|
114
|
+
return GatewaysAPIClient(self._request, self._logger)
|
|
117
115
|
|
|
118
116
|
@property
|
|
119
117
|
def volumes(self) -> VolumesAPIClient:
|
|
120
|
-
return VolumesAPIClient(self._request)
|
|
118
|
+
return VolumesAPIClient(self._request, self._logger)
|
|
121
119
|
|
|
122
120
|
@property
|
|
123
121
|
def files(self) -> FilesAPIClient:
|
|
124
|
-
return FilesAPIClient(self._request)
|
|
122
|
+
return FilesAPIClient(self._request, self._logger)
|
|
125
123
|
|
|
126
124
|
def _request(
|
|
127
125
|
self,
|
|
@@ -136,20 +134,20 @@ class APIClient:
|
|
|
136
134
|
kwargs.setdefault("headers", {})["Content-Type"] = "application/json"
|
|
137
135
|
kwargs["data"] = body
|
|
138
136
|
|
|
139
|
-
|
|
137
|
+
self._logger.debug("POST /%s", path)
|
|
140
138
|
for _ in range(_MAX_RETRIES):
|
|
141
139
|
try:
|
|
142
140
|
# TODO: set adequate timeout here or everywhere the method is used
|
|
143
141
|
resp = self._s.request(method, f"{self._base_url}/{path}", **kwargs)
|
|
144
142
|
break
|
|
145
143
|
except requests.exceptions.ConnectionError as e:
|
|
146
|
-
|
|
144
|
+
self._logger.debug("Could not connect to server: %s", e)
|
|
147
145
|
time.sleep(_RETRY_INTERVAL)
|
|
148
146
|
else:
|
|
149
147
|
raise ClientError(f"Failed to connect to dstack server {self._base_url}")
|
|
150
148
|
|
|
151
149
|
if 400 <= resp.status_code < 600:
|
|
152
|
-
|
|
150
|
+
self._logger.debug(
|
|
153
151
|
"Error requesting %s. Status: %s. Headers: %s. Body: %s",
|
|
154
152
|
resp.request.url,
|
|
155
153
|
resp.status_code,
|
dstack/api/server/_gpus.py
CHANGED
|
@@ -2,6 +2,7 @@ from typing import List, Optional
|
|
|
2
2
|
|
|
3
3
|
from pydantic import parse_obj_as
|
|
4
4
|
|
|
5
|
+
from dstack._internal.core.compatibility.gpus import get_list_gpus_excludes
|
|
5
6
|
from dstack._internal.core.models.runs import RunSpec
|
|
6
7
|
from dstack._internal.server.schemas.gpus import GpuGroup, ListGpusRequest, ListGpusResponse
|
|
7
8
|
from dstack.api.server._group import APIClientGroup
|
|
@@ -17,6 +18,6 @@ class GpusAPIClient(APIClientGroup):
|
|
|
17
18
|
body = ListGpusRequest(run_spec=run_spec, group_by=group_by)
|
|
18
19
|
resp = self._request(
|
|
19
20
|
f"/api/project/{project_name}/gpus/list",
|
|
20
|
-
body=body.json(),
|
|
21
|
+
body=body.json(exclude=get_list_gpus_excludes(body)),
|
|
21
22
|
)
|
|
22
23
|
return parse_obj_as(ListGpusResponse, resp.json()).gpus
|
dstack/api/server/_group.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from logging import Logger
|
|
1
2
|
from typing import Optional
|
|
2
3
|
|
|
3
4
|
import requests
|
|
@@ -12,10 +13,10 @@ class APIRequest(Protocol):
|
|
|
12
13
|
raise_for_status: bool = True,
|
|
13
14
|
method: str = "POST",
|
|
14
15
|
**kwargs,
|
|
15
|
-
) -> requests.Response:
|
|
16
|
-
pass
|
|
16
|
+
) -> requests.Response: ...
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class APIClientGroup:
|
|
20
|
-
def __init__(self, _request: APIRequest):
|
|
20
|
+
def __init__(self, _request: APIRequest, _logger: Logger):
|
|
21
21
|
self._request = _request
|
|
22
|
+
self._logger = _logger
|
dstack/api/server/_repos.py
CHANGED
|
@@ -2,7 +2,12 @@ from typing import BinaryIO, List, Optional
|
|
|
2
2
|
|
|
3
3
|
from pydantic import parse_obj_as
|
|
4
4
|
|
|
5
|
-
from dstack._internal.core.models.repos import
|
|
5
|
+
from dstack._internal.core.models.repos import (
|
|
6
|
+
AnyRepoInfo,
|
|
7
|
+
RemoteRepoCreds,
|
|
8
|
+
RepoHead,
|
|
9
|
+
RepoHeadWithCreds,
|
|
10
|
+
)
|
|
6
11
|
from dstack._internal.server.schemas.repos import (
|
|
7
12
|
DeleteReposRequest,
|
|
8
13
|
GetRepoRequest,
|
|
@@ -16,11 +21,23 @@ class ReposAPIClient(APIClientGroup):
|
|
|
16
21
|
resp = self._request(f"/api/project/{project_name}/repos/list")
|
|
17
22
|
return parse_obj_as(List[RepoHead.__response__], resp.json())
|
|
18
23
|
|
|
19
|
-
def get(
|
|
20
|
-
|
|
24
|
+
def get(
|
|
25
|
+
self, project_name: str, repo_id: str, include_creds: Optional[bool] = None
|
|
26
|
+
) -> RepoHead:
|
|
27
|
+
if include_creds is not None:
|
|
28
|
+
self._logger.warning(
|
|
29
|
+
"`include_creds` argument is deprecated and has no effect, `get()` always returns"
|
|
30
|
+
" the repo without creds. Use `get_with_creds()` to get the repo with creds"
|
|
31
|
+
)
|
|
32
|
+
body = GetRepoRequest(repo_id=repo_id, include_creds=False)
|
|
21
33
|
resp = self._request(f"/api/project/{project_name}/repos/get", body=body.json())
|
|
22
34
|
return parse_obj_as(RepoHead.__response__, resp.json())
|
|
23
35
|
|
|
36
|
+
def get_with_creds(self, project_name: str, repo_id: str) -> RepoHeadWithCreds:
|
|
37
|
+
body = GetRepoRequest(repo_id=repo_id, include_creds=True)
|
|
38
|
+
resp = self._request(f"/api/project/{project_name}/repos/get", body=body.json())
|
|
39
|
+
return parse_obj_as(RepoHeadWithCreds.__response__, resp.json())
|
|
40
|
+
|
|
24
41
|
def init(
|
|
25
42
|
self,
|
|
26
43
|
project_name: str,
|
|
@@ -86,6 +86,7 @@ class CustomApplyPolicy(ApplyPolicy):
|
|
|
86
86
|
spec: ApplySpec,
|
|
87
87
|
excludes: Optional[Dict] = None,
|
|
88
88
|
) -> ApplySpec:
|
|
89
|
+
spec_json = None
|
|
89
90
|
try:
|
|
90
91
|
spec_request = request_cls(user=user, project=project, spec=spec)
|
|
91
92
|
spec_json = self._call_plugin_service(spec_request, endpoint, excludes)
|
dstack/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dstack
|
|
3
|
-
Version: 0.19.
|
|
3
|
+
Version: 0.19.26
|
|
4
4
|
Summary: dstack is an open-source orchestration engine for running AI workloads on any cloud or on-premises.
|
|
5
5
|
Project-URL: Homepage, https://dstack.ai
|
|
6
6
|
Project-URL: Source, https://github.com/dstackai/dstack
|