diff --git a/services/modelserving/oas_commit b/services/modelserving/oas_commit index e3713dde3..72dcff29c 100644 --- a/services/modelserving/oas_commit +++ b/services/modelserving/oas_commit @@ -1 +1 @@ -0e64886dd0847341800d7191ed193b75413be998 +0867dbbb09a8032415dc6debe18bc392bd58ba42 diff --git a/services/modelserving/src/stackit/modelserving/api_client.py b/services/modelserving/src/stackit/modelserving/api_client.py index b0dfa8cfe..faf3a2be8 100644 --- a/services/modelserving/src/stackit/modelserving/api_client.py +++ b/services/modelserving/src/stackit/modelserving/api_client.py @@ -67,6 +67,7 @@ class ApiClient: "date": datetime.date, "datetime": datetime.datetime, "decimal": decimal.Decimal, + "UUID": uuid.UUID, "object": object, } _pool = None @@ -266,7 +267,7 @@ def response_deserialize( response_text = None return_data = None try: - if response_type == "bytearray": + if response_type in ("bytearray", "bytes"): return_data = response_data.data elif response_type == "file": return_data = self.__deserialize_file(response_data) @@ -327,25 +328,20 @@ def sanitize_for_serialization(self, obj): return obj.isoformat() elif isinstance(obj, decimal.Decimal): return str(obj) - elif isinstance(obj, dict): - obj_dict = obj + return {key: self.sanitize_for_serialization(val) for key, val in obj.items()} + + # Convert model obj to dict except + # attributes `openapi_types`, `attribute_map` + # and attributes which value is not None. + # Convert attribute name to json key in + # model definition for request. + if hasattr(obj, "to_dict") and callable(getattr(obj, "to_dict")): + obj_dict = obj.to_dict() else: - # Convert model obj to dict except - # attributes `openapi_types`, `attribute_map` - # and attributes which value is not None. - # Convert attribute name to json key in - # model definition for request. - if hasattr(obj, "to_dict") and callable(getattr(obj, "to_dict")): # noqa: B009 - obj_dict = obj.to_dict() - else: - obj_dict = obj.__dict__ - - if isinstance(obj_dict, list): - # here we handle instances that can either be a list or something else, and only became a real list by calling to_dict() # noqa: E501 - return self.sanitize_for_serialization(obj_dict) + obj_dict = obj.__dict__ - return {key: self.sanitize_for_serialization(val) for key, val in obj_dict.items()} + return self.sanitize_for_serialization(obj_dict) def deserialize(self, response_text: str, response_type: str, content_type: Optional[str]): """Deserializes response into an object. @@ -418,6 +414,8 @@ def __deserialize(self, data, klass): return self.__deserialize_datetime(data) elif klass is decimal.Decimal: return decimal.Decimal(data) + elif klass is uuid.UUID: + return uuid.UUID(data) elif issubclass(klass, Enum): return self.__deserialize_enum(data, klass) else: diff --git a/services/modelserving/src/stackit/modelserving/models/chat_model_details.py b/services/modelserving/src/stackit/modelserving/models/chat_model_details.py index 06cba434c..56045ce21 100644 --- a/services/modelserving/src/stackit/modelserving/models/chat_model_details.py +++ b/services/modelserving/src/stackit/modelserving/models/chat_model_details.py @@ -21,6 +21,7 @@ from uuid import UUID from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic_core import to_jsonable_python from typing_extensions import Annotated, Self from stackit.modelserving.models.sku import SKU @@ -80,6 +81,9 @@ def category_validate_enum(cls, value): @field_validator("description") def description_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s.:\/\-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s.:\/\-]+$/") return value @@ -87,6 +91,9 @@ def description_validate_regular_expression(cls, value): @field_validator("displayed_name") def displayed_name_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s_-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s_-]+$/") return value @@ -94,6 +101,9 @@ def displayed_name_validate_regular_expression(cls, value): @field_validator("name") def name_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s.:\/\-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s.:\/\-]+$/") return value @@ -111,12 +121,16 @@ def quantization_method_validate_enum(cls, value): @field_validator("url") def url_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s.:\/\-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s.:\/\-]+$/") return value model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -127,8 +141,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/create_token_payload.py b/services/modelserving/src/stackit/modelserving/models/create_token_payload.py index 45fa1425a..ce99cccc5 100644 --- a/services/modelserving/src/stackit/modelserving/models/create_token_payload.py +++ b/services/modelserving/src/stackit/modelserving/models/create_token_payload.py @@ -20,6 +20,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from pydantic_core import to_jsonable_python from typing_extensions import Annotated, Self @@ -43,6 +44,9 @@ def description_validate_regular_expression(cls, value): if value is None: return value + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s.:\/\-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s.:\/\-]+$/") return value @@ -50,12 +54,16 @@ def description_validate_regular_expression(cls, value): @field_validator("name") def name_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s_-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s_-]+$/") return value model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -66,8 +74,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/create_token_response.py b/services/modelserving/src/stackit/modelserving/models/create_token_response.py index cbcda46bb..716ff126c 100644 --- a/services/modelserving/src/stackit/modelserving/models/create_token_response.py +++ b/services/modelserving/src/stackit/modelserving/models/create_token_response.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic_core import to_jsonable_python from typing_extensions import Self from stackit.modelserving.models.token_created import TokenCreated @@ -34,7 +35,8 @@ class CreateTokenResponse(BaseModel): __properties: ClassVar[List[str]] = ["message", "token"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -45,8 +47,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/embedding_model_details.py b/services/modelserving/src/stackit/modelserving/models/embedding_model_details.py index e83acd824..561d8268b 100644 --- a/services/modelserving/src/stackit/modelserving/models/embedding_model_details.py +++ b/services/modelserving/src/stackit/modelserving/models/embedding_model_details.py @@ -21,6 +21,7 @@ from uuid import UUID from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic_core import to_jsonable_python from typing_extensions import Annotated, Self from stackit.modelserving.models.sku import SKU @@ -64,6 +65,9 @@ def category_validate_enum(cls, value): @field_validator("description") def description_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s.:\/\-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s.:\/\-]+$/") return value @@ -71,6 +75,9 @@ def description_validate_regular_expression(cls, value): @field_validator("displayed_name") def displayed_name_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s_-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s_-]+$/") return value @@ -78,6 +85,9 @@ def displayed_name_validate_regular_expression(cls, value): @field_validator("name") def name_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s.:\/\-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s.:\/\-]+$/") return value @@ -85,12 +95,16 @@ def name_validate_regular_expression(cls, value): @field_validator("url") def url_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s.:\/\-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s.:\/\-]+$/") return value model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -101,8 +115,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/error_message_response.py b/services/modelserving/src/stackit/modelserving/models/error_message_response.py index 381da810f..565ed24ca 100644 --- a/services/modelserving/src/stackit/modelserving/models/error_message_response.py +++ b/services/modelserving/src/stackit/modelserving/models/error_message_response.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic_core import to_jsonable_python from typing_extensions import Self @@ -32,7 +33,8 @@ class ErrorMessageResponse(BaseModel): __properties: ClassVar[List[str]] = ["error", "message"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -43,8 +45,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/get_chat_model_response.py b/services/modelserving/src/stackit/modelserving/models/get_chat_model_response.py index 100e28437..8cddfce17 100644 --- a/services/modelserving/src/stackit/modelserving/models/get_chat_model_response.py +++ b/services/modelserving/src/stackit/modelserving/models/get_chat_model_response.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic_core import to_jsonable_python from typing_extensions import Self from stackit.modelserving.models.chat_model_details import ChatModelDetails @@ -34,7 +35,8 @@ class GetChatModelResponse(BaseModel): __properties: ClassVar[List[str]] = ["message", "model"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -45,8 +47,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/get_embeddings_model_resp.py b/services/modelserving/src/stackit/modelserving/models/get_embeddings_model_resp.py index faf5ccc1e..b86028255 100644 --- a/services/modelserving/src/stackit/modelserving/models/get_embeddings_model_resp.py +++ b/services/modelserving/src/stackit/modelserving/models/get_embeddings_model_resp.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic_core import to_jsonable_python from typing_extensions import Self from stackit.modelserving.models.embedding_model_details import EmbeddingModelDetails @@ -34,7 +35,8 @@ class GetEmbeddingsModelResp(BaseModel): __properties: ClassVar[List[str]] = ["message", "model"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -45,8 +47,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/get_token_response.py b/services/modelserving/src/stackit/modelserving/models/get_token_response.py index e60afca93..b769b2ddb 100644 --- a/services/modelserving/src/stackit/modelserving/models/get_token_response.py +++ b/services/modelserving/src/stackit/modelserving/models/get_token_response.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic_core import to_jsonable_python from typing_extensions import Self from stackit.modelserving.models.token import Token @@ -34,7 +35,8 @@ class GetTokenResponse(BaseModel): __properties: ClassVar[List[str]] = ["message", "token"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -45,8 +47,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/list_models_response.py b/services/modelserving/src/stackit/modelserving/models/list_models_response.py index 7a9c5e880..135b6ebb2 100644 --- a/services/modelserving/src/stackit/modelserving/models/list_models_response.py +++ b/services/modelserving/src/stackit/modelserving/models/list_models_response.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic_core import to_jsonable_python from typing_extensions import Self from stackit.modelserving.models.model import Model @@ -34,7 +35,8 @@ class ListModelsResponse(BaseModel): __properties: ClassVar[List[str]] = ["message", "models"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -45,8 +47,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/list_token_resp.py b/services/modelserving/src/stackit/modelserving/models/list_token_resp.py index 678c57d68..6603373d6 100644 --- a/services/modelserving/src/stackit/modelserving/models/list_token_resp.py +++ b/services/modelserving/src/stackit/modelserving/models/list_token_resp.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic_core import to_jsonable_python from typing_extensions import Self from stackit.modelserving.models.token import Token @@ -34,7 +35,8 @@ class ListTokenResp(BaseModel): __properties: ClassVar[List[str]] = ["message", "tokens"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -45,8 +47,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/message_response.py b/services/modelserving/src/stackit/modelserving/models/message_response.py index 64e49b5ed..bf0f9a8a7 100644 --- a/services/modelserving/src/stackit/modelserving/models/message_response.py +++ b/services/modelserving/src/stackit/modelserving/models/message_response.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic_core import to_jsonable_python from typing_extensions import Self @@ -31,7 +32,8 @@ class MessageResponse(BaseModel): __properties: ClassVar[List[str]] = ["message"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -42,8 +44,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/model.py b/services/modelserving/src/stackit/modelserving/models/model.py index 8018d86fe..b2d45ac16 100644 --- a/services/modelserving/src/stackit/modelserving/models/model.py +++ b/services/modelserving/src/stackit/modelserving/models/model.py @@ -21,6 +21,7 @@ from uuid import UUID from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from pydantic_core import to_jsonable_python from typing_extensions import Annotated, Self from stackit.modelserving.models.sku import SKU @@ -64,6 +65,9 @@ def category_validate_enum(cls, value): @field_validator("description") def description_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s.:\/\-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s.:\/\-]+$/") return value @@ -71,6 +75,9 @@ def description_validate_regular_expression(cls, value): @field_validator("displayed_name") def displayed_name_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s_-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s_-]+$/") return value @@ -83,7 +90,8 @@ def type_validate_enum(cls, value): return value model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -94,8 +102,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/partial_update_token_payload.py b/services/modelserving/src/stackit/modelserving/models/partial_update_token_payload.py index 50315194b..b21f6193e 100644 --- a/services/modelserving/src/stackit/modelserving/models/partial_update_token_payload.py +++ b/services/modelserving/src/stackit/modelserving/models/partial_update_token_payload.py @@ -20,6 +20,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, Field, field_validator +from pydantic_core import to_jsonable_python from typing_extensions import Annotated, Self @@ -38,6 +39,9 @@ def description_validate_regular_expression(cls, value): if value is None: return value + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s.:\/\-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s.:\/\-]+$/") return value @@ -48,12 +52,16 @@ def name_validate_regular_expression(cls, value): if value is None: return value + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s_-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s_-]+$/") return value model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -64,8 +72,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/sku.py b/services/modelserving/src/stackit/modelserving/models/sku.py index ef5a56d51..e92ee21a6 100644 --- a/services/modelserving/src/stackit/modelserving/models/sku.py +++ b/services/modelserving/src/stackit/modelserving/models/sku.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic_core import to_jsonable_python from typing_extensions import Self @@ -33,7 +34,8 @@ class SKU(BaseModel): __properties: ClassVar[List[str]] = ["description", "id", "type"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -44,8 +46,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/token.py b/services/modelserving/src/stackit/modelserving/models/token.py index 62b055753..fe06db148 100644 --- a/services/modelserving/src/stackit/modelserving/models/token.py +++ b/services/modelserving/src/stackit/modelserving/models/token.py @@ -22,6 +22,7 @@ from uuid import UUID from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from pydantic_core import to_jsonable_python from typing_extensions import Annotated, Self @@ -44,6 +45,9 @@ def description_validate_regular_expression(cls, value): if value is None: return value + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s.:\/\-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s.:\/\-]+$/") return value @@ -51,6 +55,9 @@ def description_validate_regular_expression(cls, value): @field_validator("name") def name_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s_-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s_-]+$/") return value @@ -76,7 +83,8 @@ def valid_until_change_year_zero_to_one(cls, value): return value model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -87,8 +95,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/token_created.py b/services/modelserving/src/stackit/modelserving/models/token_created.py index 3984b297b..4de56d8aa 100644 --- a/services/modelserving/src/stackit/modelserving/models/token_created.py +++ b/services/modelserving/src/stackit/modelserving/models/token_created.py @@ -22,6 +22,7 @@ from uuid import UUID from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from pydantic_core import to_jsonable_python from typing_extensions import Annotated, Self @@ -42,6 +43,9 @@ class TokenCreated(BaseModel): @field_validator("content") def content_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s_-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s_-]+$/") return value @@ -52,6 +56,9 @@ def description_validate_regular_expression(cls, value): if value is None: return value + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s.:\/\-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s.:\/\-]+$/") return value @@ -59,6 +66,9 @@ def description_validate_regular_expression(cls, value): @field_validator("name") def name_validate_regular_expression(cls, value): """Validates the regular expression""" + if not isinstance(value, str): + value = str(value) + if not re.match(r"^[0-9a-zA-Z\s_-]+$", value): raise ValueError(r"must validate the regular expression /^[0-9a-zA-Z\s_-]+$/") return value @@ -84,7 +94,8 @@ def valid_until_change_year_zero_to_one(cls, value): return value model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -95,8 +106,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: diff --git a/services/modelserving/src/stackit/modelserving/models/update_token_response.py b/services/modelserving/src/stackit/modelserving/models/update_token_response.py index 7a649c5de..fe11beb86 100644 --- a/services/modelserving/src/stackit/modelserving/models/update_token_response.py +++ b/services/modelserving/src/stackit/modelserving/models/update_token_response.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic_core import to_jsonable_python from typing_extensions import Self from stackit.modelserving.models.token import Token @@ -34,7 +35,8 @@ class UpdateTokenResponse(BaseModel): __properties: ClassVar[List[str]] = ["message", "token"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -45,8 +47,7 @@ def to_str(self) -> str: def to_json(self) -> str: """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + return json.dumps(to_jsonable_python(self.to_dict())) @classmethod def from_json(cls, json_str: str) -> Optional[Self]: