Skip to content

Commit 8dd9ef4

Browse files
committed
fix: generate top-level array schemas typed lists
1 parent b807611 commit 8dd9ef4

7 files changed

Lines changed: 64 additions & 6 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"fingerprint-pro-server-api-python-sdk": patch
3+
---
4+
5+
**events**: Fix parsing of `GeolocationSubdivisions` so `subdivisions` returns a typed list of `GeolocationSubdivision`

fingerprint_pro_server_api_sdk/api_client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,12 @@ def __deserialize_model(data, klass):
590590
if not klass.swagger_types and not ApiClientDeserializer.__hasattr(klass, 'get_real_child_model'):
591591
if hasattr(klass, '__parent_class__') and klass.__parent_class__ == 'dict':
592592
return klass(**data)
593+
if hasattr(klass, '__parent_class__') and klass.__parent_class__ == 'list':
594+
item_type = getattr(klass, '__list_item_type__', None)
595+
if item_type is not None and isinstance(data, list):
596+
return klass(ApiClientDeserializer.deserialize(sub_data, item_type)
597+
for sub_data in data)
598+
return klass(data)
593599
return data
594600

595601
kwargs = {}

fingerprint_pro_server_api_sdk/models/geolocation_subdivisions.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from fingerprint_pro_server_api_sdk.base_model import BaseModel
1616

1717

18-
class GeolocationSubdivisions(BaseModel):
18+
class GeolocationSubdivisions(list):
1919
"""NOTE: This class is auto generated by the swagger code generator program.
2020
2121
Do not edit the class manually.
@@ -36,7 +36,6 @@ class GeolocationSubdivisions(BaseModel):
3636
attribute_map = {
3737
}
3838

39-
def __init__(self): # noqa: E501
40-
"""GeolocationSubdivisions - a model defined in Swagger""" # noqa: E501
41-
self.discriminator = None
39+
__parent_class__ = 'list'
40+
__list_item_type__ = 'GeolocationSubdivision'
4241

template/api_client.mustache

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,12 @@ class ApiClientDeserializer:
582582
if not klass.swagger_types and not ApiClientDeserializer.__hasattr(klass, 'get_real_child_model'):
583583
if hasattr(klass, '__parent_class__') and klass.__parent_class__ == 'dict':
584584
return klass(**data)
585+
if hasattr(klass, '__parent_class__') and klass.__parent_class__ == 'list':
586+
item_type = getattr(klass, '__list_item_type__', None)
587+
if item_type is not None and isinstance(data, list):
588+
return klass(ApiClientDeserializer.deserialize(sub_data, item_type)
589+
for sub_data in data)
590+
return klass(data)
585591
return data
586592

587593
kwargs = {}

template/model.mustache

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ from typing_extensions import deprecated
2323
{{#schema.deprecated}}
2424
@deprecated("This class is deprecated. Please avoid using it in new code.")
2525
{{/schema.deprecated}}
26-
class {{classname}}({{#parent}}{{parent}}{{/parent}}{{^parent}}BaseModel{{/parent}}):
26+
class {{classname}}({{#isArrayModel}}list{{/isArrayModel}}{{^isArrayModel}}{{#parent}}{{parent}}{{/parent}}{{^parent}}BaseModel{{/parent}}{{/isArrayModel}}):
2727
"""{{#description}}
2828
{{{.}}}
2929

@@ -72,6 +72,11 @@ class {{classname}}({{#parent}}{{parent}}{{/parent}}{{^parent}}BaseModel{{/paren
7272
}
7373
{{/discriminator}}
7474

75+
{{#isArrayModel}}
76+
__parent_class__ = 'list'
77+
__list_item_type__ = '{{{arrayModelType}}}'
78+
{{/isArrayModel}}
79+
{{^isArrayModel}}
7580
{{#parent}}
7681
__parent_class__ = '{{parent}}'
7782
{{/parent}}
@@ -85,6 +90,7 @@ class {{classname}}({{#parent}}{{parent}}{{/parent}}{{^parent}}BaseModel{{/paren
8590
{{/vars}}
8691
self.discriminator = {{#discriminator}}'{{discriminator}}'{{/discriminator}}{{^discriminator}}None{{/discriminator}}
8792
{{/parent}}
93+
{{/isArrayModel}}
8894
{{#vars}}{{#@first}}
8995
{{/@first}}
9096
{{#required}}

test/test_base_model.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,31 @@ def test_to_dict_with_dict_of_models(self):
9191
}
9292
self.assertEqual(model.to_dict(), expected)
9393

94+
def test_to_dict_with_list_of_models(self):
95+
"""Test conversion to dictionary when a list attribute holds models.
96+
97+
This mirrors how array schemas (e.g. GeolocationSubdivisions) expose a
98+
list of typed items that each must be serialized via to_dict().
99+
"""
100+
model = ExampleModel(
101+
name="Test Model",
102+
details={"key": "value"},
103+
items=[SubModel(id=1, value="first"), SubModel(id=2, value="second")],
104+
sub_model=self.sub_model,
105+
)
106+
expected = {
107+
'name': "Test Model",
108+
'details': {"key": "value"},
109+
'items': [{'id': 1, 'value': 'first'}, {'id': 2, 'value': 'second'}],
110+
'sub_model': {'id': 1, 'value': 'sub_value'},
111+
}
112+
self.assertEqual(model.to_dict(), expected)
113+
114+
def test_to_dict_with_list_of_mixed_items(self):
115+
"""Test that a list mixing models and primitives serializes each correctly."""
116+
model = ExampleModel(items=[SubModel(id=1, value="first"), "plain", 3])
117+
self.assertEqual(model.to_dict(), {'items': [{'id': 1, 'value': 'first'}, "plain", 3]})
118+
94119
def test_to_str(self):
95120
"""Test conversion to string."""
96121
expected_str = pprint.pformat(self.model.to_dict())

test/test_fingerprint_api.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818

1919
from fingerprint_pro_server_api_sdk import (Configuration, ErrorResponse, ErrorPlainResponse, ErrorCode,
2020
RawDeviceAttributes, EventsUpdateRequest, RelatedVisitorsResponse,
21-
SearchEventsResponse, SearchEventsResponseEvents, Products)
21+
SearchEventsResponse, SearchEventsResponseEvents, Products,
22+
GeolocationSubdivisions, GeolocationSubdivision)
2223
from fingerprint_pro_server_api_sdk.api.fingerprint_api import FingerprintApi # noqa: E501
2324
from fingerprint_pro_server_api_sdk.rest import KnownApiException, ApiException
2425
from urllib.parse import urlencode
@@ -274,6 +275,16 @@ def test_get_event_correct_data(self):
274275
self.assertIsNone(event_response_dict["products"]["identification"]["data"]["last_seen_at"]["subscription"])
275276
self.assertIsInstance(event_response.products.raw_device_attributes.data, RawDeviceAttributes)
276277

278+
subdivisions = event_response.products.identification.data.ip_location.subdivisions
279+
self.assertIsInstance(subdivisions, GeolocationSubdivisions)
280+
self.assertEqual(len(subdivisions), 1)
281+
self.assertIsInstance(subdivisions[0], GeolocationSubdivision)
282+
self.assertEqual(subdivisions[0].iso_code, "63")
283+
self.assertEqual(subdivisions[0].name, "North Rhine-Westphalia")
284+
self.assertEqual(
285+
event_response_dict["products"]["identification"]["data"]["ip_location"]["subdivisions"],
286+
[{"iso_code": "63", "name": "North Rhine-Westphalia"}])
287+
277288
def test_get_event_errors_200(self):
278289
"""Test checks correct code run result in scenario of arrors in BotD or identification API"""
279290
mock_pool = MockPoolManager(self)

0 commit comments

Comments
 (0)