Skip to content

Commit

Permalink
Merge pull request #362 from VariantEffect/release-2024.4.2
Browse files Browse the repository at this point in the history
Release 2024.4.2
  • Loading branch information
bencap authored Nov 21, 2024
2 parents 65dd9cb + f772db4 commit 82cc0d6
Show file tree
Hide file tree
Showing 59 changed files with 2,017 additions and 630 deletions.
40 changes: 40 additions & 0 deletions alembic/manual_migrations/migrate_non_api_like_constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import sqlalchemy as sa
from sqlalchemy.orm import Session, configure_mappers

from mavedb.models import *
from mavedb.models.enums.target_category import TargetCategory
from mavedb.models.target_gene import TargetGene

from mavedb.db.session import SessionLocal

configure_mappers()

def api_like_target_gene_category(category: str):
if category == "Protein coding":
return TargetCategory.protein_coding
elif category == "Other noncoding":
return TargetCategory.other_noncoding
elif category == "Regulatory":
return TargetCategory.regulatory
else:
raise ValueError()


def do_migration(db: Session):
target_genes = db.scalars(sa.select(TargetGene)).all()

for target in target_genes:
target.category = api_like_target_gene_category(target.category)
db.add(target)

db.commit()


if __name__ == "__main__":
db = SessionLocal()
db.current_user = None # type: ignore

do_migration(db)

db.commit()
db.close()
33 changes: 33 additions & 0 deletions alembic/manual_migrations/refresh_published_tmp_urns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import sqlalchemy as sa
from sqlalchemy.orm import Session, configure_mappers

from mavedb.models import *

from mavedb.lib.score_sets import refresh_variant_urns

from mavedb.models.score_set import ScoreSet
from mavedb.models.variant import Variant

from mavedb.db.session import SessionLocal

configure_mappers()


def do_migration(db: Session):
published_score_sets_with_associated_tmp_variants: sa.ScalarResult[str]
published_score_sets_with_associated_tmp_variants = db.execute(
sa.select(sa.distinct(ScoreSet.urn)).join(Variant).where(ScoreSet.published_date.is_not(None), Variant.urn.like("%tmp:%"))
).scalars()

for score_set_urn in published_score_sets_with_associated_tmp_variants:
refresh_variant_urns(db, db.execute(sa.select(ScoreSet).where(ScoreSet.urn == score_set_urn)).scalar_one())


if __name__ == "__main__":
db = SessionLocal()
db.current_user = None # type: ignore

do_migration(db)

db.commit()
db.close()
54 changes: 54 additions & 0 deletions alembic/versions/03c7124c33e1_target_category_enum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""Target category enum
Revision ID: 03c7124c33e1
Revises: 2b6f40ea2fb6
Create Date: 2024-11-01 11:27:03.609116
"""

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "03c7124c33e1"
down_revision = "2b6f40ea2fb6"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"target_genes",
"category",
type_=sa.Enum(
"protein_coding",
"other_noncoding",
"regulatory",
name="targetcategory",
native_enum=False,
create_constraint=True,
length=32,
),
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"target_genes",
"category",
type_=sa.String(),
existing_type=sa.Enum(
"protein_coding",
"other_noncoding",
"regulatory",
name="targetcategory",
native_enum=False,
create_constraint=True,
length=32,
),
)
# ### end Alembic commands ###
2 changes: 1 addition & 1 deletion alembic/versions/2b6f40ea2fb6_add_score_range_column.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Add score range column
Revision ID: 2b6f40ea2fb6
Revises: 1d4933b4b6f7
Revises: 1cee01c42909
Create Date: 2024-09-09 12:25:33.180077
"""
Expand Down
29 changes: 29 additions & 0 deletions alembic/versions/68a0ec57694e_add_active_column_to_licenses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Add active column to licenses
Revision ID: 68a0ec57694e
Revises: 03c7124c33e1
Create Date: 2024-10-22 15:36:41.868909
"""

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "68a0ec57694e"
down_revision = "03c7124c33e1"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("licenses", sa.Column("active", sa.Boolean(), nullable=False, server_default=sa.true()))
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("licenses", "active")
# ### end Alembic commands ###
555 changes: 307 additions & 248 deletions poetry.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "mavedb"
version = "2024.4.1"
version = "2024.4.2"
description = "API for MaveDB, the database of Multiplexed Assays of Variant Effect."
license = "AGPL-3.0-only"
readme = "README.md"
Expand All @@ -26,7 +26,7 @@ python = "^3.9"

fqfa = "~1.3.0"
pyhumps = "~3.8.0"
pyyaml = "~5.1"
pyyaml = "~6.0.1"
IDUtils = "~1.2.0"
mavehgvs = "~0.6.0"
eutils = "~0.6.0"
Expand Down Expand Up @@ -99,6 +99,7 @@ mypy_path = "mypy_stubs"
addopts = "-v -rP --import-mode=importlib --disable-socket --allow-hosts localhost,::1,127.0.0.1"
asyncio_mode = 'strict'
testpaths = "tests/"
pythonpath = "."
norecursedirs = "tests/helpers/"
# Uncomment the following lines to include application log output in Pytest logs.
# log_cli = true
Expand Down
2 changes: 1 addition & 1 deletion src/mavedb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
logger = module_logging.getLogger(__name__)

__project__ = "mavedb-api"
__version__ = "2024.4.1"
__version__ = "2024.4.2"

logger.info(f"MaveDB {__version__}")
2 changes: 1 addition & 1 deletion src/mavedb/lib/experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def search_experiments(
)
)

items: list[Experiment] = query.order_by(Experiment.title).all()
items: list[Experiment] = query.order_by(Experiment.urn, Experiment.title).all()
if not items:
items = []

Expand Down
15 changes: 15 additions & 0 deletions src/mavedb/lib/score_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,21 @@ def create_variants(db, score_set: ScoreSet, variants_data: list[VariantData], b
return len(score_set.variants)


def refresh_variant_urns(db: Session, score_set: ScoreSet):
variants = db.execute(select(Variant).where(Variant.score_set_id == score_set.id)).scalars()

for variant in variants:
if not variant.urn:
raise ValueError("All variants should have an associated URN.")

variant_number = variant.urn.split("#")[1]
refreshed_urn = f"{score_set.urn}#{variant_number}"
variant.urn = refreshed_urn
db.add(variant)

db.commit()


def bulk_create_urns(n, score_set, reset_counter=False) -> list[str]:
start_value = 0 if reset_counter else score_set.num_variants
parent_urn = score_set.urn
Expand Down
25 changes: 0 additions & 25 deletions src/mavedb/lib/script_environment.py

This file was deleted.

56 changes: 56 additions & 0 deletions src/mavedb/lib/target_genes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import logging
from typing import Optional

from sqlalchemy import func, or_
from sqlalchemy.orm import Session

from mavedb.lib.logging.context import logging_context, save_to_logging_context
from mavedb.models.contributor import Contributor
from mavedb.models.score_set import ScoreSet
from mavedb.models.target_gene import TargetGene
from mavedb.models.user import User
from mavedb.view_models.search import TextSearch

logger = logging.getLogger(__name__)


def search_target_genes(
db: Session,
owner_or_contributor: Optional[User],
search: TextSearch,
limit: Optional[int],
) -> list[TargetGene]:
save_to_logging_context({"target_gene_search_criteria": search.dict()})

query = db.query(TargetGene)

if search.text and len(search.text.strip()) > 0:
lower_search_text = search.text.strip().lower()
query = query.filter(func.lower(TargetGene.name).contains(lower_search_text))
if owner_or_contributor is not None:
query = query.filter(
TargetGene.score_set.has(
or_(
ScoreSet.created_by_id == owner_or_contributor.id,
ScoreSet.contributors.any(
Contributor.orcid_id == owner_or_contributor.username
),
)
)
)

query = query.order_by(TargetGene.name)
if limit is not None:
query = query.limit(limit)

target_genes = query.all()
if not target_genes:
target_genes = []

save_to_logging_context({"matching_resources": len(target_genes)})
logger.debug(
msg=f"Target gene search yielded {len(target_genes)} matching resources.",
extra=logging_context(),
)

return target_genes
1 change: 0 additions & 1 deletion src/mavedb/lib/validation/constants/target.py
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
valid_categories = ["Protein coding", "Regulatory", "Other noncoding"]
valid_sequence_types = ["infer", "dna", "protein"]
23 changes: 1 addition & 22 deletions src/mavedb/lib/validation/target.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,10 @@
from fqfa import infer_sequence_type
from fqfa.validator import amino_acids_validator, dna_bases_validator

from mavedb.lib.validation.constants.target import valid_categories, valid_sequence_types
from mavedb.lib.validation.constants.target import valid_sequence_types
from mavedb.lib.validation.exceptions import ValidationError


def validate_target_category(category: str):
"""
If the target category provided does not fall within a pre-defined list of valid categories.
Parameters
__________
category: str
The target category to be validated.
Raises
______
ValidationError
If the target category provided is not valid.
"""
if category not in valid_categories:
raise ValidationError(
"{} is not a valid target category. Valid categories are "
"Protein coding, Regulatory, and Other noncoding".format(category)
)


def validate_sequence_category(sequence_type: str):
"""
If the sequence type provided does not fall within a pre-defined list of valid sequence types.
Expand Down
7 changes: 7 additions & 0 deletions src/mavedb/models/enums/target_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from enum import Enum


class TargetCategory(str, Enum):
protein_coding = "protein_coding"
regulatory = "regulatory"
other_noncoding = "other_noncoding"
3 changes: 2 additions & 1 deletion src/mavedb/models/license.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from datetime import date

from sqlalchemy import Column, Date, Integer, String
from sqlalchemy import Boolean, Column, Date, Integer, String

from mavedb.db.base import Base

Expand All @@ -16,3 +16,4 @@ class License(Base):
version = Column(String, nullable=True, unique=False)
creation_date = Column(Date, nullable=False, default=date.today)
modification_date = Column(Date, nullable=False, default=date.today, onupdate=date.today)
active = Column(Boolean, nullable=False)
4 changes: 2 additions & 2 deletions src/mavedb/models/mapped_variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class MappedVariant(Base):

id = Column(Integer, primary_key=True)

pre_mapped = Column(JSONB, nullable=True)
post_mapped = Column(JSONB, nullable=True)
pre_mapped = Column(JSONB(none_as_null=True), nullable=True)
post_mapped = Column(JSONB(none_as_null=True), nullable=True)
vrs_version = Column(String, nullable=True)
error_message = Column(String, nullable=True)
modification_date = Column(Date, nullable=False, default=date.today, onupdate=date.today)
Expand Down
Loading

0 comments on commit 82cc0d6

Please sign in to comment.