Skip to content

Commit e05d046

Browse files
✨ Introduce vip models pricing 1 of 2 parts (#6897)
1 parent cba896a commit e05d046

File tree

31 files changed

+1424
-32
lines changed

31 files changed

+1424
-32
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
""" Helper script to generate OAS automatically
2+
"""
3+
4+
# pylint: disable=redefined-outer-name
5+
# pylint: disable=unused-argument
6+
# pylint: disable=unused-variable
7+
# pylint: disable=too-many-arguments
8+
9+
from typing import Annotated
10+
11+
from _common import as_query
12+
from fastapi import APIRouter, Depends, status
13+
from models_library.api_schemas_webserver.licensed_items import LicensedItemGet
14+
from models_library.generics import Envelope
15+
from models_library.rest_error import EnvelopedError
16+
from simcore_service_webserver._meta import API_VTAG
17+
from simcore_service_webserver.catalog.licenses._exceptions_handlers import (
18+
_TO_HTTP_ERROR_MAP,
19+
)
20+
from simcore_service_webserver.catalog.licenses._models import (
21+
LicensedItemsBodyParams,
22+
LicensedItemsListQueryParams,
23+
LicensedItemsPathParams,
24+
)
25+
26+
router = APIRouter(
27+
prefix=f"/{API_VTAG}",
28+
tags=[
29+
"licenses",
30+
"catalog",
31+
],
32+
responses={
33+
i.status_code: {"model": EnvelopedError} for i in _TO_HTTP_ERROR_MAP.values()
34+
},
35+
)
36+
37+
38+
@router.get(
39+
"/catalog/licensed-items",
40+
response_model=Envelope[list[LicensedItemGet]],
41+
)
42+
async def list_licensed_items(
43+
_query: Annotated[as_query(LicensedItemsListQueryParams), Depends()],
44+
):
45+
...
46+
47+
48+
@router.get(
49+
"/catalog/licensed-items/{licensed_item_id}",
50+
response_model=Envelope[LicensedItemGet],
51+
)
52+
async def get_licensed_item(
53+
_path: Annotated[LicensedItemsPathParams, Depends()],
54+
):
55+
...
56+
57+
58+
@router.post(
59+
"/catalog/licensed-items/{licensed_item_id}:purchase",
60+
status_code=status.HTTP_204_NO_CONTENT,
61+
)
62+
async def purchase_licensed_item(
63+
_path: Annotated[LicensedItemsPathParams, Depends()],
64+
_body: LicensedItemsBodyParams,
65+
):
66+
...

api/specs/web-server/openapi.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"_announcements",
3232
"_catalog",
3333
"_catalog_tags", # MUST BE after _catalog
34+
"_catalog_licensed_items",
3435
"_computations",
3536
"_exporter",
3637
"_folders",
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from datetime import datetime
2+
from typing import NamedTuple
3+
4+
from models_library.licensed_items import LicensedItemID, LicensedResourceType
5+
from models_library.resource_tracker import PricingPlanId
6+
from pydantic import PositiveInt
7+
8+
from ._base import OutputSchema
9+
10+
11+
class LicensedItemGet(OutputSchema):
12+
licensed_item_id: LicensedItemID
13+
name: str
14+
licensed_resource_type: LicensedResourceType
15+
pricing_plan_id: PricingPlanId
16+
created_at: datetime
17+
modified_at: datetime
18+
19+
20+
class LicensedItemGetPage(NamedTuple):
21+
items: list[LicensedItemGet]
22+
total: PositiveInt
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from datetime import datetime
2+
from enum import auto
3+
from typing import TypeAlias
4+
from uuid import UUID
5+
6+
from pydantic import BaseModel, ConfigDict, Field
7+
8+
from .products import ProductName
9+
from .resource_tracker import PricingPlanId
10+
from .utils.enums import StrAutoEnum
11+
12+
LicensedItemID: TypeAlias = UUID
13+
14+
15+
class LicensedResourceType(StrAutoEnum):
16+
VIP_MODEL = auto()
17+
18+
19+
#
20+
# DB
21+
#
22+
23+
24+
class LicensedItemDB(BaseModel):
25+
licensed_item_id: LicensedItemID
26+
name: str
27+
licensed_resource_type: LicensedResourceType
28+
pricing_plan_id: PricingPlanId
29+
product_name: ProductName
30+
created: datetime = Field(
31+
...,
32+
description="Timestamp on creation",
33+
)
34+
modified: datetime = Field(
35+
...,
36+
description="Timestamp of last modification",
37+
)
38+
# ----
39+
model_config = ConfigDict(from_attributes=True)
40+
41+
42+
class LicensedItemUpdateDB(BaseModel):
43+
name: str | None = None
44+
pricing_plan_id: PricingPlanId | None = None

packages/postgres-database/requirements/_base.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
--requirement ../../../packages/common-library/requirements/_base.in
77

88
alembic
9+
opentelemetry-instrumentation-asyncpg
910
pydantic
1011
sqlalchemy[postgresql_psycopg2binary,postgresql_asyncpg] # SEE extras in https://github.com/sqlalchemy/sqlalchemy/blob/main/setup.cfg#L43
11-
opentelemetry-instrumentation-asyncpg
1212
yarl

packages/postgres-database/requirements/_base.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pydantic-core==2.27.1
5454
# via pydantic
5555
pydantic-extra-types==2.10.0
5656
# via -r requirements/../../../packages/common-library/requirements/_base.in
57-
setuptools==75.2.0
57+
setuptools==75.6.0
5858
# via opentelemetry-instrumentation
5959
sqlalchemy==1.4.54
6060
# via

packages/postgres-database/requirements/_migration.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ certifi==2024.8.30
66
# via
77
# -c requirements/../../../requirements/constraints.txt
88
# requests
9-
charset-normalizer==3.3.2
9+
charset-normalizer==3.4.0
1010
# via requests
1111
click==8.1.7
1212
# via -r requirements/_migration.in

packages/postgres-database/requirements/_test.txt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ async-timeout==4.0.3
66
# aiopg
77
attrs==24.2.0
88
# via pytest-docker
9-
coverage==7.6.1
9+
coverage==7.6.8
1010
# via
1111
# -r requirements/_test.in
1212
# pytest-cov
13-
faker==29.0.0
13+
faker==33.1.0
1414
# via -r requirements/_test.in
1515
greenlet==3.1.1
1616
# via
@@ -19,11 +19,11 @@ greenlet==3.1.1
1919
# sqlalchemy
2020
iniconfig==2.0.0
2121
# via pytest
22-
mypy==1.12.0
22+
mypy==1.13.0
2323
# via sqlalchemy
2424
mypy-extensions==1.0.0
2525
# via mypy
26-
packaging==24.1
26+
packaging==24.2
2727
# via pytest
2828
pluggy==1.5.0
2929
# via pytest
@@ -32,7 +32,7 @@ psycopg2-binary==2.9.9
3232
# -c requirements/_base.txt
3333
# aiopg
3434
# sqlalchemy
35-
pytest==8.3.3
35+
pytest==8.3.4
3636
# via
3737
# -r requirements/_test.in
3838
# pytest-asyncio
@@ -43,7 +43,7 @@ pytest-asyncio==0.23.8
4343
# via
4444
# -c requirements/../../../requirements/constraints.txt
4545
# -r requirements/_test.in
46-
pytest-cov==5.0.0
46+
pytest-cov==6.0.0
4747
# via -r requirements/_test.in
4848
pytest-docker==3.1.1
4949
# via -r requirements/_test.in
@@ -70,14 +70,15 @@ sqlalchemy2-stubs==0.0.2a38
7070
# via sqlalchemy
7171
types-docker==7.1.0.20240827
7272
# via -r requirements/_test.in
73-
types-psycopg2==2.9.21.20240819
73+
types-psycopg2==2.9.21.20241019
7474
# via -r requirements/_test.in
75-
types-requests==2.32.0.20240914
75+
types-requests==2.32.0.20241016
7676
# via types-docker
7777
typing-extensions==4.12.2
7878
# via
7979
# -c requirements/_base.txt
8080
# -c requirements/_migration.txt
81+
# faker
8182
# mypy
8283
# sqlalchemy2-stubs
8384
urllib3==2.2.3
Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
astroid==3.3.4
1+
astroid==3.3.5
22
# via pylint
3-
black==24.8.0
3+
black==24.10.0
44
# via -r requirements/../../../requirements/devenv.txt
5-
build==1.2.2
5+
build==1.2.2.post1
66
# via pip-tools
77
bump2version==1.0.1
88
# via -r requirements/../../../requirements/devenv.txt
@@ -12,21 +12,21 @@ click==8.1.7
1212
# via
1313
# black
1414
# pip-tools
15-
dill==0.3.8
15+
dill==0.3.9
1616
# via pylint
17-
distlib==0.3.8
17+
distlib==0.3.9
1818
# via virtualenv
1919
filelock==3.16.1
2020
# via virtualenv
21-
identify==2.6.1
21+
identify==2.6.3
2222
# via pre-commit
2323
isort==5.13.2
2424
# via
2525
# -r requirements/../../../requirements/devenv.txt
2626
# pylint
2727
mccabe==0.7.0
2828
# via pylint
29-
mypy==1.12.0
29+
mypy==1.13.0
3030
# via
3131
# -c requirements/_test.txt
3232
# -r requirements/../../../requirements/devenv.txt
@@ -37,14 +37,14 @@ mypy-extensions==1.0.0
3737
# mypy
3838
nodeenv==1.9.1
3939
# via pre-commit
40-
packaging==24.1
40+
packaging==24.2
4141
# via
4242
# -c requirements/_test.txt
4343
# black
4444
# build
4545
pathspec==0.12.1
4646
# via black
47-
pip==24.2
47+
pip==24.3.1
4848
# via pip-tools
4949
pip-tools==7.4.1
5050
# via -r requirements/../../../requirements/devenv.txt
@@ -53,11 +53,11 @@ platformdirs==4.3.6
5353
# black
5454
# pylint
5555
# virtualenv
56-
pre-commit==3.8.0
56+
pre-commit==4.0.1
5757
# via -r requirements/../../../requirements/devenv.txt
58-
pylint==3.3.0
58+
pylint==3.3.2
5959
# via -r requirements/../../../requirements/devenv.txt
60-
pyproject-hooks==1.1.0
60+
pyproject-hooks==1.2.0
6161
# via
6262
# build
6363
# pip-tools
@@ -66,9 +66,9 @@ pyyaml==6.0.2
6666
# -c requirements/../../../requirements/constraints.txt
6767
# -c requirements/_test.txt
6868
# pre-commit
69-
ruff==0.6.7
69+
ruff==0.8.1
7070
# via -r requirements/../../../requirements/devenv.txt
71-
setuptools==75.2.0
71+
setuptools==75.6.0
7272
# via
7373
# -c requirements/_base.txt
7474
# pip-tools
@@ -79,7 +79,7 @@ typing-extensions==4.12.2
7979
# -c requirements/_base.txt
8080
# -c requirements/_test.txt
8181
# mypy
82-
virtualenv==20.26.5
82+
virtualenv==20.28.0
8383
# via pre-commit
84-
wheel==0.44.0
84+
wheel==0.45.1
8585
# via pip-tools

0 commit comments

Comments
 (0)