Skip to content

Commit

Permalink
♻️ catalog API schema models moved to models-library (#4553)
Browse files Browse the repository at this point in the history
  • Loading branch information
pcrespov authored Jul 31, 2023
1 parent 52ca6b4 commit f2f6a81
Show file tree
Hide file tree
Showing 119 changed files with 841 additions and 1,986 deletions.
36 changes: 18 additions & 18 deletions packages/models-library/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,30 @@ def read_reqs(reqs_path: Path) -> set[str]:
) # STRICK requirements


SETUP = dict(
name="simcore-models-library",
version=Path(CURRENT_DIR / "VERSION").read_text().strip(),
author="Sylvain Anderegg (sanderegg)",
description="Core service library for simcore pydantic models",
python_requires="~=3.10",
classifiers=[
SETUP = {
"name": "simcore-models-library",
"version": Path(CURRENT_DIR / "VERSION").read_text().strip(),
"author": "Sylvain Anderegg (sanderegg)",
"description": "Core service library for simcore pydantic models",
"python_requires": "~=3.10",
"classifiers": [
"Development Status :: 2 - Pre-Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Programming Language :: Python :: 3.10",
],
long_description=Path(CURRENT_DIR / "README.md").read_text(),
license="MIT license",
install_requires=INSTALL_REQUIREMENTS,
packages=find_packages(where="src"),
package_dir={"": "src"},
include_package_data=True,
test_suite="tests",
tests_require=TEST_REQUIREMENTS,
extras_require={"test": TEST_REQUIREMENTS},
zip_safe=False,
)
"long_description": Path(CURRENT_DIR / "README.md").read_text(),
"license": "MIT license",
"install_requires": INSTALL_REQUIREMENTS,
"packages": find_packages(where="src"),
"package_dir": {"": "src"},
"include_package_data": True,
"test_suite": "tests",
"tests_require": TEST_REQUIREMENTS,
"extras_require": {"test": TEST_REQUIREMENTS},
"zip_safe": False,
}


if __name__ == "__main__":
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from typing import Any, ClassVar

from pydantic import BaseModel, Field

from ..basic_types import VersionStr


class Meta(BaseModel):
name: str
version: VersionStr
released: dict[str, VersionStr] | None = Field(
None, description="Maps every route's path tag with a released version"
)

class Config:
schema_extra: ClassVar[dict[str, Any]] = {
"example": {
"name": "simcore_service_foo",
"version": "2.4.45",
"released": {"v1": "1.3.4", "v2": "2.4.45"},
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from models_library.users import GroupID
from pydantic import BaseModel

from .services import ServiceKey, ServiceVersion
from ..services import ServiceKey, ServiceVersion
from ..users import GroupID


class ServiceAccessRightsGet(BaseModel):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
from typing import Optional
from typing import Any, ClassVar

from models_library.emails import LowerCaseEmailStr
from models_library.services import ServiceDockerData, ServiceMetaData
from models_library.services_access import ServiceAccessRights
from models_library.services_resources import ServiceResourcesDict
from pydantic import Extra
from pydantic.main import BaseModel

from ..emails import LowerCaseEmailStr
from ..services import ServiceDockerData, ServiceMetaData
from ..services_access import ServiceAccessRights
from ..services_resources import ServiceResourcesDict


# OpenAPI models (contain both service metadata and access rights)
class ServiceUpdate(ServiceMetaData, ServiceAccessRights):
class Config:
schema_extra = {
schema_extra: ClassVar[dict[str, Any]] = {
"example": {
# ServiceAccessRights
"accessRights": {
Expand Down Expand Up @@ -64,16 +63,16 @@ class Config:
class ServiceGet(
ServiceDockerData, ServiceAccessRights, ServiceMetaData
): # pylint: disable=too-many-ancestors
owner: Optional[LowerCaseEmailStr]
owner: LowerCaseEmailStr | None

class Config:
allow_population_by_field_name = True
extra = Extra.ignore
schema_extra = {
schema_extra: ClassVar[dict[str, Any]] = {
"example": {
"name": "File Picker",
"thumbnail": None,
"description": "File Picker",
"description": "description",
"classifiers": [],
"quality": {},
"accessRights": {
Expand Down Expand Up @@ -109,32 +108,4 @@ class Config:
}


# TODO: prototype for next iteration
# Items are non-detailed version of resources listed
class ServiceItem(BaseModel):
class Config:
extra = Extra.ignore
schema_extra = {
"example": {
"title": "File Picker", # NEW: rename 'name' as title (so it is not confused with an identifier!)
"thumbnail": None, # optional
"description": "File Picker",
"classifiers_url": "https://catalog:8080/services/a8f5a503-01d5-40bc-b416-f5b7cc5d1fa4/classifiers",
"quality": "https://catalog:8080/services/a8f5a503-01d5-40bc-b416-f5b7cc5d1fa4/quality",
"access_rights_url": "https://catalog:8080/services/a8f5a503-01d5-40bc-b416-f5b7cc5d1fa4/access_rights",
"key_id": "simcore/services/frontend/file-picker", # NEW: renames key -> key_id
"version": "1.0.0",
"id": "a8f5a503-01d5-40bc-b416-f5b7cc5d1fa4", # NEW: alternative identifier to key_id:version
"integration-version": "1.0.0",
"type": "dynamic",
"badges_url": "https://catalog:8080/services/a8f5a503-01d5-40bc-b416-f5b7cc5d1fa4/badges",
"authors_url": "https://catalog:8080/services/a8f5a503-01d5-40bc-b416-f5b7cc5d1fa4/authors",
"inputs_url": "https://catalog:8080/services/a8f5a503-01d5-40bc-b416-f5b7cc5d1fa4/inputs",
"outputs_url": "https://catalog:8080/services/a8f5a503-01d5-40bc-b416-f5b7cc5d1fa4/outputs",
"owner": "[email protected]", # NEW, replaces "contact": "[email protected]"
"url": "https://catalog:8080/services/a8f5a503-01d5-40bc-b416-f5b7cc5d1fa4", # NEW self
}
}


ServiceResourcesGet = ServiceResourcesDict
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
from typing import Any, Literal, Optional, Union
from typing import Any, ClassVar, Literal

from models_library.basic_regex import PUBLIC_VARIABLE_NAME_RE
from models_library.services import ServiceInput, ServiceOutput
from models_library.utils.services_io import (
from pydantic import BaseModel, Field

from ..basic_regex import PUBLIC_VARIABLE_NAME_RE
from ..services import ServiceInput, ServiceOutput
from ..utils.services_io import (
get_service_io_json_schema,
guess_media_type,
update_schema_doc,
)
from pydantic import BaseModel, Field

PortKindStr = Literal["input", "output"]


#
# Model -------------------------------------------------------------------------------
#


class ServicePortGet(BaseModel):
key: str = Field(
...,
Expand All @@ -25,14 +21,14 @@ class ServicePortGet(BaseModel):
title="Key name",
)
kind: PortKindStr
content_media_type: Optional[str] = None
content_schema: Optional[dict[str, Any]] = Field(
content_media_type: str | None = None
content_schema: dict[str, Any] | None = Field(
None,
description="jsonschema for the port's value. SEE https://json-schema.org/understanding-json-schema/",
)

class Config:
schema_extra = {
schema_extra: ClassVar[dict[str, Any]] = {
"example": {
"key": "input_1",
"kind": "input",
Expand All @@ -51,7 +47,7 @@ def from_service_io(
cls,
kind: PortKindStr,
key: str,
port: Union[ServiceInput, ServiceOutput],
port: ServiceInput | ServiceOutput,
) -> "ServicePortGet":
kwargs: dict[str, Any] = {"key": key, "kind": kind}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
from typing import Optional

from models_library.generated_models.docker_rest_api import (
ServiceSpec as DockerServiceSpec,
)
from pydantic import BaseModel, Field

from ..generated_models.docker_rest_api import ServiceSpec as DockerServiceSpec


class ServiceSpecifications(BaseModel):
sidecar: Optional[DockerServiceSpec] = Field(
sidecar: DockerServiceSpec | None = Field(
default=None,
description="schedule-time specifications for the service sidecar (follows Docker Service creation API, see https://docs.docker.com/engine/api/v1.25/#operation/ServiceCreate)",
)
service: Optional[DockerServiceSpec] = Field(
service: DockerServiceSpec | None = Field(
default=None,
description="schedule-time specifications specifications for the service (follows Docker Service creation API (specifically only the Resources part), see https://docs.docker.com/engine/api/v1.41/#tag/Service/operation/ServiceCreate",
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import logging
from typing import TypeAlias

from pydantic import BaseModel, ConstrainedFloat, Field, validate_arguments, validator

_logger = logging.getLogger(__name__)

TaskId = str

ProgressMessage = str
ProgressMessage: TypeAlias = str


class ProgressPercent(ConstrainedFloat):
Expand All @@ -21,7 +22,7 @@ class TaskProgress(BaseModel):
"""

message: ProgressMessage = Field(default="")
percent: ProgressPercent = Field(default=ProgressPercent(0.0))
percent: ProgressPercent = Field(default=0.0) # type: ignore[assignment]

@validate_arguments
def update(
Expand All @@ -35,14 +36,15 @@ def update(
self.message = message
if percent:
if not (0.0 <= percent <= 1.0):
raise ValueError(f"{percent=} must be in range [0.0, 1.0]")
msg = f"percent={percent!r} must be in range [0.0, 1.0]"
raise ValueError(msg)
self.percent = percent

_logger.debug("Progress update: %s", f"{self}")

@classmethod
def create(cls) -> "TaskProgress":
return cls.parse_obj(dict(message="", percent=0.0))
return cls.parse_obj({"message": "", "percent": 0.0})

@validator("percent")
@classmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@
from typing import Any, ClassVar
from uuid import UUID

from models_library.projects_nodes_io import (
LocationID,
LocationName,
NodeID,
SimcoreS3FileID,
StorageFileID,
)
from pydantic import (
BaseModel,
ByteSize,
Expand All @@ -34,6 +27,13 @@

from .basic_regex import DATCORE_DATASET_NAME_RE, S3_BUCKET_NAME_RE
from .generics import ListModel
from .projects_nodes_io import (
LocationID,
LocationName,
NodeID,
SimcoreS3FileID,
StorageFileID,
)

ETag = str

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class Config:

def data(
self,
*,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
Expand All @@ -49,6 +50,7 @@ def data(

def data_json(
self,
*,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@
from pydantic import Field, validator

from ..api_schemas_long_running_tasks.tasks import TaskGet
from ..basic_types import HttpUrlWithCustomMinLength
from ..emails import LowerCaseEmailStr
from ..projects import ClassifierID, DateTimeStr, NodesDict, ProjectID
from ..projects_access import AccessRights, GroupIDStr
from ..projects_nodes import HttpUrlWithCustomMinLength
from ..projects_state import ProjectState
from ..projects_ui import StudyUI
from ..utils.common_validators import empty_str_to_none, none_to_empty_str
from ..utils.common_validators import (
empty_str_to_none_pre_validator,
none_to_empty_str_pre_validator,
)
from ..utils.pydantic_tools_extension import FieldNotRequired
from ._base import EmptyModel, InputSchema, OutputSchema
from .permalinks import ProjectPermalink
Expand All @@ -35,7 +38,7 @@ class ProjectCreateNew(InputSchema):

_empty_is_none = validator(
"uuid", "thumbnail", "description", allow_reuse=True, pre=True
)(empty_str_to_none)
)(empty_str_to_none_pre_validator)


# NOTE: based on OVERRIDABLE_DOCUMENT_KEYS
Expand All @@ -46,7 +49,7 @@ class ProjectCopyOverride(InputSchema):
prj_owner: LowerCaseEmailStr

_empty_is_none = validator("thumbnail", allow_reuse=True, pre=True)(
empty_str_to_none
empty_str_to_none_pre_validator
)


Expand All @@ -69,7 +72,7 @@ class ProjectGet(OutputSchema):
permalink: ProjectPermalink = FieldNotRequired()

_empty_description = validator("description", allow_reuse=True, pre=True)(
none_to_empty_str
none_to_empty_str_pre_validator
)


Expand Down Expand Up @@ -99,7 +102,7 @@ class ProjectReplace(InputSchema):
)

_empty_is_none = validator("thumbnail", allow_reuse=True, pre=True)(
empty_str_to_none
empty_str_to_none_pre_validator
)


Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from datetime import datetime
from enum import Enum

from models_library.projects import ProjectID
from models_library.projects_nodes_io import NodeID
from models_library.services import ServiceKey, ServiceVersion
from pydantic import BaseModel

from ..projects import ProjectID
from ..projects_nodes_io import NodeID
from ..services import ServiceKey, ServiceVersion

# Frontend API


Expand Down
Loading

0 comments on commit f2f6a81

Please sign in to comment.