Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions alembic/versions/00dab0f5f498_add_external_links_property_to_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""add external links property to experiments

Revision ID: 00dab0f5f498
Revises: b22b450d409c
Create Date: 2025-12-16 12:06:15.265947

"""

import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

from alembic import op

# revision identifiers, used by Alembic.
revision = "00dab0f5f498"
down_revision = "b22b450d409c"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"experiments",
sa.Column("external_links", postgresql.JSONB(astext_type=sa.Text()), nullable=False, server_default="{}"),
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("experiments", "external_links")
# ### end Alembic commands ###
1 change: 1 addition & 0 deletions src/mavedb/models/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class Experiment(Base):
abstract_text = Column(String, nullable=False)
method_text = Column(String, nullable=False)
extra_metadata = Column(JSONB, nullable=False)
external_links = Column(JSONB, nullable=False, default={})

private = Column(Boolean, nullable=False, default=True)
approved = Column(Boolean, nullable=False, default=False)
Expand Down
13 changes: 12 additions & 1 deletion src/mavedb/view_models/collection.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from datetime import date
from typing import Any, Sequence, Optional
from typing import Any, Optional, Sequence

from pydantic import Field, model_validator

Expand Down Expand Up @@ -132,3 +132,14 @@ class Collection(SavedCollection):
# NOTE: Coupled to ContributionRole enum
class AdminCollection(Collection):
pass


# Properties to return for official collections
class OfficialCollection(BaseModel):
badge_name: str
name: str
urn: str

class Config:
arbitrary_types_allowed = True
from_attributes = True
15 changes: 15 additions & 0 deletions src/mavedb/view_models/components/external_link.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from typing import Optional

from mavedb.view_models.base.base import BaseModel


class ExternalLink(BaseModel):
"""
Represents an external hyperlink for view models.

Attributes:
url (Optional[str]): Fully qualified URL for the external resource.
May be None if no link is available or applicable.
"""

url: Optional[str] = None
19 changes: 6 additions & 13 deletions src/mavedb/view_models/experiment.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
from datetime import date
from typing import Any, Collection, Optional, Sequence

from pydantic import field_validator, model_validator, ValidationInfo
from pydantic import ValidationInfo, field_validator, model_validator

from mavedb.lib.validation import urn_re
from mavedb.lib.validation.exceptions import ValidationError
from mavedb.lib.validation.transform import (
transform_experiment_set_to_urn,
transform_score_set_list_to_urn_list,
transform_record_publication_identifiers,
transform_score_set_list_to_urn_list,
)
from mavedb.lib.validation import urn_re
from mavedb.lib.validation.utilities import is_null
from mavedb.view_models import record_type_validator, set_record_type
from mavedb.view_models.base.base import BaseModel
from mavedb.view_models.collection import OfficialCollection
from mavedb.view_models.components.external_link import ExternalLink
from mavedb.view_models.contributor import Contributor, ContributorCreate
from mavedb.view_models.doi_identifier import (
DoiIdentifier,
Expand All @@ -37,16 +39,6 @@
from mavedb.view_models.user import SavedUser, User


class OfficialCollection(BaseModel):
badge_name: str
name: str
urn: str

class Config:
arbitrary_types_allowed = True
from_attributes = True


class ExperimentBase(BaseModel):
title: str
short_description: str
Expand Down Expand Up @@ -115,6 +107,7 @@ class SavedExperiment(ExperimentBase):
contributors: list[Contributor]
keywords: Sequence[SavedExperimentControlledKeyword]
score_set_urns: list[str]
external_links: dict[str, ExternalLink]

_record_type_factory = record_type_validator()(set_record_type)

Expand Down
16 changes: 2 additions & 14 deletions src/mavedb/view_models/score_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
from mavedb.models.enums.processing_state import ProcessingState
from mavedb.view_models import record_type_validator, set_record_type
from mavedb.view_models.base.base import BaseModel
from mavedb.view_models.collection import OfficialCollection
from mavedb.view_models.components.external_link import ExternalLink
from mavedb.view_models.contributor import Contributor, ContributorCreate
from mavedb.view_models.doi_identifier import (
DoiIdentifier,
Expand Down Expand Up @@ -49,20 +51,6 @@
UnboundedRange = tuple[Union[float, None], Union[float, None]]


class ExternalLink(BaseModel):
url: Optional[str] = None


class OfficialCollection(BaseModel):
badge_name: str
name: str
urn: str

class Config:
arbitrary_types_allowed = True
from_attributes = True


class ScoreSetBase(BaseModel):
"""Base class for score set view models."""

Expand Down
36 changes: 17 additions & 19 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging # noqa: F401
import sys
from datetime import datetime
from unittest import mock
import sys

import email_validator
import pytest
Expand All @@ -11,35 +11,33 @@
from sqlalchemy.pool import NullPool

from mavedb.db.base import Base
from mavedb.models import * # noqa: F403
from mavedb.models.experiment import Experiment
from mavedb.models.experiment_set import ExperimentSet
from mavedb.models.score_set_publication_identifier import ScoreSetPublicationIdentifierAssociation
from mavedb.models.user import User, UserRole, Role
from mavedb.models.license import License
from mavedb.models.taxonomy import Taxonomy
from mavedb.models.publication_identifier import PublicationIdentifier
from mavedb.models.experiment import Experiment
from mavedb.models.variant import Variant
from mavedb.models.mapped_variant import MappedVariant
from mavedb.models.publication_identifier import PublicationIdentifier
from mavedb.models.score_set import ScoreSet

from mavedb.models import * # noqa: F403

from mavedb.models.score_set_publication_identifier import ScoreSetPublicationIdentifierAssociation
from mavedb.models.taxonomy import Taxonomy
from mavedb.models.user import Role, User, UserRole
from mavedb.models.variant import Variant
from tests.helpers.constants import (
ADMIN_USER,
EXTRA_USER,
TEST_LICENSE,
TEST_BRNICH_SCORE_CALIBRATION,
TEST_INACTIVE_LICENSE,
TEST_LICENSE,
TEST_PATHOGENICITY_SCORE_CALIBRATION,
TEST_PUBMED_IDENTIFIER,
TEST_SAVED_TAXONOMY,
TEST_USER,
VALID_VARIANT_URN,
VALID_SCORE_SET_URN,
VALID_EXPERIMENT_URN,
VALID_EXPERIMENT_SET_URN,
TEST_PUBMED_IDENTIFIER,
TEST_VALID_POST_MAPPED_VRS_ALLELE_VRS2_X,
TEST_VALID_PRE_MAPPED_VRS_ALLELE_VRS2_X,
TEST_BRNICH_SCORE_CALIBRATION,
TEST_PATHOGENICITY_SCORE_CALIBRATION,
VALID_EXPERIMENT_SET_URN,
VALID_EXPERIMENT_URN,
VALID_SCORE_SET_URN,
VALID_VARIANT_URN,
)

sys.path.append(".")
Expand All @@ -56,7 +54,7 @@
assert pytest_postgresql.factories

# Allow the @test domain name through our email validator.
email_validator.SPECIAL_USE_DOMAIN_NAMES.remove("test")
email_validator.TEST_ENVIRONMENT = True


@pytest.fixture()
Expand Down
3 changes: 3 additions & 0 deletions tests/helpers/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@
"primaryPublicationIdentifiers": [],
"secondaryPublicationIdentifiers": [],
"rawReadIdentifiers": [],
"externalLinks": {},
# keys to be set after receiving response
"urn": None,
"experimentSetUrn": None,
Expand Down Expand Up @@ -580,6 +581,7 @@
"primaryPublicationIdentifiers": [],
"secondaryPublicationIdentifiers": [],
"rawReadIdentifiers": [],
"externalLinks": {},
# keys to be set after receiving response
"urn": None,
"experimentSetUrn": None,
Expand Down Expand Up @@ -630,6 +632,7 @@
"primaryPublicationIdentifiers": [],
"secondaryPublicationIdentifiers": [],
"rawReadIdentifiers": [],
"externalLinks": {},
# keys to be set after receiving response
"urn": None,
"experimentSetUrn": None,
Expand Down