Skip to content

Commit 41e11f9

Browse files
Merge branch 'master' into fix-unsubscribe-from-logs
2 parents 590cc1c + 15df617 commit 41e11f9

File tree

22 files changed

+621
-315
lines changed

22 files changed

+621
-315
lines changed

packages/pytest-simcore/src/pytest_simcore/helpers/faker_factories.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,3 +629,65 @@ def random_service_consume_filetype(
629629

630630
data.update(overrides)
631631
return data
632+
633+
634+
def random_group_classifier(
635+
*,
636+
gid: int,
637+
fake: Faker = DEFAULT_FAKER,
638+
**overrides,
639+
) -> dict[str, Any]:
640+
from simcore_postgres_database.models.classifiers import group_classifiers
641+
642+
data = {
643+
"gid": gid,
644+
"bundle": {
645+
"vcs_ref": fake.lexify(text="???????"),
646+
"vcs_url": "https://organization.classifiers.git",
647+
"build_date": "2021-01-20T15:19:30Z",
648+
"classifiers": {
649+
"project::dak": {
650+
"url": None,
651+
"logo": None,
652+
"aliases": [],
653+
"related": [],
654+
"markdown": "",
655+
"released": None,
656+
"classifier": "project::dak",
657+
"created_by": fake.user_name(),
658+
"github_url": None,
659+
"display_name": "DAK",
660+
"wikipedia_url": None,
661+
"short_description": None,
662+
},
663+
"organization::zmt": {
664+
"url": "https://zmt.swiss/",
665+
"logo": None,
666+
"aliases": ["Zurich MedTech AG"],
667+
"related": [],
668+
"markdown": fake.text(),
669+
"released": None,
670+
"classifier": "organization::zmt",
671+
"created_by": fake.user_name(),
672+
"github_url": None,
673+
"display_name": "ZMT",
674+
"wikipedia_url": None,
675+
"short_description": "ZMT is a member of Zurich43",
676+
},
677+
},
678+
"collections": {
679+
"jupyterlab-math": {
680+
"items": ["crespo/osparc-demo"],
681+
"markdown": fake.text(),
682+
"created_by": fake.user_name(),
683+
"display_name": "jupyterlab-math",
684+
}
685+
},
686+
},
687+
"uses_scicrunch": False,
688+
}
689+
690+
assert set(data.keys()).issubset({c.name for c in group_classifiers.columns})
691+
692+
data.update(overrides)
693+
return data

packages/pytest-simcore/src/pytest_simcore/helpers/scrunch_citations.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Citations according to https://scicrunch.org/resources
22
"""
3-
NOTES:
3+
NOTES:
44
5-
- scicrunch API ONLY recognizes RRIDs from SciCrunch registry of tools (i.e. with prefix "SCR")
6-
- scicrunch web search handles ALL RRIDs (see below example of citations from other)
7-
- scicrunch API does NOT uses 'RRID:' prefix in rrid request parameters
5+
- scicrunch API ONLY recognizes RRIDs from SciCrunch registry of tools (i.e. with prefix "SCR")
6+
- scicrunch web search handles ALL RRIDs (see below example of citations from other)
7+
- scicrunch API does NOT uses 'RRID:' prefix in rrid request parameters
88
99
"""
1010

@@ -13,8 +13,12 @@
1313

1414
def split_citations(citations: list[str]) -> list[tuple[str, str]]:
1515
def _split(citation: str) -> tuple[str, str]:
16+
assert citation.startswith("("), f"Got {citation=}"
17+
assert citation.endswith(")"), f"Got {citation=}"
18+
# make sure there is a comma before RRID: so we can split
1619
if "," not in citation:
1720
citation = citation.replace("(", "(,")
21+
1822
name, rrid = re.match(r"^\((.*),\s*RRID:(.+)\)$", citation).groups()
1923
return name, rrid
2024

services/web/server/src/simcore_service_webserver/exporter/_formatter/_sds.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from ...projects._projects_service import get_project_for_user
1212
from ...projects.exceptions import BaseProjectError
1313
from ...projects.models import ProjectDict
14-
from ...scicrunch.db import ResearchResourceRepository
14+
from ...scicrunch.scicrunch_service import SCICRUNCH_SERVICE_APPKEY
1515
from ..exceptions import SDSException
1616
from .template_json import write_template_json
1717
from .xlsx.code_description import (
@@ -70,10 +70,10 @@ async def _add_rrid_entries(
7070
) -> None:
7171
rrid_entires: deque[RRIDEntry] = deque()
7272

73-
repo = ResearchResourceRepository(app)
73+
service = app[SCICRUNCH_SERVICE_APPKEY]
7474
classifiers = project_data["classifiers"]
7575
for classifier in classifiers:
76-
scicrunch_resource = await repo.get(rrid=classifier)
76+
scicrunch_resource = await service.get_resource_atdb(rrid=classifier)
7777
if scicrunch_resource is None:
7878
continue
7979

services/web/server/src/simcore_service_webserver/exporter/plugin.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22

33
from aiohttp import web
4+
from simcore_service_webserver.scicrunch.plugin import setup_scicrunch
45

56
from ..application_setup import ModuleCategory, app_setup_func
67
from . import _handlers
@@ -15,6 +16,7 @@
1516
logger=_logger,
1617
)
1718
def setup_exporter(app: web.Application) -> bool:
19+
setup_scicrunch(app)
1820

1921
# Rest-API routes: maps handlers with routes tags with "viewer" based on OAS operation_id
2022
app.router.add_routes(_handlers.routes)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import logging
2+
from typing import Any, cast
3+
4+
import sqlalchemy as sa
5+
from simcore_postgres_database.models.classifiers import group_classifiers
6+
from simcore_postgres_database.utils_repos import pass_or_acquire_connection
7+
from sqlalchemy.engine import Row
8+
from sqlalchemy.ext.asyncio import AsyncConnection
9+
10+
from ..db.base_repository import BaseRepository
11+
12+
_logger = logging.getLogger(__name__)
13+
14+
15+
class GroupClassifierRepository(BaseRepository):
16+
17+
async def _get_bundle(
18+
self, gid: int, connection: AsyncConnection | None = None
19+
) -> Row | None:
20+
async with pass_or_acquire_connection(self.engine, connection) as conn:
21+
result = await conn.execute(
22+
sa.select(group_classifiers.c.bundle).where(
23+
group_classifiers.c.gid == gid
24+
)
25+
)
26+
return result.one_or_none()
27+
28+
async def get_classifiers_from_bundle(self, gid: int) -> dict[str, Any] | None:
29+
bundle_row = await self._get_bundle(gid)
30+
if bundle_row:
31+
return cast(dict[str, Any], bundle_row.bundle)
32+
return None
33+
34+
async def group_uses_scicrunch(
35+
self, gid: int, connection: AsyncConnection | None = None
36+
) -> bool:
37+
async with pass_or_acquire_connection(self.engine, connection) as conn:
38+
result = await conn.execute(
39+
sa.select(group_classifiers.c.uses_scicrunch).where(
40+
group_classifiers.c.gid == gid
41+
)
42+
)
43+
row = result.one_or_none()
44+
return bool(row.uses_scicrunch if row else False)

services/web/server/src/simcore_service_webserver/groups/_classifiers_rest.py

Lines changed: 18 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@
88

99
from .._meta import API_VTAG
1010
from ..login.decorators import login_required
11-
from ..scicrunch.db import ResearchResourceRepository
12-
from ..scicrunch.errors import ScicrunchError
13-
from ..scicrunch.models import ResearchResource, ResourceHit
14-
from ..scicrunch.service_client import SciCrunch
11+
from ..scicrunch.models import ResourceHit
12+
from ..scicrunch.scicrunch_service import SCICRUNCH_SERVICE_APPKEY
1513
from ..security.decorators import permission_required
1614
from ..utils_aiohttp import envelope_json_response
17-
from ._classifiers_service import GroupClassifierRepository, build_rrids_tree_view
15+
from ._classifiers_service import GroupClassifiersService
1816
from ._common.exceptions_handlers import handle_plugin_requests_exceptions
1917
from ._common.schemas import GroupsClassifiersQuery, GroupsPathParams
2018

@@ -29,23 +27,15 @@
2927
@permission_required("groups.*")
3028
@handle_plugin_requests_exceptions
3129
async def get_group_classifiers(request: web.Request):
32-
try:
33-
path_params = parse_request_path_parameters_as(GroupsPathParams, request)
34-
query_params: GroupsClassifiersQuery = parse_request_query_parameters_as(
35-
GroupsClassifiersQuery, request
36-
)
37-
38-
repo = GroupClassifierRepository(request.app)
39-
if not await repo.group_uses_scicrunch(path_params.gid):
40-
bundle = await repo.get_classifiers_from_bundle(path_params.gid)
41-
return envelope_json_response(bundle)
42-
43-
# otherwise, build dynamic tree with RRIDs
44-
view = await build_rrids_tree_view(
45-
request.app, tree_view_mode=query_params.tree_view
46-
)
47-
except ScicrunchError:
48-
view = {}
30+
path_params = parse_request_path_parameters_as(GroupsPathParams, request)
31+
query_params: GroupsClassifiersQuery = parse_request_query_parameters_as(
32+
GroupsClassifiersQuery, request
33+
)
34+
35+
service = GroupClassifiersService(request.app)
36+
view = await service.get_group_classifiers(
37+
path_params.gid, tree_view_mode=query_params.tree_view
38+
)
4939

5040
return envelope_json_response(view)
5141

@@ -59,15 +49,9 @@ async def get_group_classifiers(request: web.Request):
5949
@handle_plugin_requests_exceptions
6050
async def get_scicrunch_resource(request: web.Request):
6151
rrid = request.match_info["rrid"]
62-
rrid = SciCrunch.validate_identifier(rrid)
6352

64-
# check if in database first
65-
repo = ResearchResourceRepository(request.app)
66-
resource: ResearchResource | None = await repo.get_resource(rrid)
67-
if not resource:
68-
# otherwise, request to scicrunch service
69-
scicrunch = SciCrunch.get_instance(request.app)
70-
resource = await scicrunch.get_resource_fields(rrid)
53+
service = request.app[SCICRUNCH_SERVICE_APPKEY]
54+
resource = await service.get_or_fetch_research_resource(rrid)
7155

7256
return envelope_json_response(resource.model_dump())
7357

@@ -82,16 +66,8 @@ async def get_scicrunch_resource(request: web.Request):
8266
async def add_scicrunch_resource(request: web.Request):
8367
rrid = request.match_info["rrid"]
8468

85-
# check if exists
86-
repo = ResearchResourceRepository(request.app)
87-
resource: ResearchResource | None = await repo.get_resource(rrid)
88-
if not resource:
89-
# then request scicrunch service
90-
scicrunch = SciCrunch.get_instance(request.app)
91-
resource = await scicrunch.get_resource_fields(rrid)
92-
93-
# insert new or if exists, then update
94-
await repo.upsert(resource)
69+
service = request.app[SCICRUNCH_SERVICE_APPKEY]
70+
resource = await service.create_research_resource(rrid)
9571

9672
return envelope_json_response(resource.model_dump())
9773

@@ -106,7 +82,7 @@ async def add_scicrunch_resource(request: web.Request):
10682
async def search_scicrunch_resources(request: web.Request):
10783
guess_name = str(request.query["guess_name"]).strip()
10884

109-
scicrunch = SciCrunch.get_instance(request.app)
110-
hits: list[ResourceHit] = await scicrunch.search_resource(guess_name)
85+
service = request.app[SCICRUNCH_SERVICE_APPKEY]
86+
hits: list[ResourceHit] = await service.search_research_resources(guess_name)
11187

11288
return envelope_json_response([hit.model_dump() for hit in hits])

0 commit comments

Comments
 (0)