diff --git a/services/cost/oas_commit b/services/cost/oas_commit index c08a6770d..72dcff29c 100644 --- a/services/cost/oas_commit +++ b/services/cost/oas_commit @@ -1 +1 @@ -4407196dbbef4e53e6798809e856725cbc84ae05 +0867dbbb09a8032415dc6debe18bc392bd58ba42 diff --git a/services/cost/src/stackit/cost/api_client.py b/services/cost/src/stackit/cost/api_client.py index 7a8345ca7..db3c9dc21 100644 --- a/services/cost/src/stackit/cost/api_client.py +++ b/services/cost/src/stackit/cost/api_client.py @@ -66,6 +66,7 @@ class ApiClient: "date": datetime.date, "datetime": datetime.datetime, "decimal": decimal.Decimal, + "UUID": uuid.UUID, "object": object, } _pool = None @@ -265,7 +266,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) @@ -326,25 +327,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. @@ -417,6 +413,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/cost/src/stackit/cost/models/auth_error_response.py b/services/cost/src/stackit/cost/models/auth_error_response.py index d1ec0e1ea..dc594c883 100644 --- a/services/cost/src/stackit/cost/models/auth_error_response.py +++ b/services/cost/src/stackit/cost/models/auth_error_response.py @@ -20,6 +20,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic_core import to_jsonable_python from typing_extensions import Self @@ -49,7 +50,8 @@ def time_stamp_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=(), ) @@ -60,8 +62,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/cost/src/stackit/cost/models/detailed_service_cost.py b/services/cost/src/stackit/cost/models/detailed_service_cost.py index 3fa4f8efc..db2b30fe1 100644 --- a/services/cost/src/stackit/cost/models/detailed_service_cost.py +++ b/services/cost/src/stackit/cost/models/detailed_service_cost.py @@ -24,6 +24,7 @@ StrictFloat, StrictInt, ) +from pydantic_core import to_jsonable_python from typing_extensions import Annotated, Self from stackit.cost.models.report_data import ReportData @@ -70,7 +71,8 @@ class DetailedServiceCost(BaseModel): ] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -81,8 +83,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/cost/src/stackit/cost/models/error_response.py b/services/cost/src/stackit/cost/models/error_response.py index f05bfab59..0a826d55d 100644 --- a/services/cost/src/stackit/cost/models/error_response.py +++ b/services/cost/src/stackit/cost/models/error_response.py @@ -18,6 +18,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 @@ -30,7 +31,8 @@ class ErrorResponse(BaseModel): __properties: ClassVar[List[str]] = ["msg"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -41,8 +43,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/cost/src/stackit/cost/models/project_cost_with_detailed_services.py b/services/cost/src/stackit/cost/models/project_cost_with_detailed_services.py index da95923a7..1c1877c3a 100644 --- a/services/cost/src/stackit/cost/models/project_cost_with_detailed_services.py +++ b/services/cost/src/stackit/cost/models/project_cost_with_detailed_services.py @@ -26,6 +26,7 @@ StrictInt, StrictStr, ) +from pydantic_core import to_jsonable_python from typing_extensions import Self from stackit.cost.models.detailed_service_cost import DetailedServiceCost @@ -61,7 +62,8 @@ class ProjectCostWithDetailedServices(BaseModel): ] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -72,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/cost/src/stackit/cost/models/project_cost_with_reports.py b/services/cost/src/stackit/cost/models/project_cost_with_reports.py index 5ecc6ce56..8d6c4d191 100644 --- a/services/cost/src/stackit/cost/models/project_cost_with_reports.py +++ b/services/cost/src/stackit/cost/models/project_cost_with_reports.py @@ -26,6 +26,7 @@ StrictInt, StrictStr, ) +from pydantic_core import to_jsonable_python from typing_extensions import Self from stackit.cost.models.report_data import ReportData @@ -62,7 +63,8 @@ class ProjectCostWithReports(BaseModel): ] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -73,8 +75,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/cost/src/stackit/cost/models/project_cost_with_summarized_services.py b/services/cost/src/stackit/cost/models/project_cost_with_summarized_services.py index 7d6bab9f4..fedeeb08f 100644 --- a/services/cost/src/stackit/cost/models/project_cost_with_summarized_services.py +++ b/services/cost/src/stackit/cost/models/project_cost_with_summarized_services.py @@ -26,6 +26,7 @@ StrictInt, StrictStr, ) +from pydantic_core import to_jsonable_python from typing_extensions import Self from stackit.cost.models.summarized_service_cost import SummarizedServiceCost @@ -58,7 +59,8 @@ class ProjectCostWithSummarizedServices(BaseModel): ] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -69,8 +71,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/cost/src/stackit/cost/models/report_data.py b/services/cost/src/stackit/cost/models/report_data.py index b230abe84..237e820fa 100644 --- a/services/cost/src/stackit/cost/models/report_data.py +++ b/services/cost/src/stackit/cost/models/report_data.py @@ -24,6 +24,7 @@ StrictFloat, StrictInt, ) +from pydantic_core import to_jsonable_python from typing_extensions import Self from stackit.cost.models.report_data_time_period import ReportDataTimePeriod @@ -41,7 +42,8 @@ class ReportData(BaseModel): __properties: ClassVar[List[str]] = ["charge", "discount", "quantity", "timePeriod"] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -52,8 +54,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/cost/src/stackit/cost/models/report_data_time_period.py b/services/cost/src/stackit/cost/models/report_data_time_period.py index 9ed32be13..c39a80231 100644 --- a/services/cost/src/stackit/cost/models/report_data_time_period.py +++ b/services/cost/src/stackit/cost/models/report_data_time_period.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set from pydantic import BaseModel, ConfigDict +from pydantic_core import to_jsonable_python from typing_extensions import Self @@ -32,7 +33,8 @@ class ReportDataTimePeriod(BaseModel): __properties: ClassVar[List[str]] = ["end", "start"] 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/cost/src/stackit/cost/models/summarized_project_cost.py b/services/cost/src/stackit/cost/models/summarized_project_cost.py index 10ed44878..2de458c73 100644 --- a/services/cost/src/stackit/cost/models/summarized_project_cost.py +++ b/services/cost/src/stackit/cost/models/summarized_project_cost.py @@ -26,6 +26,7 @@ StrictInt, StrictStr, ) +from pydantic_core import to_jsonable_python from typing_extensions import Self @@ -54,7 +55,8 @@ class SummarizedProjectCost(BaseModel): ] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -65,8 +67,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/cost/src/stackit/cost/models/summarized_service_cost.py b/services/cost/src/stackit/cost/models/summarized_service_cost.py index 3da6db3f5..7b368498e 100644 --- a/services/cost/src/stackit/cost/models/summarized_service_cost.py +++ b/services/cost/src/stackit/cost/models/summarized_service_cost.py @@ -26,6 +26,7 @@ StrictInt, StrictStr, ) +from pydantic_core import to_jsonable_python from typing_extensions import Self @@ -54,7 +55,8 @@ class SummarizedServiceCost(BaseModel): ] model_config = ConfigDict( - populate_by_name=True, + validate_by_name=True, + validate_by_alias=True, validate_assignment=True, protected_namespaces=(), ) @@ -65,8 +67,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]: