From 3d161198619d08c92475d12cebefe9e6e5b1c820 Mon Sep 17 00:00:00 2001 From: BinoyOza-okta Date: Wed, 18 Mar 2026 18:38:54 +0530 Subject: [PATCH] fix: Correct EmailDomain model field deserialization Fix OpenAPI spec indentation causing EmailDomainResponse, EmailDomainResponseWithEmbedded and EmailDomain to drop 5-7 fields during deserialization. API responses now include all fields: id, domain, validationStatus, dnsValidationRecords, etc. Fixed incorrect YAML indentation in allOf composition that prevented OpenAPI generator from processing properties beyond BaseEmailDomain. Fixes: OKTA-1133517 --- docs/EmailDomain.md | 4 +- docs/EmailDomainResponse.md | 4 +- docs/EmailDomainResponseWithEmbedded.md | 6 +- ...DomainResponseWithEmbeddedAllOfEmbedded.md | 29 +++++ okta/__init__.py | 1 + okta/models/__init__.py | 1 + okta/models/email_domain.py | 24 +++- okta/models/email_domain_response.py | 42 ++++++- .../email_domain_response_with_embedded.py | 41 ++++--- ..._response_with_embedded_all_of_embedded.py | 109 ++++++++++++++++++ openapi/api.yaml | 70 +++++------ 11 files changed, 268 insertions(+), 63 deletions(-) create mode 100644 docs/EmailDomainResponseWithEmbeddedAllOfEmbedded.md create mode 100644 okta/models/email_domain_response_with_embedded_all_of_embedded.py diff --git a/docs/EmailDomain.md b/docs/EmailDomain.md index d3e205d6..baa56770 100644 --- a/docs/EmailDomain.md +++ b/docs/EmailDomain.md @@ -5,11 +5,11 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**display_name** | **str** | | +**user_name** | **str** | | **brand_id** | **str** | | **domain** | **str** | | **validation_subdomain** | **str** | Subdomain for the email sender's custom mail domain. Specify your subdomain when you configure a custom mail domain. | [optional] [default to 'mail'] -**display_name** | **str** | | -**user_name** | **str** | | ## Example diff --git a/docs/EmailDomainResponse.md b/docs/EmailDomainResponse.md index fbf33776..6c419553 100644 --- a/docs/EmailDomainResponse.md +++ b/docs/EmailDomainResponse.md @@ -5,13 +5,13 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**display_name** | **str** | | +**user_name** | **str** | | **dns_validation_records** | [**List[EmailDomainDNSRecord]**](EmailDomainDNSRecord.md) | | [optional] **domain** | **str** | | [optional] **id** | **str** | | [optional] **validation_status** | [**EmailDomainStatus**](EmailDomainStatus.md) | | [optional] **validation_subdomain** | **str** | The subdomain for the email sender's custom mail domain | [optional] [default to 'mail'] -**display_name** | **str** | | -**user_name** | **str** | | ## Example diff --git a/docs/EmailDomainResponseWithEmbedded.md b/docs/EmailDomainResponseWithEmbedded.md index 2fe403ff..6caa2b46 100644 --- a/docs/EmailDomainResponseWithEmbedded.md +++ b/docs/EmailDomainResponseWithEmbedded.md @@ -5,14 +5,14 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**embedded** | **object** | | [optional] [readonly] +**display_name** | **str** | | +**user_name** | **str** | | **dns_validation_records** | [**List[EmailDomainDNSRecord]**](EmailDomainDNSRecord.md) | | [optional] **domain** | **str** | | [optional] **id** | **str** | | [optional] **validation_status** | [**EmailDomainStatus**](EmailDomainStatus.md) | | [optional] **validation_subdomain** | **str** | The subdomain for the email sender's custom mail domain | [optional] [default to 'mail'] -**display_name** | **str** | | -**user_name** | **str** | | +**embedded** | [**EmailDomainResponseWithEmbeddedAllOfEmbedded**](EmailDomainResponseWithEmbeddedAllOfEmbedded.md) | | [optional] ## Example diff --git a/docs/EmailDomainResponseWithEmbeddedAllOfEmbedded.md b/docs/EmailDomainResponseWithEmbeddedAllOfEmbedded.md new file mode 100644 index 00000000..314c2058 --- /dev/null +++ b/docs/EmailDomainResponseWithEmbeddedAllOfEmbedded.md @@ -0,0 +1,29 @@ +# EmailDomainResponseWithEmbeddedAllOfEmbedded + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**brands** | [**List[Brand]**](Brand.md) | | [optional] + +## Example + +```python +from okta.models.email_domain_response_with_embedded_all_of_embedded import EmailDomainResponseWithEmbeddedAllOfEmbedded + +# TODO update the JSON string below +json = "{}" +# create an instance of EmailDomainResponseWithEmbeddedAllOfEmbedded from a JSON string +email_domain_response_with_embedded_all_of_embedded_instance = EmailDomainResponseWithEmbeddedAllOfEmbedded.from_json(json) +# print the JSON string representation of the object +print(EmailDomainResponseWithEmbeddedAllOfEmbedded.to_json()) + +# convert the object into a dict +email_domain_response_with_embedded_all_of_embedded_dict = email_domain_response_with_embedded_all_of_embedded_instance.to_dict() +# create an instance of EmailDomainResponseWithEmbeddedAllOfEmbedded from a dict +email_domain_response_with_embedded_all_of_embedded_from_dict = EmailDomainResponseWithEmbeddedAllOfEmbedded.from_dict(email_domain_response_with_embedded_all_of_embedded_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/okta/__init__.py b/okta/__init__.py index 7df9e24e..e7774a84 100644 --- a/okta/__init__.py +++ b/okta/__init__.py @@ -651,6 +651,7 @@ "EmailDomainDNSRecordType": "okta.models.email_domain_dns_record_type", "EmailDomainResponse": "okta.models.email_domain_response", "EmailDomainResponseWithEmbedded": "okta.models.email_domain_response_with_embedded", + "EmailDomainResponseWithEmbeddedAllOfEmbedded": "okta.models.email_domain_response_with_embedded_all_of_embedded", "EmailDomainStatus": "okta.models.email_domain_status", "EmailPreview": "okta.models.email_preview", "EmailPreviewLinks": "okta.models.email_preview_links", diff --git a/okta/models/__init__.py b/okta/models/__init__.py index b58eaaa2..e15c879f 100644 --- a/okta/models/__init__.py +++ b/okta/models/__init__.py @@ -852,6 +852,7 @@ "EmailDomainDNSRecordType": "okta.models.email_domain_dns_record_type", "EmailDomainResponse": "okta.models.email_domain_response", "EmailDomainResponseWithEmbedded": "okta.models.email_domain_response_with_embedded", + "EmailDomainResponseWithEmbeddedAllOfEmbedded": "okta.models.email_domain_response_with_embedded_all_of_embedded", "EmailDomainStatus": "okta.models.email_domain_status", "EmailPreview": "okta.models.email_preview", "EmailPreviewLinks": "okta.models.email_preview_links", diff --git a/okta/models/email_domain.py b/okta/models/email_domain.py index 1e84e5c4..b46625ea 100644 --- a/okta/models/email_domain.py +++ b/okta/models/email_domain.py @@ -37,6 +37,8 @@ class EmailDomain(BaseModel): EmailDomain """ # noqa: E501 + display_name: StrictStr = Field(alias="displayName") + user_name: StrictStr = Field(alias="userName") brand_id: StrictStr = Field(alias="brandId") domain: StrictStr validation_subdomain: Optional[StrictStr] = Field( @@ -45,9 +47,13 @@ class EmailDomain(BaseModel): "mail domain.", alias="validationSubdomain", ) - display_name: StrictStr = Field(alias="displayName") - user_name: StrictStr = Field(alias="userName") - __properties: ClassVar[List[str]] = ["displayName", "userName"] + __properties: ClassVar[List[str]] = [ + "displayName", + "userName", + "brandId", + "domain", + "validationSubdomain", + ] model_config = ConfigDict( populate_by_name=True, @@ -98,6 +104,16 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: return cls.model_validate(obj) _obj = cls.model_validate( - {"displayName": obj.get("displayName"), "userName": obj.get("userName")} + { + "displayName": obj.get("displayName"), + "userName": obj.get("userName"), + "brandId": obj.get("brandId"), + "domain": obj.get("domain"), + "validationSubdomain": ( + obj.get("validationSubdomain") + if obj.get("validationSubdomain") is not None + else "mail" + ), + } ) return _obj diff --git a/okta/models/email_domain_response.py b/okta/models/email_domain_response.py index 502846eb..fb578ea5 100644 --- a/okta/models/email_domain_response.py +++ b/okta/models/email_domain_response.py @@ -40,6 +40,8 @@ class EmailDomainResponse(BaseModel): EmailDomainResponse """ # noqa: E501 + display_name: StrictStr = Field(alias="displayName") + user_name: StrictStr = Field(alias="userName") dns_validation_records: Optional[List[EmailDomainDNSRecord]] = Field( default=None, alias="dnsValidationRecords" ) @@ -53,9 +55,15 @@ class EmailDomainResponse(BaseModel): description="The subdomain for the email sender's custom mail domain", alias="validationSubdomain", ) - display_name: StrictStr = Field(alias="displayName") - user_name: StrictStr = Field(alias="userName") - __properties: ClassVar[List[str]] = ["displayName", "userName"] + __properties: ClassVar[List[str]] = [ + "displayName", + "userName", + "dnsValidationRecords", + "domain", + "id", + "validationStatus", + "validationSubdomain", + ] model_config = ConfigDict( populate_by_name=True, @@ -94,6 +102,13 @@ def to_dict(self) -> Dict[str, Any]: exclude=excluded_fields, exclude_none=True, ) + # override the default output from pydantic by calling `to_dict()` of each item in dns_validation_records (list) + _items = [] + if self.dns_validation_records: + for _item in self.dns_validation_records: + if _item: + _items.append(_item.to_dict()) + _dict["dnsValidationRecords"] = _items return _dict @classmethod @@ -106,6 +121,25 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: return cls.model_validate(obj) _obj = cls.model_validate( - {"displayName": obj.get("displayName"), "userName": obj.get("userName")} + { + "displayName": obj.get("displayName"), + "userName": obj.get("userName"), + "dnsValidationRecords": ( + [ + EmailDomainDNSRecord.from_dict(_item) + for _item in obj["dnsValidationRecords"] + ] + if obj.get("dnsValidationRecords") is not None + else None + ), + "domain": obj.get("domain"), + "id": obj.get("id"), + "validationStatus": obj.get("validationStatus"), + "validationSubdomain": ( + obj.get("validationSubdomain") + if obj.get("validationSubdomain") is not None + else "mail" + ), + } ) return _obj diff --git a/okta/models/email_domain_response_with_embedded.py b/okta/models/email_domain_response_with_embedded.py index 0ecb3820..7466ca14 100644 --- a/okta/models/email_domain_response_with_embedded.py +++ b/okta/models/email_domain_response_with_embedded.py @@ -32,6 +32,9 @@ from typing_extensions import Self from okta.models.email_domain_dns_record import EmailDomainDNSRecord +from okta.models.email_domain_response_with_embedded_all_of_embedded import ( + EmailDomainResponseWithEmbeddedAllOfEmbedded, +) from okta.models.email_domain_status import EmailDomainStatus @@ -40,7 +43,8 @@ class EmailDomainResponseWithEmbedded(BaseModel): EmailDomainResponseWithEmbedded """ # noqa: E501 - embedded: Optional[object] = Field(default=None, alias="_embedded") + display_name: StrictStr = Field(alias="displayName") + user_name: StrictStr = Field(alias="userName") dns_validation_records: Optional[List[EmailDomainDNSRecord]] = Field( default=None, alias="dnsValidationRecords" ) @@ -54,16 +58,18 @@ class EmailDomainResponseWithEmbedded(BaseModel): description="The subdomain for the email sender's custom mail domain", alias="validationSubdomain", ) - display_name: StrictStr = Field(alias="displayName") - user_name: StrictStr = Field(alias="userName") + embedded: Optional[EmailDomainResponseWithEmbeddedAllOfEmbedded] = Field( + default=None, alias="_embedded" + ) __properties: ClassVar[List[str]] = [ + "displayName", + "userName", "dnsValidationRecords", "domain", "id", "validationStatus", "validationSubdomain", - "displayName", - "userName", + "_embedded", ] model_config = ConfigDict( @@ -95,13 +101,8 @@ def to_dict(self) -> Dict[str, Any]: * `None` is only added to the output dict for nullable fields that were set at model initialization. Other fields with value `None` are ignored. - * OpenAPI `readOnly` fields are excluded. """ - excluded_fields: Set[str] = set( - [ - "embedded", - ] - ) + excluded_fields: Set[str] = set([]) _dict = self.model_dump( by_alias=True, @@ -115,6 +116,13 @@ def to_dict(self) -> Dict[str, Any]: if _item: _items.append(_item.to_dict()) _dict["dnsValidationRecords"] = _items + # override the default output from pydantic by calling `to_dict()` of embedded + if self.embedded: + if not isinstance(self.embedded, dict): + _dict["_embedded"] = self.embedded.to_dict() + else: + _dict["_embedded"] = self.embedded + return _dict @classmethod @@ -128,6 +136,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate( { + "displayName": obj.get("displayName"), + "userName": obj.get("userName"), "dnsValidationRecords": ( [ EmailDomainDNSRecord.from_dict(_item) @@ -144,8 +154,13 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if obj.get("validationSubdomain") is not None else "mail" ), - "displayName": obj.get("displayName"), - "userName": obj.get("userName"), + "_embedded": ( + EmailDomainResponseWithEmbeddedAllOfEmbedded.from_dict( + obj["_embedded"] + ) + if obj.get("_embedded") is not None + else None + ), } ) return _obj diff --git a/okta/models/email_domain_response_with_embedded_all_of_embedded.py b/okta/models/email_domain_response_with_embedded_all_of_embedded.py new file mode 100644 index 00000000..a9819aff --- /dev/null +++ b/okta/models/email_domain_response_with_embedded_all_of_embedded.py @@ -0,0 +1,109 @@ +# The Okta software accompanied by this notice is provided pursuant to the following terms: +# Copyright © 2025-Present, Okta, Inc. +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the +# License. +# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS +# IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and limitations under the License. +# coding: utf-8 + +""" +Okta Admin Management + +Allows customers to easily access the Okta Management APIs + +The version of the OpenAPI document: 5.1.0 +Contact: devex-public@okta.com +Generated by OpenAPI Generator (https://openapi-generator.tech) + +Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +import pprint +import re # noqa: F401 +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set + +from pydantic import BaseModel, ConfigDict +from typing_extensions import Self + +from okta.models.brand import Brand + + +class EmailDomainResponseWithEmbeddedAllOfEmbedded(BaseModel): + """ + EmailDomainResponseWithEmbeddedAllOfEmbedded + """ # noqa: E501 + + brands: Optional[List[Brand]] = None + __properties: ClassVar[List[str]] = ["brands"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + 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()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of EmailDomainResponseWithEmbeddedAllOfEmbedded from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in brands (list) + _items = [] + if self.brands: + for _item in self.brands: + if _item: + _items.append(_item.to_dict()) + _dict["brands"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of EmailDomainResponseWithEmbeddedAllOfEmbedded from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "brands": ( + [Brand.from_dict(_item) for _item in obj["brands"]] + if obj.get("brands") is not None + else None + ) + } + ) + return _obj diff --git a/openapi/api.yaml b/openapi/api.yaml index 66fe4dde..4fd2337c 100644 --- a/openapi/api.yaml +++ b/openapi/api.yaml @@ -64671,16 +64671,16 @@ components: EmailDomain: allOf: - $ref: '#/components/schemas/BaseEmailDomain' - type: object - properties: - brandId: - type: string - domain: - type: string - validationSubdomain: - type: string - description: Subdomain for the email sender's custom mail domain. Specify your subdomain when you configure a custom mail domain. - default: mail + - type: object + properties: + brandId: + type: string + domain: + type: string + validationSubdomain: + type: string + description: Subdomain for the email sender's custom mail domain. Specify your subdomain when you configure a custom mail domain. + default: mail required: - domain - brandId @@ -64701,35 +64701,35 @@ components: EmailDomainResponse: allOf: - $ref: '#/components/schemas/BaseEmailDomain' - type: object - properties: - dnsValidationRecords: - type: array - items: - $ref: '#/components/schemas/EmailDomainDNSRecord' - domain: - type: string - id: - type: string - validationStatus: - $ref: '#/components/schemas/EmailDomainStatus' - validationSubdomain: - type: string - description: The subdomain for the email sender's custom mail domain - default: mail + - type: object + properties: + dnsValidationRecords: + type: array + items: + $ref: '#/components/schemas/EmailDomainDNSRecord' + domain: + type: string + id: + type: string + validationStatus: + $ref: '#/components/schemas/EmailDomainStatus' + validationSubdomain: + type: string + description: The subdomain for the email sender's custom mail domain + default: mail EmailDomainResponseWithEmbedded: allOf: - $ref: '#/components/schemas/EmailDomainResponse' - type: object - properties: - _embedded: - type: object + - type: object properties: - brands: - type: array - items: - $ref: '#/components/schemas/Brand' - readOnly: true + _embedded: + type: object + properties: + brands: + type: array + items: + $ref: '#/components/schemas/Brand' + readOnly: true EmailDomainStatus: type: string enum: