From 5ef6b57a79ae21b85be8f38cfc3958528da98f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eray=20Ayd=C4=B1n?= Date: Fri, 26 Jun 2026 13:26:29 +0300 Subject: [PATCH 1/7] fix: accept unknown enum values When the API introduces new enum values, the SDK threw `ApiException` or `ValidationError` during deserialization instead of accepting the value gracefully. Related-Task: INTER-2250 --- .changeset/accept-unknown-enum-values.md | 5 + fingerprint_server_sdk/api_client.py | 6 +- fingerprint_server_sdk/models/bot_info.py | 6 - .../models/bot_info_category.py | 8 + .../models/bot_info_confidence.py | 8 + .../models/bot_info_identity.py | 8 + fingerprint_server_sdk/models/bot_result.py | 8 + fingerprint_server_sdk/models/error_code.py | 8 + .../incremental_identification_status.py | 8 + fingerprint_server_sdk/models/proximity.py | 4 - .../models/proxy_confidence.py | 8 + .../models/proxy_details.py | 2 - .../models/rare_device_percentile_bucket.py | 8 + .../models/rule_action_type.py | 8 + fingerprint_server_sdk/models/sdk.py | 2 - .../models/search_events_bot.py | 8 + .../models/search_events_bot_info.py | 8 + ...vents_incremental_identification_status.py | 8 + ...ch_events_rare_device_percentile_bucket.py | 8 + .../models/search_events_sdk_platform.py | 8 + .../models/search_events_vpn_confidence.py | 8 + .../models/tampering_confidence.py | 8 + .../models/vpn_confidence.py | 8 + template/api_client.mustache | 10 +- template/model_enum.mustache | 35 +++++ template/model_generic.mustache | 16 -- test/test_unknown_enum_values.py | 145 ++++++++++++++++++ 27 files changed, 325 insertions(+), 42 deletions(-) create mode 100644 .changeset/accept-unknown-enum-values.md create mode 100644 template/model_enum.mustache create mode 100644 test/test_unknown_enum_values.py diff --git a/.changeset/accept-unknown-enum-values.md b/.changeset/accept-unknown-enum-values.md new file mode 100644 index 00000000..ee2f4c0b --- /dev/null +++ b/.changeset/accept-unknown-enum-values.md @@ -0,0 +1,5 @@ +--- +'@fingerprint/python-sdk': patch +--- + +Accept unknown enum values gracefully instead of throwing errors during deserialization diff --git a/fingerprint_server_sdk/api_client.py b/fingerprint_server_sdk/api_client.py index 75606481..612abd83 100644 --- a/fingerprint_server_sdk/api_client.py +++ b/fingerprint_server_sdk/api_client.py @@ -739,10 +739,8 @@ def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Enum: """ try: return klass(data) - except ValueError as err: - raise ApiException( - status=0, reason=(f'Failed to parse `{data}` as `{klass}`') - ) from err + except ValueError: + return data def __deserialize_model(self, data: Any, klass: Any) -> Any: """Deserializes list or dict to model. diff --git a/fingerprint_server_sdk/models/bot_info.py b/fingerprint_server_sdk/models/bot_info.py index 5b706334..f3607b0a 100644 --- a/fingerprint_server_sdk/models/bot_info.py +++ b/fingerprint_server_sdk/models/bot_info.py @@ -48,17 +48,11 @@ class BotInfo(BaseModel): @field_validator('identity') def identity_validate_enum(cls, value: Any) -> Any: """Validates the enum""" - if value not in set(['verified', 'signed', 'spoofed', 'unknown']): - raise ValueError( - "must be one of enum values ('verified', 'signed', 'spoofed', 'unknown')" - ) return value @field_validator('confidence') def confidence_validate_enum(cls, value: Any) -> Any: """Validates the enum""" - if value not in set(['low', 'medium', 'high']): - raise ValueError("must be one of enum values ('low', 'medium', 'high')") return value model_config = ConfigDict( diff --git a/fingerprint_server_sdk/models/bot_info_category.py b/fingerprint_server_sdk/models/bot_info_category.py index 048bff29..717f8669 100644 --- a/fingerprint_server_sdk/models/bot_info_category.py +++ b/fingerprint_server_sdk/models/bot_info_category.py @@ -47,3 +47,11 @@ class BotInfoCategory(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of BotInfoCategory from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/bot_info_confidence.py b/fingerprint_server_sdk/models/bot_info_confidence.py index 84668e2e..d707ba4f 100644 --- a/fingerprint_server_sdk/models/bot_info_confidence.py +++ b/fingerprint_server_sdk/models/bot_info_confidence.py @@ -34,3 +34,11 @@ class BotInfoConfidence(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of BotInfoConfidence from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/bot_info_identity.py b/fingerprint_server_sdk/models/bot_info_identity.py index 38f88951..17c6a4c0 100644 --- a/fingerprint_server_sdk/models/bot_info_identity.py +++ b/fingerprint_server_sdk/models/bot_info_identity.py @@ -35,3 +35,11 @@ class BotInfoIdentity(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of BotInfoIdentity from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/bot_result.py b/fingerprint_server_sdk/models/bot_result.py index 50e5abc3..f123b554 100644 --- a/fingerprint_server_sdk/models/bot_result.py +++ b/fingerprint_server_sdk/models/bot_result.py @@ -34,3 +34,11 @@ class BotResult(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of BotResult from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/error_code.py b/fingerprint_server_sdk/models/error_code.py index f39223c8..0b2f9c08 100644 --- a/fingerprint_server_sdk/models/error_code.py +++ b/fingerprint_server_sdk/models/error_code.py @@ -49,3 +49,11 @@ class ErrorCode(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of ErrorCode from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/incremental_identification_status.py b/fingerprint_server_sdk/models/incremental_identification_status.py index 40a52686..292ee5e4 100644 --- a/fingerprint_server_sdk/models/incremental_identification_status.py +++ b/fingerprint_server_sdk/models/incremental_identification_status.py @@ -33,3 +33,11 @@ class IncrementalIdentificationStatus(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of IncrementalIdentificationStatus from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/proximity.py b/fingerprint_server_sdk/models/proximity.py index dcb6d980..53b9cf28 100644 --- a/fingerprint_server_sdk/models/proximity.py +++ b/fingerprint_server_sdk/models/proximity.py @@ -43,10 +43,6 @@ class Proximity(BaseModel): @field_validator('precision_radius') def precision_radius_validate_enum(cls, value: Any) -> Any: """Validates the enum""" - if value not in set([10, 25, 65, 175, 450, 1200, 3300, 8500, 22500]): - raise ValueError( - 'must be one of enum values (10, 25, 65, 175, 450, 1200, 3300, 8500, 22500)' - ) return value model_config = ConfigDict( diff --git a/fingerprint_server_sdk/models/proxy_confidence.py b/fingerprint_server_sdk/models/proxy_confidence.py index f0af2611..509ad6a2 100644 --- a/fingerprint_server_sdk/models/proxy_confidence.py +++ b/fingerprint_server_sdk/models/proxy_confidence.py @@ -34,3 +34,11 @@ class ProxyConfidence(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of ProxyConfidence from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/proxy_details.py b/fingerprint_server_sdk/models/proxy_details.py index 2885ddf5..36deb3a8 100644 --- a/fingerprint_server_sdk/models/proxy_details.py +++ b/fingerprint_server_sdk/models/proxy_details.py @@ -42,8 +42,6 @@ class ProxyDetails(BaseModel): @field_validator('proxy_type') def proxy_type_validate_enum(cls, value: Any) -> Any: """Validates the enum""" - if value not in set(['residential', 'data_center']): - raise ValueError("must be one of enum values ('residential', 'data_center')") return value model_config = ConfigDict( diff --git a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py index 1f186a13..a4a99f32 100644 --- a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py @@ -37,3 +37,11 @@ class RareDevicePercentileBucket(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of RareDevicePercentileBucket from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/rule_action_type.py b/fingerprint_server_sdk/models/rule_action_type.py index 3dc0f091..870ee9f4 100644 --- a/fingerprint_server_sdk/models/rule_action_type.py +++ b/fingerprint_server_sdk/models/rule_action_type.py @@ -33,3 +33,11 @@ class RuleActionType(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of RuleActionType from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/sdk.py b/fingerprint_server_sdk/models/sdk.py index 48374082..8126ca8b 100644 --- a/fingerprint_server_sdk/models/sdk.py +++ b/fingerprint_server_sdk/models/sdk.py @@ -40,8 +40,6 @@ class SDK(BaseModel): @field_validator('platform') def platform_validate_enum(cls, value: Any) -> Any: """Validates the enum""" - if value not in set(['js', 'android', 'ios', 'unknown']): - raise ValueError("must be one of enum values ('js', 'android', 'ios', 'unknown')") return value model_config = ConfigDict( diff --git a/fingerprint_server_sdk/models/search_events_bot.py b/fingerprint_server_sdk/models/search_events_bot.py index 24ede8ea..81a477df 100644 --- a/fingerprint_server_sdk/models/search_events_bot.py +++ b/fingerprint_server_sdk/models/search_events_bot.py @@ -35,3 +35,11 @@ class SearchEventsBot(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of SearchEventsBot from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/search_events_bot_info.py b/fingerprint_server_sdk/models/search_events_bot_info.py index 97cddc4b..5ee22308 100644 --- a/fingerprint_server_sdk/models/search_events_bot_info.py +++ b/fingerprint_server_sdk/models/search_events_bot_info.py @@ -33,3 +33,11 @@ class SearchEventsBotInfo(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of SearchEventsBotInfo from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py index f58c5f7a..8a4d8359 100644 --- a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py +++ b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py @@ -33,3 +33,11 @@ class SearchEventsIncrementalIdentificationStatus(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of SearchEventsIncrementalIdentificationStatus from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py index 5984862e..010e479b 100644 --- a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py @@ -37,3 +37,11 @@ class SearchEventsRareDevicePercentileBucket(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of SearchEventsRareDevicePercentileBucket from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/search_events_sdk_platform.py b/fingerprint_server_sdk/models/search_events_sdk_platform.py index 75e5c0fd..e3b7d87b 100644 --- a/fingerprint_server_sdk/models/search_events_sdk_platform.py +++ b/fingerprint_server_sdk/models/search_events_sdk_platform.py @@ -34,3 +34,11 @@ class SearchEventsSdkPlatform(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of SearchEventsSdkPlatform from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/search_events_vpn_confidence.py b/fingerprint_server_sdk/models/search_events_vpn_confidence.py index 0837b41c..0875dcb9 100644 --- a/fingerprint_server_sdk/models/search_events_vpn_confidence.py +++ b/fingerprint_server_sdk/models/search_events_vpn_confidence.py @@ -34,3 +34,11 @@ class SearchEventsVpnConfidence(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of SearchEventsVpnConfidence from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/tampering_confidence.py b/fingerprint_server_sdk/models/tampering_confidence.py index ab829a91..3c2f66d9 100644 --- a/fingerprint_server_sdk/models/tampering_confidence.py +++ b/fingerprint_server_sdk/models/tampering_confidence.py @@ -34,3 +34,11 @@ class TamperingConfidence(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of TamperingConfidence from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/fingerprint_server_sdk/models/vpn_confidence.py b/fingerprint_server_sdk/models/vpn_confidence.py index a8a5bae9..9b7a74b5 100644 --- a/fingerprint_server_sdk/models/vpn_confidence.py +++ b/fingerprint_server_sdk/models/vpn_confidence.py @@ -34,3 +34,11 @@ class VpnConfidence(str, Enum): def from_json(cls, json_str: str) -> Self: """Create an instance of VpnConfidence from a JSON string""" return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = str.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj diff --git a/template/api_client.mustache b/template/api_client.mustache index 04c90402..0e4cde3c 100644 --- a/template/api_client.mustache +++ b/template/api_client.mustache @@ -793,14 +793,8 @@ class ApiClient: """ try: return klass(data) - except ValueError as err: - raise ApiException( - status=0, - reason=( - "Failed to parse `{0}` as `{1}`" - .format(data, klass) - ) - ) from err + except ValueError: + return data def __deserialize_model(self, data: Any, klass: Any) -> Any: """Deserializes list or dict to model. diff --git a/template/model_enum.mustache b/template/model_enum.mustache new file mode 100644 index 00000000..9adf198a --- /dev/null +++ b/template/model_enum.mustache @@ -0,0 +1,35 @@ +from __future__ import annotations +import json +from enum import Enum +{{#vendorExtensions.x-py-other-imports}} +{{{.}}} +{{/vendorExtensions.x-py-other-imports}} +from typing_extensions import Self + + +class {{classname}}({{vendorExtensions.x-py-enum-type}}, Enum): + """ + {{{description}}}{{^description}}{{{classname}}}{{/description}} + """ + + """ + allowed enum values + """ +{{#allowableValues}} + {{#enumVars}} + {{{name}}} = {{{value}}} + {{/enumVars}} + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of {{classname}} from a JSON string""" + return cls(json.loads(json_str)) + + @classmethod + def _missing_(cls, value: object) -> Self: + """Accept unknown enum values gracefully.""" + obj = {{vendorExtensions.x-py-enum-type}}.__new__(cls, value) + obj._name_ = str(value) + obj._value_ = value + return obj +{{/allowableValues}} diff --git a/template/model_generic.mustache b/template/model_generic.mustache index 40a04841..fa92f1f0 100644 --- a/template/model_generic.mustache +++ b/template/model_generic.mustache @@ -76,22 +76,6 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}} {{/isNullable}} {{/required}} - {{#isContainer}} - {{#isArray}} - for i in value: - if i not in set([{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}]): - raise ValueError("each list item must be one of ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})") - {{/isArray}} - {{#isMap}} - for i in value.values(): - if i not in set([{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}]): - raise ValueError("dict values must be one of enum values ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})") - {{/isMap}} - {{/isContainer}} - {{^isContainer}} - if value not in set([{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}]): - raise ValueError("must be one of enum values ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})") - {{/isContainer}} return value {{/isEnum}} {{/vars}} diff --git a/test/test_unknown_enum_values.py b/test/test_unknown_enum_values.py new file mode 100644 index 00000000..2ff63a1c --- /dev/null +++ b/test/test_unknown_enum_values.py @@ -0,0 +1,145 @@ +import json +import unittest +from pathlib import Path +from typing import Any + +from fingerprint_server_sdk import Event +from fingerprint_server_sdk.models.bot_info import BotInfo +from fingerprint_server_sdk.models.proxy_details import ProxyDetails +from fingerprint_server_sdk.models.sdk import SDK + +MOCK_DIR = Path(__file__).resolve().parent / 'mocks' + + +class TestUnknownEnumValues(unittest.TestCase): + """Test that unknown/new enum values are accepted without errors.""" + + def _load_event_json(self) -> dict[str, Any]: + mock_file = MOCK_DIR / 'events' / 'get_event_200.json' + return json.loads(mock_file.read_text(encoding='utf-8')) + + def test_event_with_unknown_proxy_type(self) -> None: + """Unknown proxy_type value should be accepted and preserved.""" + data = self._load_event_json() + data['proxy_details']['proxy_type'] = 'unknown-value' + + event = Event.from_json(json.dumps(data)) + self.assertIsInstance(event, Event) + self.assertEqual(event.proxy_details.proxy_type, 'unknown-value') + + def test_event_with_unknown_sdk_platform(self) -> None: + """Unknown SDK platform value should be accepted and preserved.""" + data = self._load_event_json() + data['sdk']['platform'] = 'new-platform' + + event = Event.from_json(json.dumps(data)) + self.assertIsInstance(event, Event) + self.assertEqual(event.sdk.platform, 'new-platform') + + def test_event_with_unknown_bot_result(self) -> None: + """Unknown bot result value should be accepted and preserved.""" + data = self._load_event_json() + data['bot'] = 'unknown-value' + + event = Event.from_json(json.dumps(data)) + self.assertIsInstance(event, Event) + self.assertEqual(event.bot, 'unknown-value') + + def test_event_with_unknown_vpn_confidence(self) -> None: + """Unknown vpn_confidence value should be accepted and preserved.""" + data = self._load_event_json() + data['vpn'] = True + data['vpn_confidence'] = 'unknown-value' + + event = Event.from_json(json.dumps(data)) + self.assertIsInstance(event, Event) + self.assertEqual(event.vpn_confidence, 'unknown-value') + + def test_event_with_unknown_proxy_confidence(self) -> None: + """Unknown proxy_confidence value should be accepted and preserved.""" + data = self._load_event_json() + data['proxy_confidence'] = 'unknown-value' + + event = Event.from_json(json.dumps(data)) + self.assertIsInstance(event, Event) + self.assertEqual(event.proxy_confidence, 'unknown-value') + + def test_event_with_unknown_tampering_confidence(self) -> None: + """Unknown tampering_confidence value should be accepted and preserved.""" + data = self._load_event_json() + data['tampering_confidence'] = 'unknown-value' + + event = Event.from_json(json.dumps(data)) + self.assertIsInstance(event, Event) + self.assertEqual(event.tampering_confidence, 'unknown-value') + + def test_event_with_unknown_rare_device_percentile_bucket(self) -> None: + """Unknown rare_device_percentile_bucket value should be accepted and preserved.""" + data = self._load_event_json() + data['rare_device_percentile_bucket'] = 'unknown-value' + + event = Event.from_json(json.dumps(data)) + self.assertIsInstance(event, Event) + self.assertEqual(event.rare_device_percentile_bucket, 'unknown-value') + + def test_proxy_details_with_unknown_proxy_type(self) -> None: + """ProxyDetails model should accept unknown proxy_type directly.""" + details = ProxyDetails.from_dict({'proxy_type': 'unknown-value', 'last_seen_at': 123}) + self.assertIsInstance(details, ProxyDetails) + self.assertEqual(details.proxy_type, 'unknown-value') + + def test_sdk_with_unknown_platform(self) -> None: + """SDK model should accept unknown platform directly.""" + sdk = SDK.from_dict({'platform': 'unknown-value', 'version': '1.0.0'}) + self.assertIsInstance(sdk, SDK) + self.assertEqual(sdk.platform, 'unknown-value') + + def test_bot_info_with_unknown_identity_and_confidence(self) -> None: + """BotInfo model should accept unknown identity and confidence values.""" + info = BotInfo.from_dict( + { + 'category': 'crawler', + 'provider': 'TestBot', + 'name': 'test', + 'identity': 'unknown-value', + 'confidence': 'unknown-value', + } + ) + self.assertIsInstance(info, BotInfo) + self.assertEqual(info.identity, 'unknown-value') + self.assertEqual(info.confidence, 'unknown-value') + + def test_event_with_multiple_unknown_enum_values(self) -> None: + """Event should deserialize when multiple enum fields have unknown values.""" + data = self._load_event_json() + data['proxy_details']['proxy_type'] = 'unknown-value' + data['sdk']['platform'] = 'unknown-value' + data['bot'] = 'unknown-value' + data['vpn'] = True + data['vpn_confidence'] = 'unknown-value' + data['proxy_confidence'] = 'unknown-value' + data['tampering_confidence'] = 'unknown-value' + data['rare_device_percentile_bucket'] = 'unknown-value' + + event = Event.from_json(json.dumps(data)) + self.assertIsInstance(event, Event) + self.assertEqual(event.proxy_details.proxy_type, 'unknown-value') + self.assertEqual(event.sdk.platform, 'unknown-value') + self.assertEqual(event.bot, 'unknown-value') + self.assertEqual(event.vpn_confidence, 'unknown-value') + self.assertEqual(event.proxy_confidence, 'unknown-value') + self.assertEqual(event.tampering_confidence, 'unknown-value') + self.assertEqual(event.rare_device_percentile_bucket, 'unknown-value') + + def test_known_enum_values_still_work(self) -> None: + """Known enum values should continue to work as before.""" + data = self._load_event_json() + + event = Event.from_json(json.dumps(data)) + self.assertIsInstance(event, Event) + self.assertEqual(event.proxy_details.proxy_type, 'residential') + self.assertEqual(event.sdk.platform, 'js') + + +if __name__ == '__main__': + unittest.main() From d9b7374fed1e102af9cb57e6572290db42f5610d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eray=20Ayd=C4=B1n?= Date: Fri, 26 Jun 2026 13:34:11 +0300 Subject: [PATCH 2/7] fix: use str for unknown and resolve mypy error Use Union[Enum, str] return type and str(data) to satisfy mypy Related-Task: INTER-2250 --- fingerprint_server_sdk/api_client.py | 6 +++--- template/api_client.mustache | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fingerprint_server_sdk/api_client.py b/fingerprint_server_sdk/api_client.py index 612abd83..1ccd2b89 100644 --- a/fingerprint_server_sdk/api_client.py +++ b/fingerprint_server_sdk/api_client.py @@ -730,17 +730,17 @@ def __deserialize_datetime(self, string: str) -> datetime.datetime: status=0, reason=(f'Failed to parse `{string}` as datetime object') ) from err - def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Enum: + def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Union[Enum, str]: """Deserializes primitive type to enum. :param data: primitive type. :param klass: class literal. - :return: enum value. + :return: enum value or raw string if the value is unknown. """ try: return klass(data) except ValueError: - return data + return str(data) def __deserialize_model(self, data: Any, klass: Any) -> Any: """Deserializes list or dict to model. diff --git a/template/api_client.mustache b/template/api_client.mustache index 0e4cde3c..a803373f 100644 --- a/template/api_client.mustache +++ b/template/api_client.mustache @@ -784,17 +784,17 @@ class ApiClient: ) ) from err - def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Enum: + def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Union[Enum, str]: """Deserializes primitive type to enum. :param data: primitive type. :param klass: class literal. - :return: enum value. + :return: enum value or raw string if the value is unknown. """ try: return klass(data) except ValueError: - return data + return str(data) def __deserialize_model(self, data: Any, klass: Any) -> Any: """Deserializes list or dict to model. From c92dc7f370ab4fe2febbb2c400bd4ab4d9b0e28f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eray=20Ayd=C4=B1n?= Date: Fri, 26 Jun 2026 14:06:05 +0300 Subject: [PATCH 3/7] fix: cast and cache unknown members in _missing_ --- fingerprint_server_sdk/models/bot_info_category.py | 8 +++++--- fingerprint_server_sdk/models/bot_info_confidence.py | 8 +++++--- fingerprint_server_sdk/models/bot_info_identity.py | 8 +++++--- fingerprint_server_sdk/models/bot_result.py | 8 +++++--- fingerprint_server_sdk/models/error_code.py | 8 +++++--- .../models/incremental_identification_status.py | 8 +++++--- fingerprint_server_sdk/models/proxy_confidence.py | 8 +++++--- .../models/rare_device_percentile_bucket.py | 8 +++++--- fingerprint_server_sdk/models/rule_action_type.py | 8 +++++--- fingerprint_server_sdk/models/search_events_bot.py | 8 +++++--- fingerprint_server_sdk/models/search_events_bot_info.py | 8 +++++--- .../search_events_incremental_identification_status.py | 8 +++++--- .../models/search_events_rare_device_percentile_bucket.py | 8 +++++--- .../models/search_events_sdk_platform.py | 8 +++++--- .../models/search_events_vpn_confidence.py | 8 +++++--- fingerprint_server_sdk/models/tampering_confidence.py | 8 +++++--- fingerprint_server_sdk/models/vpn_confidence.py | 8 +++++--- template/model_enum.mustache | 8 +++++--- 18 files changed, 90 insertions(+), 54 deletions(-) diff --git a/fingerprint_server_sdk/models/bot_info_category.py b/fingerprint_server_sdk/models/bot_info_category.py index 717f8669..d806f60f 100644 --- a/fingerprint_server_sdk/models/bot_info_category.py +++ b/fingerprint_server_sdk/models/bot_info_category.py @@ -51,7 +51,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_info_confidence.py b/fingerprint_server_sdk/models/bot_info_confidence.py index d707ba4f..019445cd 100644 --- a/fingerprint_server_sdk/models/bot_info_confidence.py +++ b/fingerprint_server_sdk/models/bot_info_confidence.py @@ -38,7 +38,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_info_identity.py b/fingerprint_server_sdk/models/bot_info_identity.py index 17c6a4c0..a128539d 100644 --- a/fingerprint_server_sdk/models/bot_info_identity.py +++ b/fingerprint_server_sdk/models/bot_info_identity.py @@ -39,7 +39,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_result.py b/fingerprint_server_sdk/models/bot_result.py index f123b554..c172bee9 100644 --- a/fingerprint_server_sdk/models/bot_result.py +++ b/fingerprint_server_sdk/models/bot_result.py @@ -38,7 +38,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/error_code.py b/fingerprint_server_sdk/models/error_code.py index 0b2f9c08..88aea720 100644 --- a/fingerprint_server_sdk/models/error_code.py +++ b/fingerprint_server_sdk/models/error_code.py @@ -53,7 +53,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/incremental_identification_status.py b/fingerprint_server_sdk/models/incremental_identification_status.py index 292ee5e4..e1e3f0c6 100644 --- a/fingerprint_server_sdk/models/incremental_identification_status.py +++ b/fingerprint_server_sdk/models/incremental_identification_status.py @@ -37,7 +37,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/proxy_confidence.py b/fingerprint_server_sdk/models/proxy_confidence.py index 509ad6a2..3feaa747 100644 --- a/fingerprint_server_sdk/models/proxy_confidence.py +++ b/fingerprint_server_sdk/models/proxy_confidence.py @@ -38,7 +38,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py index a4a99f32..f402d476 100644 --- a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py @@ -41,7 +41,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/rule_action_type.py b/fingerprint_server_sdk/models/rule_action_type.py index 870ee9f4..2c628031 100644 --- a/fingerprint_server_sdk/models/rule_action_type.py +++ b/fingerprint_server_sdk/models/rule_action_type.py @@ -37,7 +37,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_bot.py b/fingerprint_server_sdk/models/search_events_bot.py index 81a477df..3032c7c6 100644 --- a/fingerprint_server_sdk/models/search_events_bot.py +++ b/fingerprint_server_sdk/models/search_events_bot.py @@ -39,7 +39,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_bot_info.py b/fingerprint_server_sdk/models/search_events_bot_info.py index 5ee22308..7685c391 100644 --- a/fingerprint_server_sdk/models/search_events_bot_info.py +++ b/fingerprint_server_sdk/models/search_events_bot_info.py @@ -37,7 +37,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py index 8a4d8359..d8eee49f 100644 --- a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py +++ b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py @@ -37,7 +37,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py index 010e479b..ae636c76 100644 --- a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py @@ -41,7 +41,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_sdk_platform.py b/fingerprint_server_sdk/models/search_events_sdk_platform.py index e3b7d87b..d49ad632 100644 --- a/fingerprint_server_sdk/models/search_events_sdk_platform.py +++ b/fingerprint_server_sdk/models/search_events_sdk_platform.py @@ -38,7 +38,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_vpn_confidence.py b/fingerprint_server_sdk/models/search_events_vpn_confidence.py index 0875dcb9..6f4b2bab 100644 --- a/fingerprint_server_sdk/models/search_events_vpn_confidence.py +++ b/fingerprint_server_sdk/models/search_events_vpn_confidence.py @@ -38,7 +38,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/tampering_confidence.py b/fingerprint_server_sdk/models/tampering_confidence.py index 3c2f66d9..ece53e32 100644 --- a/fingerprint_server_sdk/models/tampering_confidence.py +++ b/fingerprint_server_sdk/models/tampering_confidence.py @@ -38,7 +38,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/fingerprint_server_sdk/models/vpn_confidence.py b/fingerprint_server_sdk/models/vpn_confidence.py index 9b7a74b5..bd0a3eeb 100644 --- a/fingerprint_server_sdk/models/vpn_confidence.py +++ b/fingerprint_server_sdk/models/vpn_confidence.py @@ -38,7 +38,9 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = str.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = str(value) + obj = str.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj diff --git a/template/model_enum.mustache b/template/model_enum.mustache index 9adf198a..74b5d85b 100644 --- a/template/model_enum.mustache +++ b/template/model_enum.mustache @@ -28,8 +28,10 @@ class {{classname}}({{vendorExtensions.x-py-enum-type}}, Enum): @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - obj = {{vendorExtensions.x-py-enum-type}}.__new__(cls, value) - obj._name_ = str(value) - obj._value_ = value + typed_value = {{vendorExtensions.x-py-enum-type}}(value) + obj = {{vendorExtensions.x-py-enum-type}}.__new__(cls, typed_value) + obj._name_ = typed_value + obj._value_ = typed_value + cls._value2member_map_[typed_value] = obj return obj {{/allowableValues}} From de2e748b5033cae29cb41f75bd0d5c12a8670061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eray=20Ayd=C4=B1n?= Date: Fri, 26 Jun 2026 14:25:28 +0300 Subject: [PATCH 4/7] refactor: remove no-op enum field validators --- fingerprint_server_sdk/models/bot_info.py | 12 +----------- fingerprint_server_sdk/models/proximity.py | 7 +------ .../models/proxy_details.py | 7 +------ fingerprint_server_sdk/models/sdk.py | 7 +------ template/model_generic.mustache | 19 ------------------- 5 files changed, 4 insertions(+), 48 deletions(-) diff --git a/fingerprint_server_sdk/models/bot_info.py b/fingerprint_server_sdk/models/bot_info.py index f3607b0a..5b1e6163 100644 --- a/fingerprint_server_sdk/models/bot_info.py +++ b/fingerprint_server_sdk/models/bot_info.py @@ -17,7 +17,7 @@ import re # noqa: F401 from typing import Any, ClassVar, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing_extensions import Self @@ -45,16 +45,6 @@ class BotInfo(BaseModel): 'confidence', ] - @field_validator('identity') - def identity_validate_enum(cls, value: Any) -> Any: - """Validates the enum""" - return value - - @field_validator('confidence') - def confidence_validate_enum(cls, value: Any) -> Any: - """Validates the enum""" - return value - model_config = ConfigDict( populate_by_name=True, validate_assignment=True, diff --git a/fingerprint_server_sdk/models/proximity.py b/fingerprint_server_sdk/models/proximity.py index 53b9cf28..14c8f17d 100644 --- a/fingerprint_server_sdk/models/proximity.py +++ b/fingerprint_server_sdk/models/proximity.py @@ -17,7 +17,7 @@ import re # noqa: F401 from typing import Annotated, Any, ClassVar, Optional, Union -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr from typing_extensions import Self @@ -40,11 +40,6 @@ class Proximity(BaseModel): ) __properties: ClassVar[list[str]] = ['id', 'precision_radius', 'confidence'] - @field_validator('precision_radius') - def precision_radius_validate_enum(cls, value: Any) -> Any: - """Validates the enum""" - return value - model_config = ConfigDict( populate_by_name=True, validate_assignment=True, diff --git a/fingerprint_server_sdk/models/proxy_details.py b/fingerprint_server_sdk/models/proxy_details.py index 36deb3a8..0c357f20 100644 --- a/fingerprint_server_sdk/models/proxy_details.py +++ b/fingerprint_server_sdk/models/proxy_details.py @@ -17,7 +17,7 @@ import re # noqa: F401 from typing import Any, ClassVar, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr from typing_extensions import Self @@ -39,11 +39,6 @@ class ProxyDetails(BaseModel): ) __properties: ClassVar[list[str]] = ['proxy_type', 'last_seen_at', 'provider'] - @field_validator('proxy_type') - def proxy_type_validate_enum(cls, value: Any) -> Any: - """Validates the enum""" - return value - model_config = ConfigDict( populate_by_name=True, validate_assignment=True, diff --git a/fingerprint_server_sdk/models/sdk.py b/fingerprint_server_sdk/models/sdk.py index 8126ca8b..ef06139b 100644 --- a/fingerprint_server_sdk/models/sdk.py +++ b/fingerprint_server_sdk/models/sdk.py @@ -17,7 +17,7 @@ import re # noqa: F401 from typing import Any, ClassVar, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing_extensions import Self from fingerprint_server_sdk.models.integration import Integration @@ -37,11 +37,6 @@ class SDK(BaseModel): integrations: Optional[list[Integration]] = None __properties: ClassVar[list[str]] = ['platform', 'version', 'integrations'] - @field_validator('platform') - def platform_validate_enum(cls, value: Any) -> Any: - """Validates the enum""" - return value - model_config = ConfigDict( populate_by_name=True, validate_assignment=True, diff --git a/template/model_generic.mustache b/template/model_generic.mustache index fa92f1f0..e72fd3cf 100644 --- a/template/model_generic.mustache +++ b/template/model_generic.mustache @@ -59,25 +59,6 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}} raise ValueError(r"must validate the regular expression {{{vendorExtensions.x-pattern}}}") return value {{/vendorExtensions.x-regex}} - {{#isEnum}} - - @field_validator('{{{name}}}') - def {{{name}}}_validate_enum(cls, value: Any) -> Any: - """Validates the enum""" - {{^required}} - if value is None: - return value - - {{/required}} - {{#required}} - {{#isNullable}} - if value is None: - return value - - {{/isNullable}} - {{/required}} - return value - {{/isEnum}} {{/vars}} model_config = ConfigDict( From 5a0b52e2d82be8d1a91ba58e9426953592a1ec11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eray=20Ayd=C4=B1n?= Date: Fri, 26 Jun 2026 14:53:17 +0300 Subject: [PATCH 5/7] refactor: simpl __deserialize_enum validate type --- fingerprint_server_sdk/api_client.py | 9 +++------ fingerprint_server_sdk/models/bot_info_category.py | 11 ++++++----- fingerprint_server_sdk/models/bot_info_confidence.py | 11 ++++++----- fingerprint_server_sdk/models/bot_info_identity.py | 11 ++++++----- fingerprint_server_sdk/models/bot_result.py | 11 ++++++----- fingerprint_server_sdk/models/error_code.py | 11 ++++++----- .../models/incremental_identification_status.py | 11 ++++++----- fingerprint_server_sdk/models/proxy_confidence.py | 11 ++++++----- .../models/rare_device_percentile_bucket.py | 11 ++++++----- fingerprint_server_sdk/models/rule_action_type.py | 11 ++++++----- fingerprint_server_sdk/models/search_events_bot.py | 11 ++++++----- .../models/search_events_bot_info.py | 11 ++++++----- ...search_events_incremental_identification_status.py | 11 ++++++----- .../search_events_rare_device_percentile_bucket.py | 11 ++++++----- .../models/search_events_sdk_platform.py | 11 ++++++----- .../models/search_events_vpn_confidence.py | 11 ++++++----- fingerprint_server_sdk/models/tampering_confidence.py | 11 ++++++----- fingerprint_server_sdk/models/vpn_confidence.py | 11 ++++++----- template/api_client.mustache | 9 +++------ template/model_enum.mustache | 11 ++++++----- 20 files changed, 114 insertions(+), 102 deletions(-) diff --git a/fingerprint_server_sdk/api_client.py b/fingerprint_server_sdk/api_client.py index 1ccd2b89..f40ab76e 100644 --- a/fingerprint_server_sdk/api_client.py +++ b/fingerprint_server_sdk/api_client.py @@ -730,17 +730,14 @@ def __deserialize_datetime(self, string: str) -> datetime.datetime: status=0, reason=(f'Failed to parse `{string}` as datetime object') ) from err - def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Union[Enum, str]: + def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Enum: """Deserializes primitive type to enum. :param data: primitive type. :param klass: class literal. - :return: enum value or raw string if the value is unknown. + :return: enum value. """ - try: - return klass(data) - except ValueError: - return str(data) + return klass(data) def __deserialize_model(self, data: Any, klass: Any) -> Any: """Deserializes list or dict to model. diff --git a/fingerprint_server_sdk/models/bot_info_category.py b/fingerprint_server_sdk/models/bot_info_category.py index d806f60f..06431a1e 100644 --- a/fingerprint_server_sdk/models/bot_info_category.py +++ b/fingerprint_server_sdk/models/bot_info_category.py @@ -51,9 +51,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_info_confidence.py b/fingerprint_server_sdk/models/bot_info_confidence.py index 019445cd..2e655b08 100644 --- a/fingerprint_server_sdk/models/bot_info_confidence.py +++ b/fingerprint_server_sdk/models/bot_info_confidence.py @@ -38,9 +38,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_info_identity.py b/fingerprint_server_sdk/models/bot_info_identity.py index a128539d..bb09a72d 100644 --- a/fingerprint_server_sdk/models/bot_info_identity.py +++ b/fingerprint_server_sdk/models/bot_info_identity.py @@ -39,9 +39,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_result.py b/fingerprint_server_sdk/models/bot_result.py index c172bee9..86436b06 100644 --- a/fingerprint_server_sdk/models/bot_result.py +++ b/fingerprint_server_sdk/models/bot_result.py @@ -38,9 +38,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/error_code.py b/fingerprint_server_sdk/models/error_code.py index 88aea720..29b32a5e 100644 --- a/fingerprint_server_sdk/models/error_code.py +++ b/fingerprint_server_sdk/models/error_code.py @@ -53,9 +53,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/incremental_identification_status.py b/fingerprint_server_sdk/models/incremental_identification_status.py index e1e3f0c6..cae6ee3f 100644 --- a/fingerprint_server_sdk/models/incremental_identification_status.py +++ b/fingerprint_server_sdk/models/incremental_identification_status.py @@ -37,9 +37,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/proxy_confidence.py b/fingerprint_server_sdk/models/proxy_confidence.py index 3feaa747..1084fee5 100644 --- a/fingerprint_server_sdk/models/proxy_confidence.py +++ b/fingerprint_server_sdk/models/proxy_confidence.py @@ -38,9 +38,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py index f402d476..9bd3781b 100644 --- a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py @@ -41,9 +41,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/rule_action_type.py b/fingerprint_server_sdk/models/rule_action_type.py index 2c628031..121c12b8 100644 --- a/fingerprint_server_sdk/models/rule_action_type.py +++ b/fingerprint_server_sdk/models/rule_action_type.py @@ -37,9 +37,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_bot.py b/fingerprint_server_sdk/models/search_events_bot.py index 3032c7c6..274c342f 100644 --- a/fingerprint_server_sdk/models/search_events_bot.py +++ b/fingerprint_server_sdk/models/search_events_bot.py @@ -39,9 +39,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_bot_info.py b/fingerprint_server_sdk/models/search_events_bot_info.py index 7685c391..e28ba040 100644 --- a/fingerprint_server_sdk/models/search_events_bot_info.py +++ b/fingerprint_server_sdk/models/search_events_bot_info.py @@ -37,9 +37,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py index d8eee49f..56a78252 100644 --- a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py +++ b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py @@ -37,9 +37,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py index ae636c76..cafb833f 100644 --- a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py @@ -41,9 +41,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_sdk_platform.py b/fingerprint_server_sdk/models/search_events_sdk_platform.py index d49ad632..9c2d1b25 100644 --- a/fingerprint_server_sdk/models/search_events_sdk_platform.py +++ b/fingerprint_server_sdk/models/search_events_sdk_platform.py @@ -38,9 +38,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_vpn_confidence.py b/fingerprint_server_sdk/models/search_events_vpn_confidence.py index 6f4b2bab..587a1f1f 100644 --- a/fingerprint_server_sdk/models/search_events_vpn_confidence.py +++ b/fingerprint_server_sdk/models/search_events_vpn_confidence.py @@ -38,9 +38,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/tampering_confidence.py b/fingerprint_server_sdk/models/tampering_confidence.py index ece53e32..59410fc8 100644 --- a/fingerprint_server_sdk/models/tampering_confidence.py +++ b/fingerprint_server_sdk/models/tampering_confidence.py @@ -38,9 +38,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/vpn_confidence.py b/fingerprint_server_sdk/models/vpn_confidence.py index bd0a3eeb..f764de5f 100644 --- a/fingerprint_server_sdk/models/vpn_confidence.py +++ b/fingerprint_server_sdk/models/vpn_confidence.py @@ -38,9 +38,10 @@ def from_json(cls, json_str: str) -> Self: @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = str(value) - obj = str.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, str): + raise ValueError(f'{value!r} is not a valid {cls.__name__}') + obj = str.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj diff --git a/template/api_client.mustache b/template/api_client.mustache index a803373f..62849289 100644 --- a/template/api_client.mustache +++ b/template/api_client.mustache @@ -784,17 +784,14 @@ class ApiClient: ) ) from err - def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Union[Enum, str]: + def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Enum: """Deserializes primitive type to enum. :param data: primitive type. :param klass: class literal. - :return: enum value or raw string if the value is unknown. + :return: enum value. """ - try: - return klass(data) - except ValueError: - return str(data) + return klass(data) def __deserialize_model(self, data: Any, klass: Any) -> Any: """Deserializes list or dict to model. diff --git a/template/model_enum.mustache b/template/model_enum.mustache index 74b5d85b..3f1fe733 100644 --- a/template/model_enum.mustache +++ b/template/model_enum.mustache @@ -28,10 +28,11 @@ class {{classname}}({{vendorExtensions.x-py-enum-type}}, Enum): @classmethod def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" - typed_value = {{vendorExtensions.x-py-enum-type}}(value) - obj = {{vendorExtensions.x-py-enum-type}}.__new__(cls, typed_value) - obj._name_ = typed_value - obj._value_ = typed_value - cls._value2member_map_[typed_value] = obj + if not isinstance(value, {{vendorExtensions.x-py-enum-type}}): + raise ValueError(f"{value!r} is not a valid {cls.__name__}") + obj = {{vendorExtensions.x-py-enum-type}}.__new__(cls, value) + obj._name_ = value + obj._value_ = value + cls._value2member_map_[value] = obj return obj {{/allowableValues}} From fa66beb9db4af3d635ffc11071d0aa99ecd311ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eray=20Ayd=C4=B1n?= Date: Fri, 26 Jun 2026 16:48:12 +0300 Subject: [PATCH 6/7] fix: use str for enum _name_ restore ApiException Use str(value) for \_name\_ in \_missing\_ so enum member names are always strings. Restore ValueError -> ApiException wrapping. Related-Task: INTER-2250 --- fingerprint_server_sdk/api_client.py | 7 ++++++- fingerprint_server_sdk/models/bot_info_category.py | 2 +- fingerprint_server_sdk/models/bot_info_confidence.py | 2 +- fingerprint_server_sdk/models/bot_info_identity.py | 2 +- fingerprint_server_sdk/models/bot_result.py | 2 +- fingerprint_server_sdk/models/error_code.py | 2 +- .../models/incremental_identification_status.py | 2 +- fingerprint_server_sdk/models/proxy_confidence.py | 2 +- .../models/rare_device_percentile_bucket.py | 2 +- fingerprint_server_sdk/models/rule_action_type.py | 2 +- fingerprint_server_sdk/models/search_events_bot.py | 2 +- .../models/search_events_bot_info.py | 2 +- ...search_events_incremental_identification_status.py | 2 +- .../search_events_rare_device_percentile_bucket.py | 2 +- .../models/search_events_sdk_platform.py | 2 +- .../models/search_events_vpn_confidence.py | 2 +- fingerprint_server_sdk/models/tampering_confidence.py | 2 +- fingerprint_server_sdk/models/vpn_confidence.py | 2 +- template/api_client.mustache | 11 ++++++++++- template/model_enum.mustache | 2 +- 20 files changed, 34 insertions(+), 20 deletions(-) diff --git a/fingerprint_server_sdk/api_client.py b/fingerprint_server_sdk/api_client.py index f40ab76e..75606481 100644 --- a/fingerprint_server_sdk/api_client.py +++ b/fingerprint_server_sdk/api_client.py @@ -737,7 +737,12 @@ def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Enum: :param klass: class literal. :return: enum value. """ - return klass(data) + try: + return klass(data) + except ValueError as err: + raise ApiException( + status=0, reason=(f'Failed to parse `{data}` as `{klass}`') + ) from err def __deserialize_model(self, data: Any, klass: Any) -> Any: """Deserializes list or dict to model. diff --git a/fingerprint_server_sdk/models/bot_info_category.py b/fingerprint_server_sdk/models/bot_info_category.py index 06431a1e..13b5887c 100644 --- a/fingerprint_server_sdk/models/bot_info_category.py +++ b/fingerprint_server_sdk/models/bot_info_category.py @@ -54,7 +54,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_info_confidence.py b/fingerprint_server_sdk/models/bot_info_confidence.py index 2e655b08..9171d4d3 100644 --- a/fingerprint_server_sdk/models/bot_info_confidence.py +++ b/fingerprint_server_sdk/models/bot_info_confidence.py @@ -41,7 +41,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_info_identity.py b/fingerprint_server_sdk/models/bot_info_identity.py index bb09a72d..9e4321d0 100644 --- a/fingerprint_server_sdk/models/bot_info_identity.py +++ b/fingerprint_server_sdk/models/bot_info_identity.py @@ -42,7 +42,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_result.py b/fingerprint_server_sdk/models/bot_result.py index 86436b06..9b5ae50b 100644 --- a/fingerprint_server_sdk/models/bot_result.py +++ b/fingerprint_server_sdk/models/bot_result.py @@ -41,7 +41,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/error_code.py b/fingerprint_server_sdk/models/error_code.py index 29b32a5e..a7deb875 100644 --- a/fingerprint_server_sdk/models/error_code.py +++ b/fingerprint_server_sdk/models/error_code.py @@ -56,7 +56,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/incremental_identification_status.py b/fingerprint_server_sdk/models/incremental_identification_status.py index cae6ee3f..800bde27 100644 --- a/fingerprint_server_sdk/models/incremental_identification_status.py +++ b/fingerprint_server_sdk/models/incremental_identification_status.py @@ -40,7 +40,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/proxy_confidence.py b/fingerprint_server_sdk/models/proxy_confidence.py index 1084fee5..00104445 100644 --- a/fingerprint_server_sdk/models/proxy_confidence.py +++ b/fingerprint_server_sdk/models/proxy_confidence.py @@ -41,7 +41,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py index 9bd3781b..f9dad983 100644 --- a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py @@ -44,7 +44,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/rule_action_type.py b/fingerprint_server_sdk/models/rule_action_type.py index 121c12b8..3b0bdc07 100644 --- a/fingerprint_server_sdk/models/rule_action_type.py +++ b/fingerprint_server_sdk/models/rule_action_type.py @@ -40,7 +40,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_bot.py b/fingerprint_server_sdk/models/search_events_bot.py index 274c342f..ce35589c 100644 --- a/fingerprint_server_sdk/models/search_events_bot.py +++ b/fingerprint_server_sdk/models/search_events_bot.py @@ -42,7 +42,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_bot_info.py b/fingerprint_server_sdk/models/search_events_bot_info.py index e28ba040..42d6e9af 100644 --- a/fingerprint_server_sdk/models/search_events_bot_info.py +++ b/fingerprint_server_sdk/models/search_events_bot_info.py @@ -40,7 +40,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py index 56a78252..5e690c53 100644 --- a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py +++ b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py @@ -40,7 +40,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py index cafb833f..6cd5b950 100644 --- a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py @@ -44,7 +44,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_sdk_platform.py b/fingerprint_server_sdk/models/search_events_sdk_platform.py index 9c2d1b25..16e05867 100644 --- a/fingerprint_server_sdk/models/search_events_sdk_platform.py +++ b/fingerprint_server_sdk/models/search_events_sdk_platform.py @@ -41,7 +41,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_vpn_confidence.py b/fingerprint_server_sdk/models/search_events_vpn_confidence.py index 587a1f1f..96c7f8ee 100644 --- a/fingerprint_server_sdk/models/search_events_vpn_confidence.py +++ b/fingerprint_server_sdk/models/search_events_vpn_confidence.py @@ -41,7 +41,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/tampering_confidence.py b/fingerprint_server_sdk/models/tampering_confidence.py index 59410fc8..daa6e48f 100644 --- a/fingerprint_server_sdk/models/tampering_confidence.py +++ b/fingerprint_server_sdk/models/tampering_confidence.py @@ -41,7 +41,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/vpn_confidence.py b/fingerprint_server_sdk/models/vpn_confidence.py index f764de5f..75c88b45 100644 --- a/fingerprint_server_sdk/models/vpn_confidence.py +++ b/fingerprint_server_sdk/models/vpn_confidence.py @@ -41,7 +41,7 @@ def _missing_(cls, value: object) -> Self: if not isinstance(value, str): raise ValueError(f'{value!r} is not a valid {cls.__name__}') obj = str.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj diff --git a/template/api_client.mustache b/template/api_client.mustache index 62849289..04c90402 100644 --- a/template/api_client.mustache +++ b/template/api_client.mustache @@ -791,7 +791,16 @@ class ApiClient: :param klass: class literal. :return: enum value. """ - return klass(data) + try: + return klass(data) + except ValueError as err: + raise ApiException( + status=0, + reason=( + "Failed to parse `{0}` as `{1}`" + .format(data, klass) + ) + ) from err def __deserialize_model(self, data: Any, klass: Any) -> Any: """Deserializes list or dict to model. diff --git a/template/model_enum.mustache b/template/model_enum.mustache index 3f1fe733..cf7a18cb 100644 --- a/template/model_enum.mustache +++ b/template/model_enum.mustache @@ -31,7 +31,7 @@ class {{classname}}({{vendorExtensions.x-py-enum-type}}, Enum): if not isinstance(value, {{vendorExtensions.x-py-enum-type}}): raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = {{vendorExtensions.x-py-enum-type}}.__new__(cls, value) - obj._name_ = value + obj._name_ = str(value) obj._value_ = value cls._value2member_map_[value] = obj return obj From 17e4e211602984fb138ae86070bb24e7dd14bdd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eray=20Ayd=C4=B1n?= Date: Mon, 29 Jun 2026 14:18:59 +0300 Subject: [PATCH 7/7] docs: add comment explaining _value2member_map_ --- fingerprint_server_sdk/models/bot_info_category.py | 1 + fingerprint_server_sdk/models/bot_info_confidence.py | 1 + fingerprint_server_sdk/models/bot_info_identity.py | 1 + fingerprint_server_sdk/models/bot_result.py | 1 + fingerprint_server_sdk/models/error_code.py | 1 + .../models/incremental_identification_status.py | 1 + fingerprint_server_sdk/models/proxy_confidence.py | 1 + fingerprint_server_sdk/models/rare_device_percentile_bucket.py | 1 + fingerprint_server_sdk/models/rule_action_type.py | 1 + fingerprint_server_sdk/models/search_events_bot.py | 1 + fingerprint_server_sdk/models/search_events_bot_info.py | 1 + .../models/search_events_incremental_identification_status.py | 1 + .../models/search_events_rare_device_percentile_bucket.py | 1 + fingerprint_server_sdk/models/search_events_sdk_platform.py | 1 + fingerprint_server_sdk/models/search_events_vpn_confidence.py | 1 + fingerprint_server_sdk/models/tampering_confidence.py | 1 + fingerprint_server_sdk/models/vpn_confidence.py | 1 + template/model_enum.mustache | 1 + 18 files changed, 18 insertions(+) diff --git a/fingerprint_server_sdk/models/bot_info_category.py b/fingerprint_server_sdk/models/bot_info_category.py index 13b5887c..b0cdb7a4 100644 --- a/fingerprint_server_sdk/models/bot_info_category.py +++ b/fingerprint_server_sdk/models/bot_info_category.py @@ -56,5 +56,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_info_confidence.py b/fingerprint_server_sdk/models/bot_info_confidence.py index 9171d4d3..89cb08af 100644 --- a/fingerprint_server_sdk/models/bot_info_confidence.py +++ b/fingerprint_server_sdk/models/bot_info_confidence.py @@ -43,5 +43,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_info_identity.py b/fingerprint_server_sdk/models/bot_info_identity.py index 9e4321d0..2aeb8e4f 100644 --- a/fingerprint_server_sdk/models/bot_info_identity.py +++ b/fingerprint_server_sdk/models/bot_info_identity.py @@ -44,5 +44,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/bot_result.py b/fingerprint_server_sdk/models/bot_result.py index 9b5ae50b..545a5b05 100644 --- a/fingerprint_server_sdk/models/bot_result.py +++ b/fingerprint_server_sdk/models/bot_result.py @@ -43,5 +43,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/error_code.py b/fingerprint_server_sdk/models/error_code.py index a7deb875..1655e282 100644 --- a/fingerprint_server_sdk/models/error_code.py +++ b/fingerprint_server_sdk/models/error_code.py @@ -58,5 +58,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/incremental_identification_status.py b/fingerprint_server_sdk/models/incremental_identification_status.py index 800bde27..397c035b 100644 --- a/fingerprint_server_sdk/models/incremental_identification_status.py +++ b/fingerprint_server_sdk/models/incremental_identification_status.py @@ -42,5 +42,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/proxy_confidence.py b/fingerprint_server_sdk/models/proxy_confidence.py index 00104445..ae833aea 100644 --- a/fingerprint_server_sdk/models/proxy_confidence.py +++ b/fingerprint_server_sdk/models/proxy_confidence.py @@ -43,5 +43,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py index f9dad983..1c9120be 100644 --- a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py @@ -46,5 +46,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/rule_action_type.py b/fingerprint_server_sdk/models/rule_action_type.py index 3b0bdc07..3e078f68 100644 --- a/fingerprint_server_sdk/models/rule_action_type.py +++ b/fingerprint_server_sdk/models/rule_action_type.py @@ -42,5 +42,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_bot.py b/fingerprint_server_sdk/models/search_events_bot.py index ce35589c..1bcdfd8e 100644 --- a/fingerprint_server_sdk/models/search_events_bot.py +++ b/fingerprint_server_sdk/models/search_events_bot.py @@ -44,5 +44,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_bot_info.py b/fingerprint_server_sdk/models/search_events_bot_info.py index 42d6e9af..6e80098d 100644 --- a/fingerprint_server_sdk/models/search_events_bot_info.py +++ b/fingerprint_server_sdk/models/search_events_bot_info.py @@ -42,5 +42,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py index 5e690c53..7469293d 100644 --- a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py +++ b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py @@ -42,5 +42,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py index 6cd5b950..de9cd812 100644 --- a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py @@ -46,5 +46,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_sdk_platform.py b/fingerprint_server_sdk/models/search_events_sdk_platform.py index 16e05867..9d498aa3 100644 --- a/fingerprint_server_sdk/models/search_events_sdk_platform.py +++ b/fingerprint_server_sdk/models/search_events_sdk_platform.py @@ -43,5 +43,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/search_events_vpn_confidence.py b/fingerprint_server_sdk/models/search_events_vpn_confidence.py index 96c7f8ee..a0d15163 100644 --- a/fingerprint_server_sdk/models/search_events_vpn_confidence.py +++ b/fingerprint_server_sdk/models/search_events_vpn_confidence.py @@ -43,5 +43,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/tampering_confidence.py b/fingerprint_server_sdk/models/tampering_confidence.py index daa6e48f..719073fe 100644 --- a/fingerprint_server_sdk/models/tampering_confidence.py +++ b/fingerprint_server_sdk/models/tampering_confidence.py @@ -43,5 +43,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/fingerprint_server_sdk/models/vpn_confidence.py b/fingerprint_server_sdk/models/vpn_confidence.py index 75c88b45..c6fd5d48 100644 --- a/fingerprint_server_sdk/models/vpn_confidence.py +++ b/fingerprint_server_sdk/models/vpn_confidence.py @@ -43,5 +43,6 @@ def _missing_(cls, value: object) -> Self: obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj diff --git a/template/model_enum.mustache b/template/model_enum.mustache index cf7a18cb..72e9d381 100644 --- a/template/model_enum.mustache +++ b/template/model_enum.mustache @@ -33,6 +33,7 @@ class {{classname}}({{vendorExtensions.x-py-enum-type}}, Enum): obj = {{vendorExtensions.x-py-enum-type}}.__new__(cls, value) obj._name_ = str(value) obj._value_ = value + # cache it so the same value won't trigger `_missing_` again cls._value2member_map_[value] = obj return obj {{/allowableValues}}