Skip to content

Commit d3fa0e5

Browse files
removing vip mels
1 parent 4d72da8 commit d3fa0e5

File tree

9 files changed

+79
-120
lines changed

9 files changed

+79
-120
lines changed

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

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
from datetime import datetime
2-
from typing import NamedTuple
2+
from typing import Any, NamedTuple
33

44
from models_library.licensed_items import (
5+
VIP_DETAILS_EXAMPLE,
56
LicensedItemID,
67
LicensedResourceType,
7-
VipDetails,
88
)
99
from models_library.resource_tracker import PricingPlanId
10-
from pydantic import BaseModel, ConfigDict, PositiveInt
10+
from models_library.utils.common_validators import to_camel_recursive
11+
from pydantic import AfterValidator, BaseModel, ConfigDict, PositiveInt
1112
from pydantic.alias_generators import to_camel
13+
from typing_extensions import Annotated
1214

1315
from ._base import OutputSchema
1416

@@ -20,25 +22,24 @@ class LicensedItemRpcGet(BaseModel):
2022
display_name: str
2123
licensed_resource_type: LicensedResourceType
2224
pricing_plan_id: PricingPlanId
23-
licensed_resource_type_details: VipDetails
25+
licensed_resource_type_details: dict[str, Any]
2426
created_at: datetime
2527
modified_at: datetime
2628
model_config = ConfigDict(
29+
alias_generator=to_camel,
2730
json_schema_extra={
2831
"examples": [
2932
{
3033
"licensed_item_id": "0362b88b-91f8-4b41-867c-35544ad1f7a1",
3134
"display_name": "best-model",
3235
"licensed_resource_type": f"{LicensedResourceType.VIP_MODEL}",
3336
"pricing_plan_id": "15",
34-
"licensed_resource_type_details": VipDetails.model_config[
35-
"json_schema_extra"
36-
]["examples"][0],
37+
"licensed_resource_type_details": VIP_DETAILS_EXAMPLE,
3738
"created_at": "2024-12-12 09:59:26.422140",
3839
"modified_at": "2024-12-12 09:59:26.422140",
3940
}
4041
]
41-
}
42+
},
4243
)
4344

4445

@@ -66,7 +67,9 @@ class LicensedItemRestGet(OutputSchema):
6667
display_name: str
6768
licensed_resource_type: LicensedResourceType
6869
pricing_plan_id: PricingPlanId
69-
licensed_resource_type_details: VipDetails
70+
licensed_resource_type_details: Annotated[
71+
dict[str, Any], AfterValidator(to_camel_recursive)
72+
]
7073
created_at: datetime
7174
modified_at: datetime
7275
model_config = ConfigDict(
@@ -77,9 +80,7 @@ class LicensedItemRestGet(OutputSchema):
7780
"display_name": "best-model",
7881
"licensed_resource_type": f"{LicensedResourceType.VIP_MODEL}",
7982
"pricing_plan_id": "15",
80-
"licensed_resource_type_details": VipDetails.model_config[
81-
"json_schema_extra"
82-
]["examples"][0],
83+
"licensed_resource_type_details": VIP_DETAILS_EXAMPLE,
8384
"created_at": "2024-12-12 09:59:26.422140",
8485
"modified_at": "2024-12-12 09:59:26.422140",
8586
}

packages/models-library/src/models_library/licensed_items.py

Lines changed: 28 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
from datetime import datetime
22
from enum import auto
3-
from typing import TypeAlias
3+
from typing import Any, TypeAlias
44
from uuid import UUID
55

6-
from pydantic import AliasGenerator, BaseModel, ConfigDict, Field
7-
from pydantic.alias_generators import to_camel
6+
from pydantic import BaseModel, ConfigDict, Field
87

98
from .products import ProductName
109
from .resource_tracker import PricingPlanId
@@ -17,78 +16,31 @@ class LicensedResourceType(StrAutoEnum):
1716
VIP_MODEL = auto()
1817

1918

20-
class VipFeatures(BaseModel):
21-
name: str
22-
version: str
23-
sex: str
24-
age: str
25-
weight: str
26-
height: str
27-
data: str
28-
ethnicity: str
29-
functionality: str
30-
31-
model_config = ConfigDict(
32-
alias_generator=AliasGenerator(
33-
serialization_alias=to_camel,
34-
),
35-
populate_by_name=True,
36-
extra="allow",
37-
json_schema_extra={
38-
"examples": [
39-
{
40-
"name": "Duke",
41-
"version": "V2.0",
42-
"sex": "Male",
43-
"age": "34 years",
44-
"weight": "70.2 Kg",
45-
"height": "1.77 m",
46-
"data": "2015-03-01",
47-
"ethnicity": "Caucasian",
48-
"functionality": "Static",
49-
"additional_field": "allowed",
50-
}
51-
]
52-
},
53-
)
54-
55-
56-
class VipDetails(BaseModel):
57-
id: int
58-
description: str
59-
thumbnail: str
60-
features: VipFeatures
61-
doi: str
62-
license_key: str | None
63-
license_version: str | None
64-
protection: str
65-
available_from_url: str
66-
67-
model_config = ConfigDict(
68-
alias_generator=AliasGenerator(
69-
serialization_alias=to_camel,
70-
),
71-
populate_by_name=True,
72-
extra="allow",
73-
json_schema_extra={
74-
"examples": [
75-
{
76-
"id": 1,
77-
"description": "custom description",
78-
"thumbnail": "custom description",
79-
"features": VipFeatures.model_config["json_schema_extra"][
80-
"examples"
81-
][0],
82-
"doi": "custom value",
83-
"license_key": "custom value",
84-
"license_version": "custom value",
85-
"protection": "custom value",
86-
"available_from_url": "custom value",
87-
"additional_field": "allowed",
88-
}
89-
]
90-
},
91-
)
19+
VIP_FEAUTES_EXAMPLE = {
20+
"name": "Duke",
21+
"version": "V2.0",
22+
"sex": "Male",
23+
"age": "34 years",
24+
"weight": "70.2 Kg",
25+
"height": "1.77 m",
26+
"data": "2015-03-01",
27+
"ethnicity": "Caucasian",
28+
"functionality": "Static",
29+
"additional_field": "allowed",
30+
}
31+
32+
VIP_DETAILS_EXAMPLE = {
33+
"id": 1,
34+
"description": "custom description",
35+
"thumbnail": "custom description",
36+
"features": VIP_FEAUTES_EXAMPLE,
37+
"doi": "custom value",
38+
"license_key": "custom value",
39+
"license_version": "custom value",
40+
"protection": "custom value",
41+
"available_from_url": "custom value",
42+
"additional_field": "allowed",
43+
}
9244

9345

9446
#
@@ -102,7 +54,7 @@ class LicensedItemDB(BaseModel):
10254
licensed_resource_type: LicensedResourceType
10355
pricing_plan_id: PricingPlanId
10456
product_name: ProductName
105-
licensed_resource_type_details: VipDetails
57+
licensed_resource_type_details: dict[str, Any]
10658
created: datetime = Field(
10759
...,
10860
description="Timestamp on creation",

packages/models-library/src/models_library/utils/common_validators.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class MyModel(BaseModel):
2323
from common_library.json_serialization import json_loads
2424
from orjson import JSONDecodeError
2525
from pydantic import BaseModel
26+
from pydantic.alias_generators import to_camel
2627

2728

2829
def empty_str_to_none_pre_validator(value: Any):
@@ -120,3 +121,23 @@ def _validator(cls: type[BaseModel], values):
120121
return values
121122

122123
return _validator
124+
125+
126+
def to_camel_recursive(data: dict[str, Any]) -> dict[str, Any]:
127+
"""Recursively convert dictionary keys to camelCase"""
128+
if not isinstance(data, dict):
129+
return data # Return as-is if it's not a dictionary
130+
131+
new_dict = {}
132+
for key, value in data.items():
133+
new_key = to_camel(key) # Convert key to camelCase
134+
if isinstance(value, dict):
135+
new_dict[new_key] = to_camel_recursive(value) # Recursive call for dicts
136+
elif isinstance(value, list):
137+
new_dict[new_key] = [
138+
to_camel_recursive(item) if isinstance(item, dict) else item
139+
for item in value
140+
]
141+
else:
142+
new_dict[new_key] = value
143+
return new_dict

services/api-server/src/simcore_service_api_server/models/schemas/model_adapter.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from datetime import datetime
44
from decimal import Decimal
5-
from typing import Annotated
5+
from typing import Annotated, Any
66

77
from models_library.api_schemas_api_server.pricing_plans import (
88
ServicePricingPlanGet as _ServicePricingPlanGet,
@@ -24,11 +24,7 @@
2424
)
2525
from models_library.basic_types import IDStr, NonNegativeDecimal
2626
from models_library.groups import GroupID
27-
from models_library.licensed_items import (
28-
LicensedItemID,
29-
LicensedResourceType,
30-
VipDetails,
31-
)
27+
from models_library.licensed_items import LicensedItemID, LicensedResourceType
3228
from models_library.products import ProductName
3329
from models_library.resource_tracker import (
3430
PricingPlanClassification,
@@ -144,7 +140,7 @@ class LicensedItemGet(BaseModel):
144140
display_name: Annotated[str, Field(alias="display_name")]
145141
licensed_resource_type: LicensedResourceType
146142
pricing_plan_id: PricingPlanId
147-
licensed_resource_type_details: VipDetails
143+
licensed_resource_type_details: dict[str, Any]
148144
created_at: datetime
149145
modified_at: datetime
150146
model_config = ConfigDict(

services/web/server/src/simcore_service_webserver/licenses/_common/models.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import logging
22
from datetime import datetime
3-
from typing import NamedTuple
3+
from typing import Any, NamedTuple
44

55
from models_library.basic_types import IDStr
66
from models_library.licensed_items import (
7+
VIP_DETAILS_EXAMPLE,
78
LicensedItemID,
89
LicensedResourceType,
9-
VipDetails,
1010
)
1111
from models_library.resource_tracker import PricingPlanId, PricingUnitId
1212
from models_library.resource_tracker_licensed_items_purchases import (
@@ -34,7 +34,7 @@ class LicensedItem(BaseModel):
3434
display_name: str
3535
licensed_resource_type: LicensedResourceType
3636
pricing_plan_id: PricingPlanId
37-
licensed_resource_type_details: VipDetails
37+
licensed_resource_type_details: dict[str, Any]
3838
created_at: datetime
3939
modified_at: datetime
4040
model_config = ConfigDict(
@@ -45,9 +45,7 @@ class LicensedItem(BaseModel):
4545
"display_name": "best-model",
4646
"licensed_resource_type": f"{LicensedResourceType.VIP_MODEL}",
4747
"pricing_plan_id": "15",
48-
"licensed_resource_type_details": VipDetails.model_config[
49-
"json_schema_extra"
50-
]["examples"][0],
48+
"licensed_resource_type_details": VIP_DETAILS_EXAMPLE,
5149
"created_at": "2024-12-12 09:59:26.422140",
5250
"modified_at": "2024-12-12 09:59:26.422140",
5351
}

services/web/server/src/simcore_service_webserver/licenses/_licensed_items_repository.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
"""
66

77
import logging
8-
from typing import cast
8+
from typing import Any, cast
99

1010
from aiohttp import web
1111
from models_library.licensed_items import (
1212
LicensedItemDB,
1313
LicensedItemID,
1414
LicensedItemUpdateDB,
1515
LicensedResourceType,
16-
VipDetails,
1716
)
1817
from models_library.products import ProductName
1918
from models_library.resource_tracker import PricingPlanId
@@ -56,7 +55,7 @@ async def create(
5655
display_name: str,
5756
licensed_resource_type: LicensedResourceType,
5857
pricing_plan_id: PricingPlanId,
59-
licensed_resource_type_details: VipDetails,
58+
licensed_resource_type_details: dict[str, Any],
6059
) -> LicensedItemDB:
6160
async with transaction_context(get_asyncpg_engine(app), connection) as conn:
6261
result = await conn.stream(

services/web/server/tests/unit/with_dbs/04/licenses/test_licensed_items_repository.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
import pytest
99
from aiohttp.test_utils import TestClient
1010
from models_library.licensed_items import (
11+
VIP_DETAILS_EXAMPLE,
1112
LicensedItemDB,
1213
LicensedItemUpdateDB,
1314
LicensedResourceType,
14-
VipDetails,
1515
)
1616
from models_library.rest_ordering import OrderBy
1717
from pytest_simcore.helpers.webserver_login import UserInfoDict
@@ -48,9 +48,7 @@ async def test_licensed_items_db_crud(
4848
display_name="Model A",
4949
licensed_resource_type=LicensedResourceType.VIP_MODEL,
5050
pricing_plan_id=pricing_plan_id,
51-
licensed_resource_type_details=VipDetails.model_config["json_schema_extra"][
52-
"examples"
53-
][0],
51+
licensed_resource_type_details=VIP_DETAILS_EXAMPLE,
5452
)
5553
_licensed_item_id = licensed_item_db.licensed_item_id
5654

@@ -69,7 +67,7 @@ async def test_licensed_items_db_crud(
6967
product_name=osparc_product_name,
7068
)
7169
assert licensed_item_db.display_name == "Model A"
72-
assert isinstance(licensed_item_db.licensed_resource_type_details, VipDetails)
70+
assert isinstance(licensed_item_db.licensed_resource_type_details, dict)
7371

7472
await _licensed_items_repository.update(
7573
client.app,

services/web/server/tests/unit/with_dbs/04/licenses/test_licensed_items_rest.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
)
1313
from models_library.api_schemas_webserver.licensed_items import LicensedItemRestGet
1414
from models_library.api_schemas_webserver.wallets import WalletGetWithAvailableCredits
15-
from models_library.licensed_items import LicensedResourceType, VipDetails
15+
from models_library.licensed_items import VIP_DETAILS_EXAMPLE, LicensedResourceType
1616
from pytest_mock.plugin import MockerFixture
1717
from pytest_simcore.helpers.assert_checks import assert_status
1818
from pytest_simcore.helpers.webserver_login import UserInfoDict
@@ -45,9 +45,7 @@ async def test_licensed_items_listing(
4545
display_name="Model A",
4646
licensed_resource_type=LicensedResourceType.VIP_MODEL,
4747
pricing_plan_id=pricing_plan_id,
48-
licensed_resource_type_details=VipDetails.model_config["json_schema_extra"][
49-
"examples"
50-
][0],
48+
licensed_resource_type_details=VIP_DETAILS_EXAMPLE,
5149
)
5250
_licensed_item_id = licensed_item_db.licensed_item_id
5351

@@ -115,9 +113,7 @@ async def test_licensed_items_purchase(
115113
display_name="Model A",
116114
licensed_resource_type=LicensedResourceType.VIP_MODEL,
117115
pricing_plan_id=pricing_plan_id,
118-
licensed_resource_type_details=VipDetails.model_config["json_schema_extra"][
119-
"examples"
120-
][0],
116+
licensed_resource_type_details=VIP_DETAILS_EXAMPLE,
121117
)
122118
_licensed_item_id = licensed_item_db.licensed_item_id
123119

0 commit comments

Comments
 (0)