Skip to content

Commit

Permalink
Uses typing_extensions.TypedDict in all instances used in pydantic mo…
Browse files Browse the repository at this point in the history
…dels AND fixes with migration of rest_ordering (#6770)
  • Loading branch information
pcrespov authored Nov 19, 2024
1 parent c50d79c commit 0aea337
Show file tree
Hide file tree
Showing 20 changed files with 80 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Makefile @pcrespov @sanderegg
/ci/ @sanderegg @pcrespov
/docs/ @pcrespov
/packages/common-library/ @giancarloromeo
/packages/models-library/ @sanderegg @pcrespov @matusdrobuliak66
/packages/models-library/ @sanderegg @pcrespov @matusdrobuliak66 @giancarloromeo
/packages/postgres-database/ @matusdrobuliak66
/packages/pytest-simcore/ @pcrespov @sanderegg
/packages/service-integration/ @pcrespov @sanderegg @GitHK
Expand Down
4 changes: 3 additions & 1 deletion packages/models-library/src/models_library/boot_options.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from pydantic import BaseModel, ConfigDict, ValidationInfo, field_validator
from typing_extensions import TypedDict
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

from .basic_types import EnvVarKey

Expand Down
4 changes: 3 additions & 1 deletion packages/models-library/src/models_library/projects_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

from pydantic import BaseModel, ConfigDict, Field, field_validator
from pydantic_extra_types.color import Color
from typing_extensions import TypedDict
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

from .projects_nodes_io import NodeID, NodeIDStr
from .projects_nodes_ui import Marker, Position
Expand Down
2 changes: 1 addition & 1 deletion packages/models-library/src/models_library/rest_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class RequestParameters(BaseModel):
"""

def as_params(self, **export_options) -> dict[str, str]:
data = self.dict(**export_options)
data = self.model_dump(**export_options)
return {k: f"{v}" for k, v in data.items()}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from math import ceil
from typing import Any, Protocol, runtime_checkable
from typing_extensions import TypedDict

from common_library.pydantic_networks_extension import AnyHttpUrlLegacy
from pydantic import TypeAdapter
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

from .rest_pagination import PageLinks, PageMetaInfoLimitOffset

Expand Down Expand Up @@ -70,7 +72,9 @@ def paginate_data(
"""
last_page = ceil(total / limit) - 1

data = [item.model_dump() if hasattr(item, "model_dump") else item for item in chunk]
data = [
item.model_dump() if hasattr(item, "model_dump") else item for item in chunk
]

return PageDict(
_meta=PageMetaInfoLimitOffset(
Expand Down
6 changes: 5 additions & 1 deletion packages/models-library/src/models_library/socketio.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from typing import Any, TypedDict
from typing import Any

from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)


class SocketMessageDict(TypedDict):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def parse_json_pre_validator(value: Any):
return json_loads(value)
except JSONDecodeError as err:
msg = f"Invalid JSON {value=}: {err}"
raise TypeError(msg) from err
raise ValueError(msg) from err
return value


Expand Down
19 changes: 19 additions & 0 deletions packages/models-library/tests/test_rest_ordering.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,22 @@ def test_ordering_query_model_with_map():
model = OrderQueryParamsModel.model_validate({"order_by": {"field": "modified"}})
assert model.order_by
assert model.order_by.field == "some_db_column_name"


def test_ordering_query_parse_json_pre_validator():

OrderQueryParamsModel = create_ordering_query_model_classes(
ordering_fields={"modified", "name"},
default=OrderBy(field=IDStr("modified"), direction=OrderDirection.DESC),
)

bad_json_value = ",invalid json"
with pytest.raises(ValidationError) as err_info:
OrderQueryParamsModel.model_validate({"order_by": bad_json_value})

exc = err_info.value
assert exc.error_count() == 1
error = exc.errors()[0]
assert error["loc"] == ("order_by",)
assert error["type"] == "value_error"
assert error["input"] == bad_json_value
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.sql import func
from typing_extensions import TypedDict
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

from .base import metadata
from .groups import groups
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
from collections.abc import Callable
from copy import deepcopy
from enum import Enum
from typing import Any, Protocol, TypedDict
from typing import Any, Protocol

import arrow
from aiohttp import web
from pydantic import TypeAdapter
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

from .application_keys import APP_CONFIG_KEY, APP_SETTINGS_KEY

Expand Down
6 changes: 5 additions & 1 deletion packages/service-library/src/servicelib/rest_constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# SEE https://pydantic-docs.helpmanual.io/usage/exporting_models/#modeldict

from typing import Final, TypedDict
from typing import Final

from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)


class PydanticExportParametersDict(TypedDict):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,9 @@ def test_parse_request_query_parameters_as_with_order_by_query_models():

expected = OrderBy(field="name", direction=OrderDirection.ASC)

url = URL("/test").with_query(order_by=expected.json())
url = URL("/test").with_query(order_by=expected.model_dump_json())

request = make_mocked_request("GET", path=f"{url}")

query_params = parse_request_query_parameters_as(OrderQueryModel, request)
assert query_params.order_by == expected
assert query_params.order_by.model_dump() == expected.model_dump()
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from models_library.users import UserID
from pydantic import BaseModel, ConfigDict, PositiveInt, field_validator
from simcore_postgres_database.models.comp_pipeline import StateType
from typing_extensions import TypedDict
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

from ..utils.db import DB_TO_RUNNING_STATE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
"""

import logging
from typing import TypedDict

import redis.asyncio as aioredis
from aiohttp import web
from models_library.basic_types import UUIDStr
from servicelib.redis_utils import handle_redis_returns_union_types
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

from ..redis import get_redis_resources_client
from ._constants import APP_CLIENT_SOCKET_REGISTRY_KEY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,13 @@
import asyncio
import inspect
from collections.abc import Awaitable, Callable
from typing import TypeAlias, TypedDict
from typing import TypeAlias

from aiohttp import web
from aiosignal import Signal
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

from .._constants import APP_SETTINGS_KEY

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
"""


from typing import TypedDict

from simcore_postgres_database.models.users import UserRole
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)


class PermissionDict(TypedDict, total=False):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
import time
from collections.abc import Iterator
from contextlib import contextmanager
from typing import Final, TypedDict
from typing import Final

from aiohttp import web
from aiohttp_session import Session
from pydantic import PositiveInt, validate_call
from servicelib.aiohttp import status
from servicelib.aiohttp.typing_extension import Handler
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

from .api import get_session
from .settings import SessionSettings, get_plugin_settings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
Typically dumped in statics.json
"""
from typing import Any, TypedDict
from typing import Any

import pycountry
from aiohttp import web
from models_library.utils.change_case import snake_to_camel
from pydantic import AliasChoices, AnyHttpUrl, Field, TypeAdapter
from settings_library.base import BaseCustomSettings
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

from .._constants import APP_SETTINGS_KEY

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import logging
from typing import TypedDict

import sqlalchemy as sa
from aiohttp import web
from models_library.projects import ProjectID, ProjectIDStr
from pydantic import HttpUrl, TypeAdapter
from simcore_postgres_database.models.project_to_groups import project_to_groups
from simcore_postgres_database.models.projects import ProjectType, projects
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

from ..db.plugin import get_database_engine
from ..projects.api import ProjectPermalink, register_permalink_factory
Expand Down
4 changes: 3 additions & 1 deletion services/web/server/src/simcore_service_webserver/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
import orjson
from common_library.error_codes import ErrorCodeStr
from models_library.basic_types import SHA1Str
from typing_extensions import TypedDict
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
TypedDict,
)

_CURRENT_DIR = (
Path(sys.argv[0] if __name__ == "__main__" else __file__).resolve().parent
Expand Down

0 comments on commit 0aea337

Please sign in to comment.