Skip to content

Commit 4976951

Browse files
committed
helpers
1 parent 3d8c06c commit 4976951

File tree

2 files changed

+106
-92
lines changed

2 files changed

+106
-92
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
from pathlib import Path
2+
3+
import aiofiles
4+
from aiohttp import web
5+
from models_library.products import ProductName
6+
from simcore_postgres_database.utils_products_prices import ProductPriceInfo
7+
8+
from .._constants import RQ_PRODUCT_KEY
9+
from .._resources import webserver_resources
10+
from . import _service
11+
from ._web_events import APP_PRODUCTS_TEMPLATES_DIR_KEY
12+
from .products_models import Product
13+
14+
15+
def get_product_name(request: web.Request) -> str:
16+
"""Returns product name in request but might be undefined"""
17+
product_name: str = request[RQ_PRODUCT_KEY]
18+
return product_name
19+
20+
21+
def get_current_product(request: web.Request) -> Product:
22+
"""Returns product associated to current request"""
23+
product_name: ProductName = get_product_name(request)
24+
current_product: Product = _service.get_product(
25+
request.app, product_name=product_name
26+
)
27+
return current_product
28+
29+
30+
async def get_current_product_credit_price_info(
31+
request: web.Request,
32+
) -> ProductPriceInfo | None:
33+
"""Gets latest credit price for this product.
34+
35+
NOTE: Contrary to other product api functions (e.g. get_current_product) this function
36+
gets the latest update from the database. Otherwise, products are loaded
37+
on startup and cached therefore in those cases would require a restart
38+
of the service for the latest changes to take effect.
39+
"""
40+
current_product_name = get_product_name(request)
41+
return await _service.get_credit_price_info(
42+
request.app, product_name=current_product_name
43+
)
44+
45+
46+
def _themed(dirname: str, template: str) -> Path:
47+
path: Path = webserver_resources.get_path(f"{Path(dirname) / template}")
48+
return path
49+
50+
51+
def _safe_get_current_product(request: web.Request) -> Product | None:
52+
try:
53+
product: Product = get_current_product(request)
54+
return product
55+
except KeyError:
56+
return None
57+
58+
59+
async def get_product_template_path(request: web.Request, filename: str) -> Path:
60+
if product := _safe_get_current_product(request):
61+
if template_name := product.get_template_name_for(filename):
62+
template_dir: Path = request.app[APP_PRODUCTS_TEMPLATES_DIR_KEY]
63+
template_path = template_dir / template_name
64+
if not template_path.exists():
65+
# cache
66+
content = await _service.get_template_content(
67+
request.app, template_name=template_name
68+
)
69+
try:
70+
async with aiofiles.open(template_path, "w") as fh:
71+
await fh.write(content)
72+
except Exception:
73+
# fails to write
74+
if template_path.exists():
75+
template_path.unlink()
76+
raise
77+
78+
return template_path
79+
80+
# check static resources under templates/
81+
if (
82+
template_path := _themed(f"templates/{product.name}", filename)
83+
) and template_path.exists():
84+
return template_path
85+
86+
# If no product or template for product defined, we fall back to common templates
87+
common_template = _themed("templates/common", filename)
88+
if not common_template.exists():
89+
msg = f"{filename} is not part of the templates/common"
90+
raise ValueError(msg)
91+
92+
return common_template
Lines changed: 14 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,14 @@
1-
from pathlib import Path
2-
3-
import aiofiles
4-
from aiohttp import web
5-
from models_library.products import ProductName
6-
from simcore_postgres_database.utils_products_prices import ProductPriceInfo
7-
8-
from .._constants import RQ_PRODUCT_KEY
9-
from .._resources import webserver_resources
10-
from . import _service
11-
from ._web_events import APP_PRODUCTS_TEMPLATES_DIR_KEY
12-
from .products_models import Product
13-
14-
15-
def get_product_name(request: web.Request) -> str:
16-
"""Returns product name in request but might be undefined"""
17-
product_name: str = request[RQ_PRODUCT_KEY]
18-
return product_name
19-
20-
21-
def get_current_product(request: web.Request) -> Product:
22-
"""Returns product associated to current request"""
23-
product_name: ProductName = get_product_name(request)
24-
current_product: Product = _service.get_product(
25-
request.app, product_name=product_name
26-
)
27-
return current_product
28-
29-
30-
async def get_current_product_credit_price_info(
31-
request: web.Request,
32-
) -> ProductPriceInfo | None:
33-
"""Gets latest credit price for this product.
34-
35-
NOTE: Contrary to other product api functions (e.g. get_current_product) this function
36-
gets the latest update from the database. Otherwise, products are loaded
37-
on startup and cached therefore in those cases would require a restart
38-
of the service for the latest changes to take effect.
39-
"""
40-
current_product_name = get_product_name(request)
41-
return await _service.get_credit_price_info(
42-
request.app, product_name=current_product_name
43-
)
44-
45-
46-
def _themed(dirname: str, template: str) -> Path:
47-
path: Path = webserver_resources.get_path(f"{Path(dirname) / template}")
48-
return path
49-
50-
51-
def _safe_get_current_product(request: web.Request) -> Product | None:
52-
try:
53-
product: Product = get_current_product(request)
54-
return product
55-
except KeyError:
56-
return None
57-
58-
59-
async def get_product_template_path(request: web.Request, filename: str) -> Path:
60-
if product := _safe_get_current_product(request):
61-
if template_name := product.get_template_name_for(filename):
62-
template_dir: Path = request.app[APP_PRODUCTS_TEMPLATES_DIR_KEY]
63-
template_path = template_dir / template_name
64-
if not template_path.exists():
65-
# cache
66-
content = await _service.get_template_content(
67-
request.app, template_name=template_name
68-
)
69-
try:
70-
async with aiofiles.open(template_path, "w") as fh:
71-
await fh.write(content)
72-
except Exception:
73-
# fails to write
74-
if template_path.exists():
75-
template_path.unlink()
76-
raise
77-
78-
return template_path
79-
80-
# check static resources under templates/
81-
if (
82-
template_path := _themed(f"templates/{product.name}", filename)
83-
) and template_path.exists():
84-
return template_path
85-
86-
# If no product or template for product defined, we fall back to common templates
87-
common_template = _themed("templates/common", filename)
88-
if not common_template.exists():
89-
msg = f"{filename} is not part of the templates/common"
90-
raise ValueError(msg)
91-
92-
return common_template
1+
from ._web_helpers import (
2+
get_current_product,
3+
get_current_product_credit_price_info,
4+
get_product_name,
5+
get_product_template_path,
6+
)
7+
8+
__all__: tuple[str, ...] = (
9+
"get_product_name",
10+
"get_current_product",
11+
"get_current_product_credit_price_info",
12+
"get_product_template_path",
13+
)
14+
# nopycln: file

0 commit comments

Comments
 (0)