Skip to content

Commit f9700d3

Browse files
odeimaizpcrespov
authored andcommitted
🎨♻️ [Frontend (& API)] Retire history from list latest services (ITISFoundation#7292)
Co-authored-by: Pedro Crespo-Valero <[email protected]>
1 parent e8fb81b commit f9700d3

File tree

48 files changed

+1078
-991
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1078
-991
lines changed

api/specs/web-server/_catalog.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
from fastapi import APIRouter, Depends
44
from models_library.api_schemas_api_server.pricing_plans import ServicePricingPlanGet
55
from models_library.api_schemas_webserver.catalog import (
6+
CatalogLatestServiceGet,
67
CatalogServiceGet,
7-
CatalogServiceListItem,
88
CatalogServiceUpdate,
99
ServiceInputGet,
1010
ServiceInputKey,
@@ -34,10 +34,9 @@
3434

3535
@router.get(
3636
"/catalog/services/-/latest",
37-
response_model=Page[CatalogServiceListItem],
37+
response_model=Page[CatalogLatestServiceGet],
3838
)
39-
def list_services_latest(_query: Annotated[ListServiceParams, Depends()]):
40-
pass
39+
def list_services_latest(_query: Annotated[ListServiceParams, Depends()]): ...
4140

4241

4342
@router.get(

packages/models-library/src/models_library/api_schemas_catalog/services.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,15 @@ class _BaseServiceGetV2(CatalogOutputSchema):
202202

203203
access_rights: dict[GroupID, ServiceGroupAccessRightsV2] | None
204204

205-
classifiers: list[str] | None = []
206-
quality: dict[str, Any] = {}
205+
classifiers: Annotated[
206+
list[str] | None,
207+
Field(default_factory=list),
208+
] = DEFAULT_FACTORY
209+
210+
quality: Annotated[
211+
dict[str, Any],
212+
Field(default_factory=dict),
213+
] = DEFAULT_FACTORY
207214

208215
model_config = ConfigDict(
209216
extra="forbid",
@@ -212,6 +219,34 @@ class _BaseServiceGetV2(CatalogOutputSchema):
212219
)
213220

214221

222+
class LatestServiceGet(_BaseServiceGetV2):
223+
release: Annotated[
224+
ServiceRelease,
225+
Field(description="release information of current (latest) service"),
226+
]
227+
228+
@staticmethod
229+
def _update_json_schema_extra(schema: JsonDict) -> None:
230+
schema.update(
231+
{
232+
"examples": [
233+
{
234+
**_EXAMPLE_SLEEPER, # v2.2.1 (latest)
235+
"release": {
236+
"version": _EXAMPLE_SLEEPER["version"],
237+
"version_display": "Summer Release",
238+
"released": "2025-07-20T15:00:00",
239+
},
240+
}
241+
]
242+
}
243+
)
244+
245+
model_config = ConfigDict(
246+
json_schema_extra=_update_json_schema_extra,
247+
)
248+
249+
215250
class ServiceGetV2(_BaseServiceGetV2):
216251
# Model used in catalog's rpc and rest interfaces
217252
history: Annotated[
@@ -235,7 +270,7 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
235270
{
236271
"version": _EXAMPLE_SLEEPER["version"],
237272
"version_display": "Summer Release",
238-
"released": "2024-07-20T15:00:00",
273+
"released": "2024-07-21T15:00:00",
239274
},
240275
{
241276
"version": "2.0.0",
@@ -263,7 +298,7 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
263298
},
264299
{
265300
"version": "0.9.0",
266-
"retired": "2024-07-20T15:00:00",
301+
"retired": "2024-07-20T16:00:00",
267302
},
268303
{"version": "0.8.0"},
269304
{"version": "0.1.0"},
@@ -288,21 +323,9 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
288323
)
289324

290325

291-
class ServiceListItem(_BaseServiceGetV2):
292-
history: Annotated[
293-
list[ServiceRelease],
294-
Field(
295-
default_factory=list,
296-
deprecated=True,
297-
description="History will be replaced by current 'release' instead",
298-
json_schema_extra={"default": []},
299-
),
300-
] = DEFAULT_FACTORY
301-
302-
303326
PageRpcServicesGetV2: TypeAlias = PageRpc[
304327
# WARNING: keep this definition in models_library and not in the RPC interface
305-
ServiceListItem
328+
LatestServiceGet
306329
]
307330

308331
ServiceResourcesGet: TypeAlias = ServiceResourcesDict

packages/models-library/src/models_library/api_schemas_webserver/catalog.py

Lines changed: 120 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Annotated, Any, TypeAlias
1+
from typing import Annotated, TypeAlias
22

33
from pydantic import ConfigDict, Field
44
from pydantic.config import JsonDict
@@ -106,132 +106,131 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
106106

107107
ServiceInputsGetDict: TypeAlias = dict[ServicePortKey, ServiceInputGet]
108108
ServiceOutputsGetDict: TypeAlias = dict[ServicePortKey, ServiceOutputGet]
109-
110-
111-
_EXAMPLE_FILEPICKER: dict[str, Any] = {
112-
**api_schemas_catalog_services.ServiceGet.model_json_schema()["examples"][1],
113-
"inputs": {},
114-
"outputs": {
115-
"outFile": {
116-
"displayOrder": 0,
117-
"label": "File",
118-
"description": "Chosen File",
119-
"type": "data:*/*",
120-
"fileToKeyMap": None,
121-
"keyId": "outFile",
122-
}
123-
},
124-
}
125-
126-
_EXAMPLE_SLEEPER: dict[str, Any] = {
127-
**api_schemas_catalog_services.ServiceGet.model_json_schema()["examples"][0],
128-
"inputs": {
129-
"input_1": {
130-
"displayOrder": 1,
131-
"label": "File with int number",
132-
"description": "Pick a file containing only one integer",
133-
"type": "data:text/plain",
134-
"fileToKeyMap": {"single_number.txt": "input_1"},
135-
"keyId": "input_1",
136-
},
137-
"input_2": {
138-
"unitLong": "second",
139-
"unitShort": "s",
140-
"label": "Sleep interval",
141-
"description": "Choose an amount of time to sleep in range [0:]",
142-
"keyId": "input_2",
143-
"displayOrder": 2,
144-
"type": "ref_contentSchema",
145-
"contentSchema": {
146-
"title": "Sleep interval",
147-
"type": "integer",
148-
"x_unit": "second",
149-
"minimum": 0,
150-
},
151-
"defaultValue": 2,
152-
},
153-
"input_3": {
154-
"displayOrder": 3,
155-
"label": "Fail after sleep",
156-
"description": "If set to true will cause service to fail after it sleeps",
157-
"type": "boolean",
158-
"defaultValue": False,
159-
"keyId": "input_3",
160-
},
161-
"input_4": {
162-
"unitLong": "meter",
163-
"unitShort": "m",
164-
"label": "Distance to bed",
165-
"description": "It will first walk the distance to bed",
166-
"keyId": "input_4",
167-
"displayOrder": 4,
168-
"type": "ref_contentSchema",
169-
"contentSchema": {
170-
"title": "Distance to bed",
171-
"type": "integer",
172-
"x_unit": "meter",
173-
},
174-
"defaultValue": 0,
175-
},
176-
"input_5": {
177-
"unitLong": "byte",
178-
"unitShort": "B",
179-
"label": "Dream (or nightmare) of the night",
180-
"description": "Defines the size of the dream that will be generated [0:]",
181-
"keyId": "input_5",
182-
"displayOrder": 5,
183-
"type": "ref_contentSchema",
184-
"contentSchema": {
185-
"title": "Dream of the night",
186-
"type": "integer",
187-
"x_unit": "byte",
188-
"minimum": 0,
189-
},
190-
"defaultValue": 0,
191-
},
192-
},
193-
"outputs": {
194-
"output_1": {
195-
"displayOrder": 1,
196-
"label": "File containing one random integer",
197-
"description": "Integer is generated in range [1-9]",
198-
"type": "data:text/plain",
199-
"fileToKeyMap": {"single_number.txt": "output_1"},
200-
"keyId": "output_1",
201-
},
202-
"output_2": {
203-
"unitLong": "second",
204-
"unitShort": "s",
205-
"label": "Random sleep interval",
206-
"description": "Interval is generated in range [1-9]",
207-
"keyId": "output_2",
208-
"displayOrder": 2,
209-
"type": "ref_contentSchema",
210-
"contentSchema": {
211-
"title": "Random sleep interval",
212-
"type": "integer",
213-
"x_unit": "second",
214-
},
215-
},
216-
"output_3": {
217-
"displayOrder": 3,
218-
"label": "Dream output",
219-
"description": "Contains some random data representing a dream",
220-
"type": "data:text/plain",
221-
"fileToKeyMap": {"dream.txt": "output_3"},
222-
"keyId": "output_3",
223-
},
224-
},
225-
}
226-
227-
228109
ServiceResourcesGet: TypeAlias = api_schemas_catalog_services.ServiceResourcesGet
229110

230111

231-
class CatalogServiceListItem(api_schemas_catalog_services.ServiceListItem):
112+
class CatalogLatestServiceGet(api_schemas_catalog_services.LatestServiceGet):
232113
inputs: ServiceInputsGetDict # type: ignore[assignment]
233114
outputs: ServiceOutputsGetDict # type: ignore[assignment]
234115

116+
@staticmethod
117+
def _update_json_schema_extra(schema: JsonDict) -> None:
118+
base_example = (
119+
api_schemas_catalog_services.LatestServiceGet.model_json_schema()[
120+
"examples"
121+
][0]
122+
)
123+
124+
schema.update(
125+
{
126+
"example": {
127+
**base_example,
128+
"inputs": {
129+
"input_1": {
130+
"displayOrder": 1,
131+
"label": "File with int number",
132+
"description": "Pick a file containing only one integer",
133+
"type": "data:text/plain",
134+
"fileToKeyMap": {"single_number.txt": "input_1"},
135+
"keyId": "input_1",
136+
},
137+
"input_2": {
138+
"unitLong": "second",
139+
"unitShort": "s",
140+
"label": "Sleep interval",
141+
"description": "Choose an amount of time to sleep in range [0:]",
142+
"keyId": "input_2",
143+
"displayOrder": 2,
144+
"type": "ref_contentSchema",
145+
"contentSchema": {
146+
"title": "Sleep interval",
147+
"type": "integer",
148+
"x_unit": "second",
149+
"minimum": 0,
150+
},
151+
"defaultValue": 2,
152+
},
153+
"input_3": {
154+
"displayOrder": 3,
155+
"label": "Fail after sleep",
156+
"description": "If set to true will cause service to fail after it sleeps",
157+
"type": "boolean",
158+
"defaultValue": False,
159+
"keyId": "input_3",
160+
},
161+
"input_4": {
162+
"unitLong": "meter",
163+
"unitShort": "m",
164+
"label": "Distance to bed",
165+
"description": "It will first walk the distance to bed",
166+
"keyId": "input_4",
167+
"displayOrder": 4,
168+
"type": "ref_contentSchema",
169+
"contentSchema": {
170+
"title": "Distance to bed",
171+
"type": "integer",
172+
"x_unit": "meter",
173+
},
174+
"defaultValue": 0,
175+
},
176+
"input_5": {
177+
"unitLong": "byte",
178+
"unitShort": "B",
179+
"label": "Dream (or nightmare) of the night",
180+
"description": "Defines the size of the dream that will be generated [0:]",
181+
"keyId": "input_5",
182+
"displayOrder": 5,
183+
"type": "ref_contentSchema",
184+
"contentSchema": {
185+
"title": "Dream of the night",
186+
"type": "integer",
187+
"x_unit": "byte",
188+
"minimum": 0,
189+
},
190+
"defaultValue": 0,
191+
},
192+
},
193+
"outputs": {
194+
"output_1": {
195+
"displayOrder": 1,
196+
"label": "File containing one random integer",
197+
"description": "Integer is generated in range [1-9]",
198+
"type": "data:text/plain",
199+
"fileToKeyMap": {"single_number.txt": "output_1"},
200+
"keyId": "output_1",
201+
},
202+
"output_2": {
203+
"unitLong": "second",
204+
"unitShort": "s",
205+
"label": "Random sleep interval",
206+
"description": "Interval is generated in range [1-9]",
207+
"keyId": "output_2",
208+
"displayOrder": 2,
209+
"type": "ref_contentSchema",
210+
"contentSchema": {
211+
"title": "Random sleep interval",
212+
"type": "integer",
213+
"x_unit": "second",
214+
},
215+
},
216+
"output_3": {
217+
"displayOrder": 3,
218+
"label": "Dream output",
219+
"description": "Contains some random data representing a dream",
220+
"type": "data:text/plain",
221+
"fileToKeyMap": {"dream.txt": "output_3"},
222+
"keyId": "output_3",
223+
},
224+
},
225+
}
226+
}
227+
)
228+
229+
model_config = ConfigDict(
230+
**OutputSchema.model_config,
231+
json_schema_extra=_update_json_schema_extra,
232+
)
233+
235234

236235
class CatalogServiceGet(api_schemas_catalog_services.ServiceGetV2):
237236
# pylint: disable=too-many-ancestors

0 commit comments

Comments
 (0)