From 224b526a57f9d05d16baca5ddbdbc6e52c0e5d66 Mon Sep 17 00:00:00 2001 From: Chiara Rasi Date: Mon, 11 Dec 2023 10:02:09 +0100 Subject: [PATCH 1/2] Convert validators and Config to Pydantic 2 --- CHANGELOG.md | 2 ++ schug/config.py | 6 ++--- schug/models.py | 0 schug/models/common.py | 4 +-- schug/models/gene.py | 52 +++++--------------------------------- schug/models/transcript.py | 7 ++--- 6 files changed, 17 insertions(+), 54 deletions(-) delete mode 100644 schug/models.py diff --git a/CHANGELOG.md b/CHANGELOG.md index aed94a7..38d406a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ - Updated version of external images used in GitHub actions - Updated Python version to v3.11 in tests GitHub action - Removed pytest from the package dependencies +### Fixed +- Converted deprecated Pydantic validators and Config into Pydantic 2 format ## [1.4] ### Changed diff --git a/schug/config.py b/schug/config.py index 553caf6..afae549 100644 --- a/schug/config.py +++ b/schug/config.py @@ -1,6 +1,6 @@ from pathlib import Path -from pydantic_settings import BaseSettings +from pydantic_settings import BaseSettings, SettingsConfigDict DEMO_DB: str = "sqlite://" SCHUG_PACKAGE = Path(__file__).parent @@ -11,12 +11,10 @@ class Settings(BaseSettings): """Settings for serving the schug app""" + model_config = SettingsConfigDict(env_file=str(ENV_FILE)) db_uri: str = DEMO_DB host: str = "localhost" port: int = 8000 - class Config: - from_file = str(ENV_FILE) - settings = Settings() diff --git a/schug/models.py b/schug/models.py deleted file mode 100644 index e69de29..0000000 diff --git a/schug/models/common.py b/schug/models/common.py index 634fe3d..b7f92f7 100644 --- a/schug/models/common.py +++ b/schug/models/common.py @@ -1,7 +1,7 @@ from enum import Enum from typing import Literal, Optional -from pydantic import validator +from pydantic import field_validator from sqlmodel import SQLModel @@ -26,7 +26,7 @@ class CoordBase(SQLModel): resource_id: str genome_build: str - @validator("genome_build", pre=True) + @field_validator("genome_build", mode="before") def correct_build(cls, v): if v != "37" and v != "38": raise ValueError(f"genome build: {v} must be either 37 or 38") diff --git a/schug/models/gene.py b/schug/models/gene.py index 0460507..8c16ed7 100644 --- a/schug/models/gene.py +++ b/schug/models/gene.py @@ -2,7 +2,7 @@ from pydantic import BaseModel from pydantic import Field as PydanticField -from pydantic import validator +from pydantic import field_validator from sqlmodel import Field, Relationship from .common import CoordBase @@ -44,13 +44,14 @@ class EnsemblGene(BaseModel): hgnc_symbol: Optional[str] = PydanticField(None, alias="HGNC symbol") hgnc_id: Optional[int] = PydanticField(None, alias="HGNC ID") - @validator("*", pre=True) + + @field_validator("*", mode="before") def convert_to_none(cls, v): if v == "": return None return v - @validator("hgnc_id", pre=True) + @field_validator("hgnc_id", mode="before") def modify_id(cls, v): if type(v) != int: return v.replace("HGNC:", "") @@ -58,7 +59,7 @@ def modify_id(cls, v): class HgncGene(BaseModel): - gene_id: str = PydanticField(..., alias="Gene stable ID") + gene_id: str = PydanticField(..., alias="Gene stable ID", validate_default=True) ensembl_gene_id: str entrez_id: int hgnc_symbol: str = PydanticField(None, alias="HGNC symbol") @@ -69,7 +70,7 @@ class HgncGene(BaseModel): aliases: List[str] = [] - @validator("gene_id", always=True) + @field_validator("gene_id") def set_alias_symbols(cls, _, values: dict): return values["alias_symbols"].split("|") @@ -85,43 +86,4 @@ def into_gene(ensembl_gene: EnsemblGene) -> Gene: primary_symbol=ensembl_gene.hgnc_symbol, resource_id=ensembl_gene.resource_id, resource=ensembl_gene.resource, - ) - - -""" -{ - "hgnc_id": "HGNC:15766", - "homeodb": "8666", - "horde_id": None, - "imgt": None, - "intermediate_filament_db": None, - "iuphar": None, - "kznf_gene_catalog": None, - "lncrnadb": None, - "location": "20q13.13", - "location_sortable": "20q13.13", - "locus_group": "protein-coding gene", - "locus_type": "gene with protein product", - "lsdb": "", - "mamit-trnadb": None, - "merops": None, - "mgd_id": "MGI:1338758", - "mirbase": "", - "name": "activity dependent neuroprotector homeobox", - "omim_id": "611386", - "orphanet": "406010", - "prev_name": "activity-dependent neuroprotector", - "prev_symbol": "", - "pseudogene.org": None, - "pubmed_id": "9872452|11013255", - "refseq_accession": "NM_181442", - "rgd_id": "RGD:71030", - "rna_central_ids": None, - "snornabase": "", - "status": "Approved", - "symbol": "ADNP", - "ucsc_id": "uc002xvt.3", - "uniprot_ids": "Q9H2P0", - "vega_id": "OTTHUMG00000032737", -} -""" + ) \ No newline at end of file diff --git a/schug/models/transcript.py b/schug/models/transcript.py index 2759d23..6b11723 100644 --- a/schug/models/transcript.py +++ b/schug/models/transcript.py @@ -2,7 +2,7 @@ from pydantic import BaseModel from pydantic import Field as PydanticField -from pydantic import validator +from pydantic import field_validator from schug.models.exon import ExonRead from sqlmodel import Field, Relationship, SQLModel @@ -53,9 +53,10 @@ class EnsemblTranscript(BaseModel): refseq_mrna: str = PydanticField(None, alias="RefSeq mRNA ID") refseq_mrna_predicted: str = PydanticField(None, alias="RefSeq mRNA predicted ID") refseq_ncrna_predicted: str = PydanticField(None, alias="RefSeq ncRNA ID") - refseq_id: Optional[str] = None + refseq_id: Optional[str] = PydanticField(None, validate_default=True) - @validator("refseq_id", always=True) + + @field_validator("refseq_id") def set_refseq_id(cls, _, values: dict) -> Optional[str]: order: List[str] = [ "refseq_mrna", From 5933c8ce5aecc25f9dc2763aa76a58f8d7f84b2b Mon Sep 17 00:00:00 2001 From: Chiara Rasi Date: Mon, 11 Dec 2023 10:05:56 +0100 Subject: [PATCH 2/2] Run black --- schug/models/gene.py | 3 +-- schug/models/transcript.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/schug/models/gene.py b/schug/models/gene.py index 8c16ed7..b77c723 100644 --- a/schug/models/gene.py +++ b/schug/models/gene.py @@ -44,7 +44,6 @@ class EnsemblGene(BaseModel): hgnc_symbol: Optional[str] = PydanticField(None, alias="HGNC symbol") hgnc_id: Optional[int] = PydanticField(None, alias="HGNC ID") - @field_validator("*", mode="before") def convert_to_none(cls, v): if v == "": @@ -86,4 +85,4 @@ def into_gene(ensembl_gene: EnsemblGene) -> Gene: primary_symbol=ensembl_gene.hgnc_symbol, resource_id=ensembl_gene.resource_id, resource=ensembl_gene.resource, - ) \ No newline at end of file + ) diff --git a/schug/models/transcript.py b/schug/models/transcript.py index 6b11723..db52f65 100644 --- a/schug/models/transcript.py +++ b/schug/models/transcript.py @@ -55,7 +55,6 @@ class EnsemblTranscript(BaseModel): refseq_ncrna_predicted: str = PydanticField(None, alias="RefSeq ncRNA ID") refseq_id: Optional[str] = PydanticField(None, validate_default=True) - @field_validator("refseq_id") def set_refseq_id(cls, _, values: dict) -> Optional[str]: order: List[str] = [