Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/dstack/_internal/core/models/envs.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,11 @@ def __setitem__(self, item, value):
def copy(self, **kwargs) -> Self:
# Env.copy() is tricky because it copies only the hidden top-level {"__root__": {...}}
# structure, not the actual nested dict representing the env itself.
# To avoid possible bugs, we prohibit shallow copying altogether.
# So we copy __root__ explicitly in case of a shallow copy.
new_copy = super().copy(**kwargs)
if not kwargs.get("deep", False):
raise TypeError(f"shallow copying of {self.__class__.__name__} is prohibited")
return super().copy(**kwargs)
new_copy.__root__ = new_copy.__root__.copy()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@un-def, I had to implement shallow copy for Env somehow because if a model defines excludes/includes, pydantic performs shallow copy for fields internally when calling copy(deep=True). Yes, copy(deep=True) may call copy(deep=False).

return new_copy

def as_dict(self) -> Dict[str, str]:
"""
Expand Down
18 changes: 17 additions & 1 deletion src/dstack/_internal/core/models/profiles.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from enum import Enum
from typing import List, Optional, Union, overload
from typing import Any, Dict, List, Optional, Union, overload

from pydantic import Field, root_validator, validator
from typing_extensions import Annotated, Literal
Expand Down Expand Up @@ -241,6 +241,22 @@ class ProfileParams(CoreModel):
Field(description="Run termination policy based on utilization"),
] = None

# # Deprecated and unused. Left for compatibility with 0.18 clients.
pool_name: Annotated[Optional[str], Field(exclude=True)] = None
instance_name: Annotated[Optional[str], Field(exclude=True)] = None
retry_policy: Annotated[Optional[ProfileRetryPolicy], Field(exclude=True)] = None
termination_policy: Annotated[Optional[TerminationPolicy], Field(exclude=True)] = None
termination_idle_time: Annotated[Optional[Union[str, int]], Field(exclude=True)] = None

class Config:
@staticmethod
def schema_extra(schema: Dict[str, Any]) -> None:
del schema["properties"]["pool_name"]
del schema["properties"]["instance_name"]
del schema["properties"]["retry_policy"]
del schema["properties"]["termination_policy"]
del schema["properties"]["termination_idle_time"]

_validate_max_duration = validator("max_duration", pre=True, allow_reuse=True)(
parse_max_duration
)
Expand Down
16 changes: 15 additions & 1 deletion src/dstack/_internal/server/schemas/gateways.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
from typing import List
from typing import Annotated, Any, Dict, List, Optional

from pydantic import Field

from dstack._internal.core.models.backends.base import BackendType
from dstack._internal.core.models.common import CoreModel
from dstack._internal.core.models.gateways import GatewayConfiguration


class CreateGatewayRequest(CoreModel):
configuration: GatewayConfiguration
# Deprecated and unused. Left for compatibility with 0.18 clients.
name: Annotated[Optional[str], Field(exclude=True)] = None
backend_type: Annotated[Optional[BackendType], Field(exclude=True)] = None
region: Annotated[Optional[str], Field(exclude=True)] = None

class Config:
@staticmethod
def schema_extra(schema: Dict[str, Any]) -> None:
del schema["properties"]["name"]
del schema["properties"]["backend_type"]
del schema["properties"]["region"]


class GetGatewayRequest(CoreModel):
Expand Down