Skip to content

Commit 36e3b06

Browse files
authored
🎨 Services metadata include an icon πŸ—ƒοΈ (#7174)
1 parent 70e88e8 commit 36e3b06

File tree

24 files changed

+352
-140
lines changed

24 files changed

+352
-140
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from pydantic import BaseModel
2+
3+
4+
class CatalogInputSchema(BaseModel):
5+
...
6+
7+
8+
class CatalogOutputSchema(BaseModel):
9+
...

β€Žpackages/models-library/src/models_library/api_schemas_catalog/services.pyβ€Ž

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import Any, TypeAlias
33

44
from models_library.rpc_pagination import PageRpc
5-
from pydantic import BaseModel, ConfigDict, Field, HttpUrl, NonNegativeInt
5+
from pydantic import ConfigDict, Field, HttpUrl, NonNegativeInt
66
from pydantic.config import JsonDict
77

88
from ..boot_options import BootOptions
@@ -21,6 +21,7 @@
2121
from ..services_resources import ServiceResourcesDict
2222
from ..services_types import ServiceKey, ServiceVersion
2323
from ..utils.change_case import snake_to_camel
24+
from ._base import CatalogInputSchema, CatalogOutputSchema
2425

2526
_EXAMPLE_FILEPICKER: dict[str, Any] = {
2627
"name": "File Picker",
@@ -71,6 +72,7 @@
7172
"thumbnail": None,
7273
"description": "A service which awaits for time to pass, two times.",
7374
"description_ui": True,
75+
"icon": "https://cdn-icons-png.flaticon.com/512/25/25231.png",
7476
"classifiers": [],
7577
"quality": {},
7678
"accessRights": {"1": {"execute": True, "write": False}},
@@ -167,12 +169,14 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
167169
)
168170

169171

170-
class ServiceGetV2(BaseModel):
172+
class ServiceGetV2(CatalogOutputSchema):
173+
# Model used in catalog's rpc and rest interfaces
171174
key: ServiceKey
172175
version: ServiceVersion
173176

174177
name: str
175178
thumbnail: HttpUrl | None = None
179+
icon: HttpUrl | None = None
176180
description: str
177181

178182
description_ui: bool = False
@@ -280,9 +284,10 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
280284
ServiceResourcesGet: TypeAlias = ServiceResourcesDict
281285

282286

283-
class ServiceUpdateV2(BaseModel):
287+
class ServiceUpdateV2(CatalogInputSchema):
284288
name: str | None = None
285289
thumbnail: HttpUrl | None = None
290+
icon: HttpUrl | None = None
286291

287292
description: str | None = None
288293
description_ui: bool = False

β€Žpackages/models-library/src/models_library/services_base.pyβ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Annotated
22

3-
from pydantic import BaseModel, ConfigDict, Field, field_validator
3+
from pydantic import BaseModel, ConfigDict, Field, HttpUrl, field_validator
44

55
from .services_types import ServiceKey, ServiceVersion
66
from .utils.common_validators import empty_str_to_none_pre_validator
@@ -41,6 +41,7 @@ class ServiceBaseDisplay(BaseModel):
4141
validate_default=True,
4242
),
4343
] = None
44+
icon: Annotated[HttpUrl | None, Field(description="URL to the service icon")] = None
4445
description: Annotated[
4546
str,
4647
Field(

β€Žpackages/models-library/src/models_library/services_metadata_editable.pyβ€Ž

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Annotated, Any
44

55
from common_library.basic_types import DEFAULT_FACTORY
6-
from pydantic import ConfigDict, Field
6+
from pydantic import ConfigDict, Field, HttpUrl
77
from pydantic.config import JsonDict
88

99
from .services_base import ServiceBaseDisplay
@@ -22,18 +22,21 @@ class ServiceMetaDataEditable(ServiceBaseDisplay):
2222
# Overrides ServiceBaseDisplay fields to Optional for a partial update
2323
name: str | None # type: ignore[assignment]
2424
thumbnail: str | None
25+
icon: HttpUrl | None
2526
description: str | None # type: ignore[assignment]
2627
description_ui: bool = False
2728
version_display: str | None = None
2829

2930
# Below fields only in the database ----
30-
deprecated: datetime | None = Field(
31-
default=None,
32-
description="Owner can set the date to retire the service. Three possibilities:"
33-
"If None, the service is marked as `published`;"
34-
"If now<deprecated the service is marked as deprecated;"
35-
"If now>=deprecated, the service is retired",
36-
)
31+
deprecated: Annotated[
32+
datetime | None,
33+
Field(
34+
description="Owner can set the date to retire the service. Three possibilities:"
35+
"If None, the service is marked as `published`;"
36+
"If now<deprecated the service is marked as deprecated;"
37+
"If now>=deprecated, the service is retired",
38+
),
39+
] = None
3740
classifiers: list[str] | None
3841
quality: Annotated[
3942
dict[str, Any], Field(default_factory=dict, json_schema_extra={"default": {}})
@@ -49,6 +52,7 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
4952
"name": "sim4life",
5053
"description": "s4l web",
5154
"thumbnail": "https://thumbnailit.org/image",
55+
"icon": "https://cdn-icons-png.flaticon.com/512/25/25231.png",
5256
"quality": {
5357
"enabled": True,
5458
"tsr_target": {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""new icon table
2+
3+
Revision ID: 3fe27ff48f73
4+
Revises: 611f956aa3e3
5+
Create Date: 2025-02-05 16:50:02.419293+00:00
6+
7+
"""
8+
import sqlalchemy as sa
9+
from alembic import op
10+
11+
# revision identifiers, used by Alembic.
12+
revision = "3fe27ff48f73"
13+
down_revision = "611f956aa3e3"
14+
branch_labels = None
15+
depends_on = None
16+
17+
18+
def upgrade():
19+
# ### commands auto generated by Alembic - please adjust! ###
20+
op.add_column("services_meta_data", sa.Column("icon", sa.String(), nullable=True))
21+
# ### end Alembic commands ###
22+
23+
24+
def downgrade():
25+
# ### commands auto generated by Alembic - please adjust! ###
26+
op.drop_column("services_meta_data", "icon")
27+
# ### end Alembic commands ###

β€Žpackages/postgres-database/src/simcore_postgres_database/models/services.pyβ€Ž

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@
6868
nullable=True,
6969
doc="Link to image to us as service thumbnail (editable)",
7070
),
71+
sa.Column(
72+
"icon",
73+
sa.String,
74+
nullable=True,
75+
doc="Link to icon (editable)",
76+
),
7177
sa.Column(
7278
"version_display",
7379
sa.String,

β€Žpackages/pytest-simcore/src/pytest_simcore/helpers/faker_factories.pyβ€Ž

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@
2727
DEFAULT_FAKER: Final = faker.Faker()
2828

2929

30+
def random_icon_url(fake: Faker):
31+
return fake.image_url(width=16, height=16)
32+
33+
34+
def random_thumbnail_url(fake: Faker):
35+
return fake.image_url(width=32, height=32)
36+
37+
3038
def _compute_hash(password: str) -> str:
3139
try:
3240
# 'passlib' will be used only if already installed.
@@ -396,7 +404,8 @@ def random_service_meta_data(
396404
# optional
397405
"description_ui": fake.pybool(),
398406
"owner": owner_primary_gid,
399-
"thumbnail": _pick_from([fake.image_url(), None]), # nullable
407+
"thumbnail": _pick_from([random_thumbnail_url(fake), None]), # nullable
408+
"icon": _pick_from([random_icon_url(fake), None]), # nullable
400409
"version_display": _pick_from([f"v{_version}", None]), # nullable
401410
"classifiers": [], # has default
402411
"quality": {}, # has default

β€Žservices/catalog/VERSIONβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.7.0
1+
0.8.0

β€Žservices/catalog/openapi.jsonβ€Ž

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"info": {
44
"title": "simcore-service-catalog",
55
"description": "Manages and maintains a catalog of all published components (e.g. macro-algorithms, scripts, etc)",
6-
"version": "0.7.0"
6+
"version": "0.8.0"
77
},
88
"paths": {
99
"/": {
@@ -2618,6 +2618,21 @@
26182618
"title": "Thumbnail",
26192619
"description": "URL to the service thumbnail"
26202620
},
2621+
"icon": {
2622+
"anyOf": [
2623+
{
2624+
"type": "string",
2625+
"maxLength": 2083,
2626+
"minLength": 1,
2627+
"format": "uri"
2628+
},
2629+
{
2630+
"type": "null"
2631+
}
2632+
],
2633+
"title": "Icon",
2634+
"description": "URL to the service icon"
2635+
},
26212636
"description": {
26222637
"type": "string",
26232638
"title": "Description",

β€Žservices/catalog/setup.cfgβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.7.0
2+
current_version = 0.8.0
33
commit = True
44
message = services/catalog version: {current_version} β†’ {new_version}
55
tag = False

0 commit comments

Comments
Β (0)