From ed821b2f900495a24c8716db1ef37c6855c38df0 Mon Sep 17 00:00:00 2001 From: fynnbe Date: Wed, 13 Nov 2024 22:52:43 +0100 Subject: [PATCH 1/3] add uploader to collection.json --- .../collection_json.py | 6 ++++++ .../remote_collection.py | 21 +++---------------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/bioimageio_collection_backoffice/collection_json.py b/bioimageio_collection_backoffice/collection_json.py index 366b513d..1b4aecf0 100644 --- a/bioimageio_collection_backoffice/collection_json.py +++ b/bioimageio_collection_backoffice/collection_json.py @@ -30,8 +30,14 @@ class TrainingData(Node, frozen=True): id: str +class Uploader(Node, frozen=True): + name: Optional[str] = None + email: str + + class CollectionEntry(Node, frozen=True): authors: Sequence[Author] + uploader: Uploader badges: Sequence[Badge] concept_doi: Optional[str] covers: Sequence[HttpUrl] diff --git a/bioimageio_collection_backoffice/remote_collection.py b/bioimageio_collection_backoffice/remote_collection.py index df657e57..dc8eab32 100644 --- a/bioimageio_collection_backoffice/remote_collection.py +++ b/bioimageio_collection_backoffice/remote_collection.py @@ -19,7 +19,6 @@ List, Literal, Mapping, - NamedTuple, Optional, Sequence, Tuple, @@ -50,6 +49,7 @@ CollectionWebsiteConfig, ConceptSummary, ConceptVersion, + Uploader, ) from .db_structure.chat import Chat, Message from .db_structure.compatibility import ( @@ -569,11 +569,6 @@ def doi(self): return None -class Uploader(NamedTuple): - email: Optional[str] - name: str - - @dataclass class RecordBase(RemoteBase, ABC): """Base class for a `RecordDraft` and `Record`""" @@ -633,18 +628,7 @@ def extend_chat( def get_uploader(self): rdf = self.get_rdf() - try: - uploader = rdf["uploader"] - email = uploader["email"] - name = uploader.get( - "name", f"{rdf.get('type', 'bioimage.io resource')} contributor" - ) - except Exception as e: - logger.error("failed to extract uploader from rdf: {}", e) - email = None - name = "bioimage.io resource contributor" - - return Uploader(email=email, name=name) + return Uploader.model_validate(rdf["uploader"]) def get_file_url(self, path: str): return self.client.get_file_url(f"{self.folder}files/{path}") @@ -1261,6 +1245,7 @@ def get_compat_tag(tool: str): return [ CollectionEntry( authors=rdf.get("authors", []), + uploader=rdf["uploader"], badges=resolve_relative_path( maybe_swap_with_thumbnail(rdf.get("badges", []), thumbnails), parsed_root, From d8e6b15b63eeb751049821dc1a839069d151fc3a Mon Sep 17 00:00:00 2001 From: fynnbe Date: Wed, 13 Nov 2024 23:02:23 +0100 Subject: [PATCH 2/3] fix notify_uploader --- .../mailroom/send_email.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/bioimageio_collection_backoffice/mailroom/send_email.py b/bioimageio_collection_backoffice/mailroom/send_email.py index 46b8a58e..622db390 100644 --- a/bioimageio_collection_backoffice/mailroom/send_email.py +++ b/bioimageio_collection_backoffice/mailroom/send_email.py @@ -17,19 +17,17 @@ def notify_uploader(rv: Union[RecordDraft, Record], subject_end: str, msg: str): - email, name = rv.get_uploader() - if email is None: - raise ValueError("missing uploader email") + uploader = rv.get_uploader() subject = f"{STATUS_UPDATE_SUBJECT}{rv.id} {rv.version} {subject_end.strip()}" - if email == BOT_EMAIL: + if uploader.email == BOT_EMAIL: logger.info("skipping email '{}' to {}", subject, BOT_EMAIL) return send_email( subject=subject, body=( - f"Dear {name},\n" + f"Dear {uploader.name},\n" + f"{msg.strip()}\n" + "Kind regards,\n" + "The bioimage.io bot 🦒\n" @@ -37,7 +35,7 @@ def notify_uploader(rv: Union[RecordDraft, Record], subject_end: str, msg: str): ).replace( "\n", "\n\n" # respect newlines in markdown ), - recipients=[email], + recipients=[uploader.email], ) From b349b911cb0fd01311e9fdfa5fa41aec7ddd003a Mon Sep 17 00:00:00 2001 From: fynnbe Date: Wed, 13 Nov 2024 23:19:18 +0100 Subject: [PATCH 3/3] add status to draft collection entries --- bioimageio_collection_backoffice/collection_json.py | 3 +++ bioimageio_collection_backoffice/remote_collection.py | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/bioimageio_collection_backoffice/collection_json.py b/bioimageio_collection_backoffice/collection_json.py index 1b4aecf0..312c1b29 100644 --- a/bioimageio_collection_backoffice/collection_json.py +++ b/bioimageio_collection_backoffice/collection_json.py @@ -11,6 +11,7 @@ CollectionWebsiteConfigTemplate, ) from .common import Node +from .db_structure.version_info import DraftStatus, ErrorStatus class Author(Node, frozen=True): @@ -58,6 +59,8 @@ class CollectionEntry(Node, frozen=True): training_data: Optional[TrainingData] = None type: Literal["application", "model", "notebook", "dataset"] source: Optional[str] = None + status: Optional[Union[DraftStatus, ErrorStatus]] = None + """status of the draft (for collection_draft.json only)""" def __lt__(self, other: CollectionEntry): sdc = 0 if self.download_count == "?" else self.download_count diff --git a/bioimageio_collection_backoffice/remote_collection.py b/bioimageio_collection_backoffice/remote_collection.py index dc8eab32..ebdcc508 100644 --- a/bioimageio_collection_backoffice/remote_collection.py +++ b/bioimageio_collection_backoffice/remote_collection.py @@ -37,7 +37,7 @@ from loguru import logger from pydantic import AnyUrl from ruyaml import YAML -from typing_extensions import Concatenate, ParamSpec +from typing_extensions import Concatenate, ParamSpec, assert_never from ._settings import settings from ._thumbnails import create_thumbnails @@ -1177,6 +1177,11 @@ def create_collection_entries( f"{record_version.concept.folder}versions.json", versions_info.model_dump(mode="json"), ) + status = None + elif isinstance(record_version, RecordDraft): + status = record_version.info.status + else: + assert_never(record_version) try: # legacy nickname @@ -1274,5 +1279,6 @@ def get_compat_tag(tool: str): training_data=rdf["training_data"] if "training_data" in rdf else None, type=rdf["type"], source=rdf.get("source"), + status=status, ) ], id_map