Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🐛 Fixed packages mypy, pylint and tests (#6678)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrei Neagu <[email protected]>
GitHK and Andrei Neagu authored Nov 11, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 60fe257 commit f07afbf
Showing 38 changed files with 219 additions and 174 deletions.
4 changes: 2 additions & 2 deletions packages/common-library/tests/test_pydantic_validators.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@

import pytest
from common_library.pydantic_validators import (
validate_legacy_timedelta_str,
_validate_legacy_timedelta_str,
validate_numeric_string_as_timedelta,
)
from faker import Faker
@@ -16,7 +16,7 @@ def test_validate_legacy_timedelta(monkeypatch: pytest.MonkeyPatch, faker: Faker
class Settings(BaseSettings):
APP_NAME: str
REQUEST_TIMEOUT: Annotated[
timedelta, BeforeValidator(validate_legacy_timedelta_str)
timedelta, BeforeValidator(_validate_legacy_timedelta_str)
] = Field(default=timedelta(hours=1))

model_config = SettingsConfigDict()
Original file line number Diff line number Diff line change
@@ -113,7 +113,7 @@ class ClusterDetailsGet(ClusterDetails):


class ClusterCreate(BaseCluster):
owner: GroupID | None
owner: GroupID | None = None # type: ignore[assignment]
authentication: ExternalClusterAuthentication
access_rights: dict[GroupID, ClusterAccessRights] = Field(
alias="accessRights", default_factory=dict
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Any, TypeAlias

from models_library.basic_types import IDStr
from pydantic import AnyHttpUrl, AnyUrl, BaseModel, Field, field_validator
from pydantic import AnyHttpUrl, AnyUrl, BaseModel, ConfigDict, Field, field_validator

from ..clusters import ClusterID
from ..projects import ProjectID
@@ -19,6 +19,17 @@ class ComputationGet(ComputationTask):
None, description="the link where to stop the task"
)

model_config = ConfigDict(
json_schema_extra={
"examples": [
x | {"url": "http://url.local"} # type:ignore[operator]
for x in ComputationTask.model_config[ # type:ignore[index,union-attr]
"json_schema_extra"
]["examples"]
]
}
)


class ComputationCreate(BaseModel):
user_id: UserID
Original file line number Diff line number Diff line change
@@ -8,8 +8,7 @@
Field,
NonNegativeFloat,
NonNegativeInt,
root_validator,
validator,
model_validator,
)

from ..projects_nodes_io import NodeID
@@ -56,29 +55,13 @@ class DiskUsage(BaseModel):
free: ByteSize = Field(description="remaining space")

total: ByteSize = Field(description="total space = free + used")
used_percent: NonNegativeFloat = Field(
used_percent: float = Field(
ge=0.00,
le=100.00,
description="Percent of used space relative to the total space",
)

@validator("free")
@classmethod
def _free_positive(cls, v: float) -> float:
if v < 0:
msg = f"free={v} cannot be a negative value"
raise ValueError(msg)
return v

@validator("used")
@classmethod
def _used_positive(cls, v: float) -> float:
if v < 0:
msg = f"used={v} cannot be a negative value"
raise ValueError(msg)
return v

@root_validator(pre=True)
@model_validator(mode="before")
@classmethod
def _check_total(cls, values: dict[str, Any]) -> dict[str, Any]:
total = values["total"]
Original file line number Diff line number Diff line change
@@ -311,12 +311,12 @@ class FileUploadCompleteFutureResponse(BaseModel):


class FoldersBody(BaseModel):
source: dict[str, Any] = Field(default_factory=dict)
destination: dict[str, Any] = Field(default_factory=dict)
nodes_map: dict[NodeID, NodeID] = Field(default_factory=dict)
source: Annotated[dict[str, Any], Field(default_factory=dict)]
destination: Annotated[dict[str, Any], Field(default_factory=dict)]
nodes_map: Annotated[dict[NodeID, NodeID], Field(default_factory=dict)]

@model_validator(mode="after")
def ensure_consistent_entries(self) -> Self:
def ensure_consistent_entries(self: Self) -> Self:
source_node_keys = (NodeID(n) for n in self.source.get("workbench", {}))
if set(source_node_keys) != set(self.nodes_map.keys()):
msg = "source project nodes do not fit with nodes_map entries"
Original file line number Diff line number Diff line change
@@ -107,7 +107,9 @@ class ProjectReplace(InputSchema):
uuid: ProjectID
name: ShortTruncatedStr
description: LongTruncatedStr
thumbnail: Annotated[HttpUrl | None, BeforeValidator(empty_str_to_none_pre_validator)] = Field(default=None)
thumbnail: Annotated[
HttpUrl | None, BeforeValidator(empty_str_to_none_pre_validator)
] = Field(default=None)
creation_date: DateTimeStr
last_change_date: DateTimeStr
workbench: NodesDict
@@ -127,13 +129,15 @@ class ProjectReplace(InputSchema):
class ProjectPatch(InputSchema):
name: ShortTruncatedStr | None = Field(default=None)
description: LongTruncatedStr | None = Field(default=None)
thumbnail: Annotated[HttpUrl | None, BeforeValidator(empty_str_to_none_pre_validator)] = Field(default=None)
thumbnail: Annotated[
HttpUrl | None, BeforeValidator(empty_str_to_none_pre_validator)
] = Field(default=None)
access_rights: dict[GroupIDStr, AccessRights] | None = Field(default=None)
classifiers: list[ClassifierID] | None = Field(default=None)
dev: dict | None = Field(default=None)
ui: StudyUI | None = Field(default=None)
quality: dict[str, Any] | None = Field(default=None)


__all__: tuple[str, ...] = (
"EmptyModel",
4 changes: 2 additions & 2 deletions packages/models-library/src/models_library/progress_bar.py
Original file line number Diff line number Diff line change
@@ -12,8 +12,8 @@ class ProgressStructuredMessage(BaseModel):
description: IDStr
current: float
total: int
unit: str | None
sub: "ProgressStructuredMessage | None"
unit: str | None = None
sub: "ProgressStructuredMessage | None" = None

model_config = ConfigDict(
json_schema_extra={
32 changes: 1 addition & 31 deletions packages/models-library/src/models_library/rest_pagination.py
Original file line number Diff line number Diff line change
@@ -136,34 +136,4 @@ def _check_data_compatible_with_meta(cls, v, info: ValidationInfo):
raise ValueError(msg)
return v

model_config = ConfigDict(
extra="forbid",
json_schema_extra={
"examples": [
# first page Page[str]
{
"_meta": {"total": 7, "count": 4, "limit": 4, "offset": 0},
"_links": {
"self": "https://osparc.io/v2/listing?offset=0&limit=4",
"first": "https://osparc.io/v2/listing?offset=0&limit=4",
"prev": None,
"next": "https://osparc.io/v2/listing?offset=1&limit=4",
"last": "https://osparc.io/v2/listing?offset=1&limit=4",
},
"data": ["data 1", "data 2", "data 3", "data 4"],
},
# second and last page
{
"_meta": {"total": 7, "count": 3, "limit": 4, "offset": 1},
"_links": {
"self": "https://osparc.io/v2/listing?offset=1&limit=4",
"first": "https://osparc.io/v2/listing?offset=0&limit=4",
"prev": "https://osparc.io/v2/listing?offset=0&limit=4",
"next": None,
"last": "https://osparc.io/v2/listing?offset=1&limit=4",
},
"data": ["data 5", "data 6", "data 7"],
},
]
},
)
model_config = ConfigDict(extra="forbid")
32 changes: 1 addition & 31 deletions packages/models-library/src/models_library/rpc_pagination.py
Original file line number Diff line number Diff line change
@@ -74,34 +74,4 @@ def create(
data=chunk,
)

model_config = ConfigDict(
extra="forbid",
json_schema_extra={
"examples": [
# first page Page[str]
{
"_meta": {"total": 7, "count": 4, "limit": 4, "offset": 0},
"_links": {
"self": {"offset": 0, "limit": 4},
"first": {"offset": 0, "limit": 4},
"prev": None,
"next": {"offset": 1, "limit": 4},
"last": {"offset": 1, "limit": 4},
},
"data": ["data 1", "data 2", "data 3", "data 4"],
},
# second and last page
{
"_meta": {"total": 7, "count": 3, "limit": 4, "offset": 1},
"_links": {
"self": {"offset": 1, "limit": 4},
"first": {"offset": 0, "limit": 4},
"prev": {"offset": 0, "limit": 4},
"next": None,
"last": {"offset": 1, "limit": 4},
},
"data": ["data 5", "data 6", "data 7"],
},
]
},
)
model_config = ConfigDict(extra="forbid")
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
from enum import Enum
from functools import cached_property
from pathlib import Path
from typing import Any, Literal, TypeAlias
from typing import Annotated, Any, Literal, TypeAlias

from common_library.json_serialization import json_dumps
from pydantic import (
@@ -317,13 +317,14 @@ class DynamicSidecarServiceLabels(BaseModel):
),
)

containers_allowed_outgoing_permit_list: None | (
Json[dict[str, list[NATRule]]]
) = Field(
None,
alias="simcore.service.containers-allowed-outgoing-permit-list",
description="allow internet access to certain domain names and ports per container",
)
containers_allowed_outgoing_permit_list: Annotated[
None | (Json[dict[str, list[NATRule]]]),
Field(
None,
alias="simcore.service.containers-allowed-outgoing-permit-list",
description="allow internet access to certain domain names and ports per container",
),
]

containers_allowed_outgoing_internet: Json[set[str]] | None = Field(
None,
12 changes: 8 additions & 4 deletions packages/models-library/src/models_library/services_base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Annotated

from pydantic import BaseModel, ConfigDict, Field, HttpUrl, field_validator

from .services_types import ServiceKey, ServiceVersion
@@ -8,10 +9,13 @@
class ServiceKeyVersion(BaseModel):
"""Service `key-version` pair uniquely identifies a service"""

key: ServiceKey = Field(
...,
description="distinctive name for the node based on the docker registry path",
)
key: Annotated[
ServiceKey,
Field(
...,
description="distinctive name for the node based on the docker registry path",
),
]
version: ServiceVersion = Field(
...,
description="service version number",
4 changes: 3 additions & 1 deletion packages/models-library/src/models_library/services_types.py
Original file line number Diff line number Diff line change
@@ -61,7 +61,9 @@ def create(cls) -> "RunID":

@classmethod
def __get_pydantic_core_schema__(
cls, source_type: Any, handler: GetCoreSchemaHandler
cls,
source_type: Any, # pylint:disable=unused-argument
handler: GetCoreSchemaHandler,
) -> CoreSchema:
return core_schema.no_info_after_validator_function(cls, handler(str))

Original file line number Diff line number Diff line change
@@ -93,7 +93,8 @@ def _validator(cls, values):
assert set(alternative_field_names).issubset(cls.__fields__) # nosec

got = {
field_name: values.get(field_name) for field_name in alternative_field_names
field_name: getattr(values, field_name)
for field_name in alternative_field_names
}

if not functools.reduce(operator.xor, (v is not None for v in got.values())):
17 changes: 15 additions & 2 deletions packages/models-library/tests/test__models_examples.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import json
from itertools import chain
from typing import Any

import models_library
import pytest
from models_library.rest_pagination import Page
from models_library.rpc_pagination import PageRpc
from pydantic import BaseModel
from pytest_simcore.pydantic_models import walk_model_examples_in_package
from pytest_simcore.examples.models_library import PAGE_EXAMPLES, RPC_PAGE_EXAMPLES
from pytest_simcore.pydantic_models import (
ModelExample,
iter_examples,
walk_model_examples_in_package,
)

GENERIC_EXAMPLES: list[ModelExample] = [
*iter_examples(model_cls=Page[str], examples=PAGE_EXAMPLES),
*iter_examples(model_cls=PageRpc[str], examples=RPC_PAGE_EXAMPLES),
]


@pytest.mark.parametrize(
"model_cls, example_name, example_data",
walk_model_examples_in_package(models_library),
chain(GENERIC_EXAMPLES, walk_model_examples_in_package(models_library)),
)
def test_all_models_library_models_config_examples(
model_cls: type[BaseModel], example_name: int, example_data: Any
Original file line number Diff line number Diff line change
@@ -42,8 +42,8 @@ def test_failing_validation():
with pytest.raises(ValidationError) as exc:
assert DiskUsage.from_efs_guardian(100, 10)

assert "free=" in f"{exc.value}"
assert "negative value" in f"{exc.value}"
assert "free" in f"{exc.value}"
assert "input_value=-90" in f"{exc.value}"

with pytest.raises(ValidationError) as exc:
assert DiskUsage(
@@ -52,8 +52,8 @@ def test_failing_validation():
total=ByteSize(0),
used_percent=-10,
)
assert "used=" in f"{exc.value}"
assert "negative value" in f"{exc.value}"
assert "used" in f"{exc.value}"
assert "input_value=-10" in f"{exc.value}"

with pytest.raises(ValidationError) as exc:
DiskUsage(
5 changes: 3 additions & 2 deletions packages/models-library/tests/test_project_nodes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# pylint:disable=unused-variable
# pylint:disable=unused-argument
# pylint:disable=no-member
# pylint:disable=redefined-outer-name
# pylint:disable=unused-argument
# pylint:disable=unused-variable

from typing import Any

Loading

0 comments on commit f07afbf

Please sign in to comment.