Skip to content

Commit 5f04b6d

Browse files
authored
[Breaking]: Drop deprecated RunCollection methods (#3340)
In Python API, drop the `RunCollection.get_plan`, `RunCollection.exec_plan`, and `RunCollection.submit` methods that were deprecated with a warning since 0.19.0. Python API users are advised to use the `RunCollection.get_run_plan`, `RunCollection.apply_plan`, and `RunCollection.apply_configuration` methods instead.
1 parent e62da62 commit 5f04b6d

File tree

1 file changed

+2
-198
lines changed

1 file changed

+2
-198
lines changed

src/dstack/api/_public/runs.py

Lines changed: 2 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from copy import copy
1010
from datetime import datetime
1111
from pathlib import Path
12-
from typing import BinaryIO, Dict, Iterable, List, Optional, Union
12+
from typing import BinaryIO, Dict, Iterable, List, Optional
1313
from urllib.parse import urlencode, urlparse
1414

1515
from websocket import WebSocketApp
@@ -25,16 +25,10 @@
2525
)
2626
from dstack._internal.core.models.files import FileArchiveMapping
2727
from dstack._internal.core.models.profiles import (
28-
CreationPolicy,
2928
Profile,
30-
ProfileRetryPolicy,
31-
SpotPolicy,
32-
TerminationPolicy,
33-
UtilizationPolicy,
3429
)
3530
from dstack._internal.core.models.repos.base import Repo
3631
from dstack._internal.core.models.repos.virtual import VirtualRepo
37-
from dstack._internal.core.models.resources import ResourcesSpec
3832
from dstack._internal.core.models.runs import (
3933
Job,
4034
JobSpec,
@@ -55,7 +49,7 @@
5549
from dstack._internal.utils.crypto import generate_rsa_key_pair
5650
from dstack._internal.utils.files import create_file_archive
5751
from dstack._internal.utils.logging import get_logger
58-
from dstack._internal.utils.path import PathLike, path_in_dir
52+
from dstack._internal.utils.path import PathLike
5953
from dstack.api.server import APIClient
6054

6155
logger = get_logger(__name__)
@@ -616,196 +610,6 @@ def apply_configuration(
616610
)
617611
return run
618612

619-
def submit(
620-
self,
621-
configuration: AnyRunConfiguration,
622-
configuration_path: Optional[str] = None,
623-
repo: Optional[Repo] = None,
624-
backends: Optional[List[BackendType]] = None,
625-
regions: Optional[List[str]] = None,
626-
instance_types: Optional[List[str]] = None,
627-
resources: Optional[ResourcesSpec] = None,
628-
spot_policy: Optional[SpotPolicy] = None,
629-
retry_policy: Optional[ProfileRetryPolicy] = None,
630-
max_duration: Optional[Union[int, str]] = None,
631-
max_price: Optional[float] = None,
632-
working_dir: Optional[str] = None,
633-
run_name: Optional[str] = None,
634-
reserve_ports: bool = True,
635-
) -> Run:
636-
# """
637-
# Submit a run
638-
639-
# Args:
640-
# configuration (Union[Task, Service]): A run configuration.
641-
# configuration_path: The path to the configuration file, relative to the root directory of the repo.
642-
# repo (Union[LocalRepo, RemoteRepo, VirtualRepo]): A repo to mount to the run.
643-
# backends: A list of allowed backend for provisioning.
644-
# regions: A list of cloud regions for provisioning.
645-
# resources: The requirements to run the configuration. Overrides the configuration's resources.
646-
# spot_policy: A spot policy for provisioning.
647-
# retry_policy (RetryPolicy): A retry policy.
648-
# max_duration: The max instance running duration in seconds.
649-
# max_price: The max instance price in dollars per hour for provisioning.
650-
# working_dir: A working directory relative to the repo root directory
651-
# run_name: A desired name of the run. Must be unique in the project. If not specified, a random name is assigned.
652-
# reserve_ports: Whether local ports should be reserved in advance.
653-
654-
# Returns:
655-
# Submitted run.
656-
# """
657-
logger.warning("The submit() method is deprecated in favor of apply_configuration().")
658-
if repo is None:
659-
repo = VirtualRepo()
660-
# TODO: Add Git credentials to RemoteRepo and if they are set, pass them here to RepoCollection.init
661-
self._client.repos.init(repo)
662-
663-
run_plan = self.get_plan(
664-
configuration=configuration,
665-
repo=repo,
666-
configuration_path=configuration_path,
667-
backends=backends,
668-
regions=regions,
669-
instance_types=instance_types,
670-
resources=resources,
671-
spot_policy=spot_policy,
672-
retry_policy=retry_policy,
673-
max_duration=max_duration,
674-
max_price=max_price,
675-
working_dir=working_dir,
676-
run_name=run_name,
677-
)
678-
return self.exec_plan(run_plan, repo, reserve_ports=reserve_ports)
679-
680-
# Deprecated in favor of get_run_plan()
681-
def get_plan(
682-
self,
683-
configuration: AnyRunConfiguration,
684-
repo: Optional[Repo] = None,
685-
configuration_path: Optional[str] = None,
686-
# Unused profile args are deprecated and removed but
687-
# kept for signature backward compatibility.
688-
backends: Optional[List[BackendType]] = None,
689-
regions: Optional[List[str]] = None,
690-
instance_types: Optional[List[str]] = None,
691-
resources: Optional[ResourcesSpec] = None,
692-
spot_policy: Optional[SpotPolicy] = None,
693-
retry_policy: Optional[ProfileRetryPolicy] = None,
694-
utilization_policy: Optional[UtilizationPolicy] = None,
695-
max_duration: Optional[Union[int, str]] = None,
696-
max_price: Optional[float] = None,
697-
working_dir: Optional[str] = None,
698-
run_name: Optional[str] = None,
699-
pool_name: Optional[str] = None,
700-
instance_name: Optional[str] = None,
701-
creation_policy: Optional[CreationPolicy] = None,
702-
termination_policy: Optional[TerminationPolicy] = None,
703-
termination_policy_idle: Optional[Union[str, int]] = None,
704-
reservation: Optional[str] = None,
705-
idle_duration: Optional[Union[str, int]] = None,
706-
stop_duration: Optional[Union[str, int]] = None,
707-
) -> RunPlan:
708-
# """
709-
# Get run plan. Same arguments as `submit`
710-
#
711-
# Returns:
712-
# run plan
713-
# """
714-
logger.warning("The get_plan() method is deprecated in favor of get_run_plan().")
715-
if repo is None:
716-
repo = VirtualRepo()
717-
repo_code_hash = None
718-
else:
719-
with _prepare_code_file(repo) as (_, repo_code_hash):
720-
pass
721-
722-
if working_dir is None:
723-
working_dir = "."
724-
elif repo.repo_dir is not None:
725-
working_dir_path = Path(repo.repo_dir) / working_dir
726-
if not path_in_dir(working_dir_path, repo.repo_dir):
727-
raise ConfigurationError("Working directory is outside of the repo")
728-
working_dir = working_dir_path.relative_to(repo.repo_dir).as_posix()
729-
730-
if configuration_path is None:
731-
configuration_path = "(python)"
732-
733-
if resources is not None:
734-
configuration = configuration.copy(deep=True)
735-
configuration.resources = resources
736-
737-
# TODO: [Andrey] "(python") looks as a hack
738-
profile = Profile(
739-
name="(python)",
740-
backends=backends,
741-
regions=regions,
742-
instance_types=instance_types,
743-
reservation=reservation,
744-
spot_policy=spot_policy,
745-
retry=None,
746-
utilization_policy=utilization_policy,
747-
max_duration=max_duration, # type: ignore[assignment]
748-
stop_duration=stop_duration, # type: ignore[assignment]
749-
max_price=max_price,
750-
creation_policy=creation_policy,
751-
idle_duration=idle_duration, # type: ignore[assignment]
752-
)
753-
config_manager = ConfigManager()
754-
key_manager = UserSSHKeyManager(self._api_client, config_manager.dstack_ssh_dir)
755-
if key_manager.get_user_key():
756-
ssh_key_pub = None # using the server-managed user key
757-
else:
758-
if not config_manager.dstack_key_path.exists():
759-
generate_rsa_key_pair(private_key_path=config_manager.dstack_key_path)
760-
logger.warning(
761-
f"Using legacy [code]{config_manager.dstack_key_path.with_suffix('.pub')}[/code]."
762-
" You will only be able to attach to the run from this client."
763-
" Update the [code]dstack[/] server to [code]0.19.34[/]+ to switch to user keys"
764-
" automatically replicated to all clients.",
765-
)
766-
ssh_key_pub = config_manager.dstack_key_path.with_suffix(".pub").read_text()
767-
run_spec = RunSpec(
768-
run_name=run_name,
769-
repo_id=repo.repo_id,
770-
repo_data=repo.run_repo_data,
771-
repo_code_hash=repo_code_hash,
772-
working_dir=working_dir,
773-
configuration_path=configuration_path,
774-
configuration=configuration,
775-
profile=profile,
776-
ssh_key_pub=ssh_key_pub,
777-
)
778-
logger.debug("Getting run plan")
779-
run_plan = self._api_client.runs.get_plan(self._project, run_spec)
780-
if run_plan.current_resource is None and run_name is not None:
781-
# If run_plan.current_resource is missing, this can mean old (0.18.x) server.
782-
# TODO: Remove in 0.19
783-
try:
784-
run_plan.current_resource = self._api_client.runs.get(self._project, run_name)
785-
except ResourceNotExistsError:
786-
pass
787-
return run_plan
788-
789-
def exec_plan(
790-
self,
791-
run_plan: RunPlan,
792-
repo: Repo,
793-
reserve_ports: bool = True,
794-
) -> Run:
795-
# """
796-
# Execute the run plan.
797-
798-
# Args:
799-
# run_plan: Result of `get_run_plan` call.
800-
# repo: Repo to use for the run.
801-
# reserve_ports: Reserve local ports before submit.
802-
803-
# Returns:
804-
# Submitted run.
805-
# """
806-
logger.warning("The exec_plan() method is deprecated in favor of apply_plan().")
807-
return self.apply_plan(run_plan=run_plan, repo=repo, reserve_ports=reserve_ports)
808-
809613
def list(self, all: bool = False, limit: Optional[int] = None) -> List[Run]:
810614
"""
811615
List runs.

0 commit comments

Comments
 (0)