Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ directorv2 API schema models moved to models-library #4560

Merged
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
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
from typing import TypeAlias
from typing import Any, ClassVar, TypeAlias

from models_library.clusters import (
CLUSTER_ADMIN_RIGHTS,
CLUSTER_MANAGER_RIGHTS,
CLUSTER_USER_RIGHTS,
BaseCluster,
Cluster,
ClusterAccessRights,
ClusterAuthentication,
ClusterTypeInModel,
ExternalClusterAuthentication,
)
from models_library.generics import DictModel
from models_library.users import GroupID
from pydantic import (
AnyHttpUrl,
BaseModel,
Expand All @@ -25,6 +12,20 @@
from pydantic.networks import AnyUrl
from pydantic.types import ByteSize, PositiveFloat

from ..clusters import (
CLUSTER_ADMIN_RIGHTS,
CLUSTER_MANAGER_RIGHTS,
CLUSTER_USER_RIGHTS,
BaseCluster,
Cluster,
ClusterAccessRights,
ClusterAuthentication,
ClusterTypeInModel,
ExternalClusterAuthentication,
)
from ..generics import DictModel
from ..users import GroupID


class TaskCounts(BaseModel):
error: int = 0
Expand Down Expand Up @@ -130,7 +131,7 @@ def set_default_thumbnail_if_empty(cls, v, values):
return v

class Config(BaseCluster.Config):
schema_extra = {
schema_extra: ClassVar[dict[str, Any]] = {
"examples": [
{
"name": "My awesome cluster",
Expand Down Expand Up @@ -176,7 +177,7 @@ class ClusterPatch(BaseCluster):
)

class Config(BaseCluster.Config):
schema_extra = {
schema_extra: ClassVar[dict[str, Any]] = {
"examples": [
{
"name": "Changing the name of my cluster",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from models_library.clusters import ClusterID
from models_library.projects import ProjectID
from models_library.projects_nodes import NodeID
from models_library.projects_pipeline import ComputationTask
from models_library.users import UserID
from pydantic import AnyHttpUrl, AnyUrl, BaseModel, Field, validator

from ..clusters import ClusterID
from ..projects import ProjectID
from ..projects_nodes_io import NodeID
from ..projects_pipeline import ComputationTask
from ..users import UserID


class ComputationGet(ComputationTask):
url: AnyHttpUrl = Field(
Expand Down Expand Up @@ -40,7 +41,8 @@ class ComputationCreate(BaseModel):
@classmethod
def ensure_product_name_defined_if_computation_starts(cls, v, values):
if "start_pipeline" in values and values["start_pipeline"] and v is None:
raise ValueError("product_name must be set if computation shall start!")
msg = "product_name must be set if computation shall start!"
raise ValueError(msg)
return v


Expand All @@ -50,7 +52,7 @@ class ComputationStop(BaseModel):

class ComputationDelete(ComputationStop):
force: bool | None = Field(
False,
default=False,
description="if True then the pipeline will be removed even if it is running",
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from models_library.services import ServicePortKey
from models_library.services_resources import (
ServiceResourcesDict,
ServiceResourcesDictHelpers,
)
from typing import Any, ClassVar, TypeAlias

from pydantic import BaseModel, ByteSize, Field

from ..schemas.dynamic_services import RunningDynamicServiceDetails, ServiceDetails
from ..services import ServicePortKey
from ..services_resources import ServiceResourcesDict, ServiceResourcesDictHelpers
from .dynamic_services_service import RunningDynamicServiceDetails, ServiceDetails


class RetrieveDataIn(BaseModel):
Expand All @@ -30,7 +29,9 @@ def from_transferred_bytes(
return cls(data=RetrieveDataOut(size_bytes=ByteSize(transferred_bytes)))

class Config:
schema_extra = {"examples": [{"data": {"size_bytes": 42}}]}
schema_extra: ClassVar[dict[str, Any]] = {
"examples": [{"data": {"size_bytes": 42}}]
}


class DynamicServiceCreate(ServiceDetails):
Expand All @@ -42,7 +43,7 @@ class DynamicServiceCreate(ServiceDetails):
)

class Config:
schema_extra = {
schema_extra: ClassVar[dict[str, Any]] = {
"example": {
"key": "simcore/services/dynamic/3dviewer",
"version": "2.4.5",
Expand All @@ -59,4 +60,4 @@ class Config:
}


DynamicServiceGet = RunningDynamicServiceDetails
DynamicServiceGet: TypeAlias = RunningDynamicServiceDetails
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
from enum import Enum, unique
from functools import cached_property, lru_cache, total_ordering
from functools import cached_property
from pathlib import Path
from typing import Any, ClassVar

from models_library.basic_types import PortInt
from models_library.projects import ProjectID
from models_library.projects_nodes_io import NodeID
from models_library.services import VERSION_RE, DynamicServiceKey
from models_library.users import UserID
from pydantic import BaseModel, Field

from ..basic_regex import VERSION_RE
from ..basic_types import PortInt
from ..projects import ProjectID
from ..projects_nodes_io import NodeID
from ..services import DynamicServiceKey
from ..services_enums import ServiceBootType, ServiceState
from ..users import UserID


class CommonServiceDetails(BaseModel):
key: DynamicServiceKey = Field(
Expand Down Expand Up @@ -54,46 +56,6 @@ class Config:
}


@unique
class ServiceBootType(str, Enum):
V0 = "V0"
V2 = "V2"


@total_ordering
@unique
class ServiceState(Enum):
PENDING = "pending"
PULLING = "pulling"
STARTING = "starting"
RUNNING = "running"
COMPLETE = "complete"
FAILED = "failed"
STOPPING = "stopping"

def __lt__(self, other):
if self.__class__ is other.__class__:
comparison_order = ServiceState.comparison_order()
self_index = comparison_order[self]
other_index = comparison_order[other]
return self_index < other_index
return NotImplemented

@staticmethod
@lru_cache(maxsize=2)
def comparison_order() -> dict["ServiceState", int]:
"""States are comparable to supportmin() on a list of ServiceState"""
return {
ServiceState.FAILED: 0,
ServiceState.PENDING: 1,
ServiceState.PULLING: 2,
ServiceState.STARTING: 3,
ServiceState.RUNNING: 4,
ServiceState.STOPPING: 5,
ServiceState.COMPLETE: 6,
}


class RunningDynamicServiceDetails(ServiceDetails):
boot_type: ServiceBootType = Field(
default=ServiceBootType.V0,
Expand Down Expand Up @@ -133,29 +95,6 @@ class RunningDynamicServiceDetails(ServiceDetails):
def legacy_service_url(self) -> str:
return f"http://{self.host}:{self.internal_port}{self.basepath}" # NOSONAR

@classmethod
def from_scheduler_data(
cls,
node_uuid: NodeID,
scheduler_data: "SchedulerData", # type: ignore
service_state: ServiceState,
service_message: str,
) -> "RunningDynamicServiceDetails":
return cls.parse_obj(
{
"boot_type": ServiceBootType.V2,
"user_id": scheduler_data.user_id,
"project_id": scheduler_data.project_id,
"service_uuid": node_uuid,
"service_key": scheduler_data.key,
"service_version": scheduler_data.version,
"service_host": scheduler_data.service_name,
"service_port": scheduler_data.service_port,
"service_state": service_state.value,
"service_message": service_message,
}
)

class Config(ServiceDetails.Config):
keep_untouched = (cached_property,)
schema_extra: ClassVar[dict[str, Any]] = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
from typing import List, Optional

from pydantic import BaseModel, Field


class Error(BaseModel):
code: Optional[str] = Field(None, description="Server Exception")
code: str | None = Field(None, description="Server Exception")


class ErrorType(BaseModel):
message: str = Field(..., description="Error message")
errors: Optional[List[Error]] = None
errors: list[Error] | None = None
status: int = Field(..., description="Error code")


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from typing import Any, ClassVar

from pydantic import BaseModel


class HealthCheckGet(BaseModel):
timestamp: str

class Config:
schema_extra: ClassVar[dict[str, Any]] = {
"example": {
"timestamp": "simcore_service_directorv2.api.routes.health@2023-07-03T12:59:12.024551+00:00"
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import re
from typing import Any, ClassVar

from models_library.basic_regex import VERSION_RE
from pydantic import BaseModel, ConstrainedStr, Field
from pydantic import BaseModel, Field


class VersionStr(ConstrainedStr):
regex = re.compile(VERSION_RE)
from ..basic_types import VersionStr


class Meta(BaseModel):
Expand All @@ -16,7 +13,7 @@ class Meta(BaseModel):
)

class Config:
schema_extra = {
schema_extra: ClassVar[dict[str, Any]] = {
"example": {
"name": "simcore_service_foo",
"version": "2.4.45",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from typing import Any, ClassVar

from models_library.service_settings_labels import ContainerSpec
from pydantic import BaseModel, Field, validator
from pydantic.types import ByteSize, NonNegativeInt

from ..service_settings_labels import ContainerSpec


class ServiceBuildDetails(BaseModel):
build_date: str
Expand Down
17 changes: 8 additions & 9 deletions packages/models-library/src/models_library/clusters.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from enum import auto
from typing import Any, ClassVar, Final, Literal, TypeAlias, Union
from typing import Any, ClassVar, Final, Literal, TypeAlias

from models_library.utils.common_validators import create_enums_pre_validator
from pydantic import (
AnyUrl,
BaseModel,
Expand All @@ -15,6 +14,7 @@
from pydantic.types import NonNegativeInt

from .users import GroupID
from .utils.common_validators import create_enums_pre_validator
from .utils.enums import StrAutoEnum


Expand Down Expand Up @@ -95,13 +95,12 @@ class NoAuthentication(BaseAuthentication):


InternalClusterAuthentication: TypeAlias = NoAuthentication
ExternalClusterAuthentication: TypeAlias = Union[
SimpleAuthentication, KerberosAuthentication, JupyterHubTokenAuthentication
]
ClusterAuthentication: TypeAlias = Union[
ExternalClusterAuthentication,
InternalClusterAuthentication,
]
ExternalClusterAuthentication: TypeAlias = (
SimpleAuthentication | KerberosAuthentication | JupyterHubTokenAuthentication
)
ClusterAuthentication: TypeAlias = (
ExternalClusterAuthentication | InternalClusterAuthentication
)


class BaseCluster(BaseModel):
Expand Down
3 changes: 2 additions & 1 deletion packages/models-library/src/models_library/groups.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import enum
from typing import Any, ClassVar, Final

from models_library.utils.common_validators import create_enums_pre_validator
from pydantic import BaseModel, Field, validator
from pydantic.types import PositiveInt

from .utils.common_validators import create_enums_pre_validator

EVERYONE_GROUP_ID: Final[int] = 1


Expand Down
6 changes: 0 additions & 6 deletions packages/models-library/src/models_library/services.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
"""

NOTE: to dump json-schema from CLI use
python -c "from models_library.services import ServiceDockerData as cls; print(cls.schema_json(indent=2))" > services-schema.json
"""

import re
from datetime import datetime
from enum import Enum
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from sqlalchemy.sql.expression import tuple_
from sqlalchemy.sql.selectable import Select

from ...models.service_specifications import ServiceSpecificationsAtDB
from ...models.services_specifications import ServiceSpecificationsAtDB
from ..tables import services_access_rights, services_meta_data, services_specifications
from ._base import BaseRepository

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""
This packages is intended for domain (i.e. internal) models
Any common/base and API (schema) models go in models_library or models_library.api_schemas_catalog
"""
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from simcore_postgres_database.models.services_specifications import (
services_specifications,
)
from simcore_service_catalog.models.service_specifications import (
from simcore_service_catalog.models.services_specifications import (
ServiceSpecificationsAtDB,
)
from sqlalchemy.ext.asyncio import AsyncEngine
Expand Down
Loading