Skip to content

Commit 9984911

Browse files
Merge branch 'master' into fix-pydantic-userwarnings
2 parents d92bb7d + 795fdfb commit 9984911

File tree

57 files changed

+932
-440
lines changed

Some content is hidden

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

57 files changed

+932
-440
lines changed

api/specs/web-server/_resource_usage.py

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
CreatePricingPlanBodyParams,
2222
CreatePricingUnitBodyParams,
2323
PricingPlanAdminGet,
24+
PricingPlanGet,
2425
PricingPlanToServiceAdminGet,
2526
PricingUnitAdminGet,
2627
PricingUnitGet,
@@ -29,15 +30,16 @@
2930
UpdatePricingUnitBodyParams,
3031
)
3132
from models_library.generics import Envelope
33+
from models_library.rest_pagination import Page, PageQueryParameters
3234
from simcore_service_webserver._meta import API_VTAG
33-
from simcore_service_webserver.resource_usage._pricing_plans_admin_handlers import (
35+
from simcore_service_webserver.resource_usage._pricing_plans_admin_rest import (
3436
PricingPlanGetPathParams,
3537
PricingUnitGetPathParams,
3638
)
37-
from simcore_service_webserver.resource_usage._pricing_plans_handlers import (
39+
from simcore_service_webserver.resource_usage._pricing_plans_rest import (
3840
PricingPlanUnitGetPathParams,
3941
)
40-
from simcore_service_webserver.resource_usage._service_runs_handlers import (
42+
from simcore_service_webserver.resource_usage._service_runs_rest import (
4143
ServicesAggregatedUsagesListQueryParams,
4244
ServicesResourceUsagesListQueryParams,
4345
ServicesResourceUsagesReportQueryParams,
@@ -48,7 +50,7 @@
4850

4951
@router.get(
5052
"/services/-/resource-usages",
51-
response_model=Envelope[list[ServiceRunGet]],
53+
response_model=Page[ServiceRunGet],
5254
summary="Retrieve finished and currently running user services"
5355
" (user and product are taken from context, optionally wallet_id parameter might be provided).",
5456
tags=["usage"],
@@ -61,7 +63,7 @@ async def list_resource_usage_services(
6163

6264
@router.get(
6365
"/services/-/aggregated-usages",
64-
response_model=Envelope[list[OsparcCreditsAggregatedByServiceGet]],
66+
response_model=Page[OsparcCreditsAggregatedByServiceGet],
6567
summary="Used credits based on aggregate by type, currently supported `services`"
6668
". (user and product are taken from context, optionally wallet_id parameter might be provided).",
6769
tags=["usage"],
@@ -93,7 +95,6 @@ async def export_resource_usage_services(
9395
@router.get(
9496
"/pricing-plans/{pricing_plan_id}/pricing-units/{pricing_unit_id}",
9597
response_model=Envelope[PricingUnitGet],
96-
summary="Retrieve detail information about pricing unit",
9798
tags=["pricing-plans"],
9899
)
99100
async def get_pricing_plan_unit(
@@ -102,27 +103,50 @@ async def get_pricing_plan_unit(
102103
...
103104

104105

106+
@router.get(
107+
"/pricing-plans",
108+
response_model=Page[PricingPlanGet],
109+
tags=["pricing-plans"],
110+
description="To keep the listing lightweight, the pricingUnits field is None.",
111+
)
112+
async def list_pricing_plans(
113+
_query: Annotated[as_query(PageQueryParameters), Depends()]
114+
):
115+
...
116+
117+
118+
@router.get(
119+
"/pricing-plans/{pricing_plan_id}",
120+
response_model=Envelope[PricingPlanGet],
121+
tags=["pricing-plans"],
122+
)
123+
async def get_pricing_plan(
124+
_path: Annotated[PricingPlanGetPathParams, Depends()],
125+
):
126+
...
127+
128+
105129
## Pricing plans for Admin panel
106130

107131

108132
@router.get(
109133
"/admin/pricing-plans",
110-
response_model=Envelope[list[PricingPlanAdminGet]],
111-
summary="List pricing plans",
134+
response_model=Page[PricingPlanAdminGet],
112135
tags=["admin"],
113136
description="To keep the listing lightweight, the pricingUnits field is None.",
114137
)
115-
async def list_pricing_plans():
138+
async def list_pricing_plans_for_admin_user(
139+
_query: Annotated[as_query(PageQueryParameters), Depends()]
140+
):
116141
...
117142

118143

119144
@router.get(
120145
"/admin/pricing-plans/{pricing_plan_id}",
121146
response_model=Envelope[PricingPlanAdminGet],
122-
summary="Retrieve detail information about pricing plan",
123147
tags=["admin"],
124148
)
125-
async def get_pricing_plan(
149+
async def get_pricing_plan_for_admin_user(
126150
_path: Annotated[PricingPlanGetPathParams, Depends()],
127151
):
128152
...
@@ -131,7 +155,6 @@ async def get_pricing_plan(
131155
@router.post(
132156
"/admin/pricing-plans",
133157
response_model=Envelope[PricingPlanAdminGet],
134-
summary="Create pricing plan",
135158
tags=["admin"],
136159
)
137160
async def create_pricing_plan(
@@ -143,7 +166,6 @@ async def create_pricing_plan(
143166
@router.put(
144167
"/admin/pricing-plans/{pricing_plan_id}",
145168
response_model=Envelope[PricingPlanAdminGet],
146-
summary="Update detail information about pricing plan",
147169
tags=["admin"],
148170
)
149171
async def update_pricing_plan(
@@ -159,7 +181,6 @@ async def update_pricing_plan(
159181
@router.get(
160182
"/admin/pricing-plans/{pricing_plan_id}/pricing-units/{pricing_unit_id}",
161183
response_model=Envelope[PricingUnitAdminGet],
162-
summary="Retrieve detail information about pricing unit",
163184
tags=["admin"],
164185
)
165186
async def get_pricing_unit(
@@ -171,7 +192,6 @@ async def get_pricing_unit(
171192
@router.post(
172193
"/admin/pricing-plans/{pricing_plan_id}/pricing-units",
173194
response_model=Envelope[PricingUnitAdminGet],
174-
summary="Create pricing unit",
175195
tags=["admin"],
176196
)
177197
async def create_pricing_unit(
@@ -184,7 +204,6 @@ async def create_pricing_unit(
184204
@router.put(
185205
"/admin/pricing-plans/{pricing_plan_id}/pricing-units/{pricing_unit_id}",
186206
response_model=Envelope[PricingUnitAdminGet],
187-
summary="Update detail information about pricing plan",
188207
tags=["admin"],
189208
)
190209
async def update_pricing_unit(
@@ -200,7 +219,6 @@ async def update_pricing_unit(
200219
@router.get(
201220
"/admin/pricing-plans/{pricing_plan_id}/billable-services",
202221
response_model=Envelope[list[PricingPlanToServiceAdminGet]],
203-
summary="List services that are connected to the provided pricing plan",
204222
tags=["admin"],
205223
)
206224
async def list_connected_services_to_pricing_plan(
@@ -212,7 +230,6 @@ async def list_connected_services_to_pricing_plan(
212230
@router.post(
213231
"/admin/pricing-plans/{pricing_plan_id}/billable-services",
214232
response_model=Envelope[PricingPlanToServiceAdminGet],
215-
summary="Connect service with pricing plan",
216233
tags=["admin"],
217234
)
218235
async def connect_service_to_pricing_plan(

packages/models-library/src/models_library/api_schemas_resource_usage_tracker/licensed_items_checkouts.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class LicensedItemCheckoutGet(BaseModel):
1717
licensed_item_id: LicensedItemID
1818
wallet_id: WalletID
1919
user_id: UserID
20+
user_email: str
2021
product_name: ProductName
2122
service_run_id: ServiceRunID
2223
started_at: datetime
@@ -31,6 +32,7 @@ class LicensedItemCheckoutGet(BaseModel):
3132
"licensed_item_id": "303942ef-6d31-4ba8-afbe-dbb1fce2a953",
3233
"wallet_id": 1,
3334
"user_id": 1,
35+
"user_email": "[email protected]",
3436
"product_name": "osparc",
3537
"service_run_id": "run_1",
3638
"started_at": "2023-01-11 13:11:47.293595",

packages/models-library/src/models_library/api_schemas_resource_usage_tracker/licensed_items_purchases.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class LicensedItemPurchaseGet(BaseModel):
2525
expire_at: datetime
2626
num_of_seats: int
2727
purchased_by_user: UserID
28+
user_email: str
2829
purchased_at: datetime
2930
modified: datetime
3031

@@ -43,6 +44,7 @@ class LicensedItemPurchaseGet(BaseModel):
4344
"expire_at": "2023-01-11 13:11:47.293595",
4445
"num_of_seats": 1,
4546
"purchased_by_user": 1,
47+
"user_email": "[email protected]",
4648
"purchased_at": "2023-01-11 13:11:47.293595",
4749
"modified": "2023-01-11 13:11:47.293595",
4850
}

packages/models-library/src/models_library/api_schemas_resource_usage_tracker/pricing_plans.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from datetime import datetime
22
from decimal import Decimal
3+
from typing import NamedTuple
34

4-
from pydantic import BaseModel, ConfigDict
5+
from pydantic import BaseModel, ConfigDict, PositiveInt
56

67
from ..resource_tracker import (
78
HardwareInfo,
@@ -76,6 +77,11 @@ class PricingPlanGet(BaseModel):
7677
)
7778

7879

80+
class PricingPlanPage(NamedTuple):
81+
items: list[PricingPlanGet]
82+
total: PositiveInt
83+
84+
7985
class PricingPlanToServiceGet(BaseModel):
8086
pricing_plan_id: PricingPlanId
8187
service_key: ServiceKey

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from datetime import datetime
22
from typing import NamedTuple
33

4+
from models_library.emails import LowerCaseEmailStr
45
from pydantic import BaseModel, ConfigDict, PositiveInt
56

67
from ..licensed_items import LicensedItemID
@@ -53,6 +54,7 @@ class LicensedItemCheckoutRestGet(OutputSchema):
5354
licensed_item_id: LicensedItemID
5455
wallet_id: WalletID
5556
user_id: UserID
57+
user_email: LowerCaseEmailStr
5658
product_name: ProductName
5759
started_at: datetime
5860
stopped_at: datetime | None

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from decimal import Decimal
33
from typing import NamedTuple
44

5+
from models_library.emails import LowerCaseEmailStr
56
from pydantic import PositiveInt
67

78
from ..licensed_items import LicensedItemID
@@ -24,6 +25,7 @@ class LicensedItemPurchaseGet(OutputSchema):
2425
expire_at: datetime
2526
num_of_seats: int
2627
purchased_by_user: UserID
28+
user_email: LowerCaseEmailStr
2729
purchased_at: datetime
2830
modified_at: datetime
2931

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class PricingPlanGet(OutputSchema):
6060
classification: PricingPlanClassification
6161
created_at: datetime
6262
pricing_plan_key: str
63-
pricing_units: list[PricingUnitGet]
63+
pricing_units: list[PricingUnitGet] | None
6464
is_active: bool
6565

6666

@@ -78,7 +78,7 @@ class PricingPlanAdminGet(OutputSchema):
7878
classification: PricingPlanClassification
7979
created_at: datetime
8080
pricing_plan_key: str
81-
pricing_units: list[PricingUnitGet] | None
81+
pricing_units: list[PricingUnitAdminGet] | None
8282
is_active: bool
8383

8484

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""add user email col to purchases
2+
3+
Revision ID: 5f88b513cd4c
4+
Revises: ecd4eadaa781
5+
Create Date: 2025-01-22 15:08:17.729337+00:00
6+
7+
"""
8+
import sqlalchemy as sa
9+
from alembic import op
10+
11+
# revision identifiers, used by Alembic.
12+
revision = "5f88b513cd4c"
13+
down_revision = "ecd4eadaa781"
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(
21+
"resource_tracker_licensed_items_purchases",
22+
sa.Column("user_email", sa.String(), nullable=True),
23+
)
24+
# ### end Alembic commands ###
25+
26+
27+
def downgrade():
28+
# ### commands auto generated by Alembic - please adjust! ###
29+
op.drop_column("resource_tracker_licensed_items_purchases", "user_email")
30+
# ### end Alembic commands ###

packages/postgres-database/src/simcore_postgres_database/models/resource_tracker_licensed_items_purchases.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@
7272
sa.BigInteger,
7373
nullable=False,
7474
),
75+
sa.Column(
76+
"user_email",
77+
sa.String,
78+
nullable=True,
79+
),
7580
sa.Column(
7681
"purchased_at",
7782
sa.DateTime(timezone=True),

packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/resource_usage_tracker/pricing_plans.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
)
77
from models_library.api_schemas_resource_usage_tracker.pricing_plans import (
88
PricingPlanGet,
9+
PricingPlanPage,
910
PricingPlanToServiceGet,
1011
)
1112
from models_library.products import ProductName
@@ -52,14 +53,21 @@ async def list_pricing_plans(
5253
rabbitmq_rpc_client: RabbitMQRPCClient,
5354
*,
5455
product_name: ProductName,
55-
) -> list[PricingPlanGet]:
56-
result: PricingPlanGet = await rabbitmq_rpc_client.request(
56+
exclude_inactive: bool = True,
57+
# pagination
58+
offset: int = 0,
59+
limit: int = 20,
60+
) -> PricingPlanPage:
61+
result = await rabbitmq_rpc_client.request(
5762
RESOURCE_USAGE_TRACKER_RPC_NAMESPACE,
5863
_RPC_METHOD_NAME_ADAPTER.validate_python("list_pricing_plans"),
5964
product_name=product_name,
65+
exclude_inactive=exclude_inactive,
66+
offset=offset,
67+
limit=limit,
6068
timeout_s=_DEFAULT_TIMEOUT_S,
6169
)
62-
assert isinstance(result, list) # nosec
70+
assert isinstance(result, PricingPlanPage) # nosec
6371
return result
6472

6573

0 commit comments

Comments
 (0)