diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3c4f071..9b2ce9c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,6 +14,7 @@ jobs: matrix: os: [ ubuntu-latest ] python-version: [ "3.11" ] + pydantic: [ "pydantic1", "pydantic2" ] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} @@ -22,7 +23,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - pip install hatch + pip install tox - name: Test with pytest run: - hatch run test + tox -e py-${{ matrix.pydantic }} diff --git a/pyproject.toml b/pyproject.toml index 77eda85..39427ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,12 @@ dependencies = [ "uvicorn", ] +[project.optional-dependencies] +tests = [ + "pytest", + "coverage", +] + [project.urls] Documentation = "https://github.com/biopragmatics/semra#readme" Issues = "https://github.com/biopragmatics/semra/issues" diff --git a/src/semra/pipeline.py b/src/semra/pipeline.py index 595bcaf..f686a15 100644 --- a/src/semra/pipeline.py +++ b/src/semra/pipeline.py @@ -58,7 +58,7 @@ class Input(BaseModel): class Mutation(BaseModel): """Represents a mutation operation on a mapping set.""" - source: str = Field() + source: str = Field(..., description="The source type") confidence: float = 1.0 old: Reference = Field(default=DB_XREF) new: Reference = Field(default=EXACT_MATCH) @@ -69,7 +69,7 @@ class Configuration(BaseModel): inputs: list[Input] negative_inputs: list[Input] = Field(default=[Input(source="biomappings", prefix="negative")]) - priority: list[str] = Field(description="If no priority is given, is inferred from the order of inputs") + priority: list[str] = Field(..., description="If no priority is given, is inferred from the order of inputs") mutations: list[Mutation] = Field(default_factory=list) exclude_pairs: list[tuple[str, str]] = Field( default_factory=list, @@ -91,7 +91,7 @@ class Configuration(BaseModel): sssom_add_labels: bool = False - @root_validator + @root_validator(skip_on_failure=True) def infer_priority(cls, values): # noqa:N805 """Infer the priority from the input list of not given.""" priority = values["priority"] diff --git a/src/semra/struct.py b/src/semra/struct.py index b5bb68e..78aee30 100644 --- a/src/semra/struct.py +++ b/src/semra/struct.py @@ -14,6 +14,7 @@ from curies import Reference from more_itertools import triplewise from pydantic import Field +from pydantic.types import UUID, UUID4 __all__ = [ "Reference", @@ -63,10 +64,10 @@ def curie(self) -> str: class MappingSet(pydantic.BaseModel): - name: str - version: str | None = Field(description="The version of the dataset from which the mapping comes") - license: str | None = Field(description="License name or URL for mapping set") - confidence: float | None = Field(description="Mapping set level confidence") + name: str = Field(..., description="Name of the mapping set") + version: str | None = Field(default=None, description="The version of the dataset from which the mapping comes") + license: str | None = Field(default=None,description="License name or URL for mapping set") + confidence: float | None = Field(default=None,description="Mapping set level confidence") def key(self): return self.name, self.version or "", self.license or "", 1.0 if self.confidence is None else self.confidence @@ -98,12 +99,13 @@ class Config: default=Reference(prefix="semapv", identifier="UnspecifiedMapping"), description="A SSSOM-compliant justification", ) - mapping_set: MappingSet = Field(description="The name of the dataset from which the mapping comes") + mapping_set: MappingSet = Field(..., description="The name of the dataset from which the mapping comes") author: Reference | None = Field( + default=None, description="A reference to the author of the mapping (e.g. with ORCID)", example=Reference(prefix="orcid", identifier="0000-0003-4423-4370"), ) - uuid: uuid.UUID = Field(default_factory=uuid.uuid4) + uuid: UUID4 = Field(default_factory=uuid.uuid4) def key(self): """Get a key suitable for hashing the evidence. @@ -136,7 +138,7 @@ class Config: frozen = True evidence_type: Literal["reasoned"] = Field(default="reasoned") - justification: Reference = Field(description="A SSSOM-compliant justification") + justification: Reference = Field(..., description="A SSSOM-compliant justification") mappings: list[Mapping] = Field( ..., description="A list of mappings and their evidences consumed to create this evidence" ) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..1603bc7 --- /dev/null +++ b/tox.ini @@ -0,0 +1,19 @@ +# Tox (http://tox.testrun.org/) is a tool for running tests +# in multiple virtualenvs. This configuration file will run the +# test suite on all supported python versions. To use it, "pip install tox" +# and then run "tox" from this directory. + +[tox] +isolated_build = true +envlist = + # the actual tests + py-pydantic1 + py-pydantic2 + +[testenv] +commands = python -m coverage run -p -m pytest --durations=20 {posargs:tests} +deps = + pydantic1: pydantic<2.0 + pydantic2: pydantic>=2.0 +extras = + tests