Skip to content

Commit 6ad5864

Browse files
Adding decimal support for python client generation (#19203)
* Adding decimal to template for Python generator * Rerunning the build steps * Add tests for decimal serialization and deserialization. * Move test to python not legacy pydantic sample * readd old imports --------- Co-authored-by: Adam <[email protected]>
1 parent fef84d9 commit 6ad5864

File tree

7 files changed

+51
-0
lines changed

7 files changed

+51
-0
lines changed

modules/openapi-generator/src/main/resources/python/api_client.mustache

+7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import datetime
66
from dateutil.parser import parse
77
from enum import Enum
8+
import decimal
89
import json
910
import mimetypes
1011
import os
@@ -59,6 +60,7 @@ class ApiClient:
5960
'bool': bool,
6061
'date': datetime.date,
6162
'datetime': datetime.datetime,
63+
'decimal': decimal.Decimal,
6264
'object': object,
6365
}
6466
_pool = None
@@ -346,6 +348,7 @@ class ApiClient:
346348
If obj is str, int, long, float, bool, return directly.
347349
If obj is datetime.datetime, datetime.date
348350
convert to string in iso8601 format.
351+
If obj is decimal.Decimal return string representation.
349352
If obj is list, sanitize each element in the list.
350353
If obj is dict, return the dict.
351354
If obj is OpenAPI model, return the properties dict.
@@ -371,6 +374,8 @@ class ApiClient:
371374
)
372375
elif isinstance(obj, (datetime.datetime, datetime.date)):
373376
return obj.isoformat()
377+
elif isinstance(obj, decimal.Decimal):
378+
return str(obj)
374379

375380
elif isinstance(obj, dict):
376381
obj_dict = obj
@@ -462,6 +467,8 @@ class ApiClient:
462467
return self.__deserialize_date(data)
463468
elif klass == datetime.datetime:
464469
return self.__deserialize_datetime(data)
470+
elif klass == decimal.Decimal:
471+
return decimal.Decimal(data)
465472
elif issubclass(klass, Enum):
466473
return self.__deserialize_enum(data, klass)
467474
else:

samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api_client.py

+7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import datetime
1717
from dateutil.parser import parse
1818
from enum import Enum
19+
import decimal
1920
import json
2021
import mimetypes
2122
import os
@@ -67,6 +68,7 @@ class ApiClient:
6768
'bool': bool,
6869
'date': datetime.date,
6970
'datetime': datetime.datetime,
71+
'decimal': decimal.Decimal,
7072
'object': object,
7173
}
7274
_pool = None
@@ -339,6 +341,7 @@ def sanitize_for_serialization(self, obj):
339341
If obj is str, int, long, float, bool, return directly.
340342
If obj is datetime.datetime, datetime.date
341343
convert to string in iso8601 format.
344+
If obj is decimal.Decimal return string representation.
342345
If obj is list, sanitize each element in the list.
343346
If obj is dict, return the dict.
344347
If obj is OpenAPI model, return the properties dict.
@@ -364,6 +367,8 @@ def sanitize_for_serialization(self, obj):
364367
)
365368
elif isinstance(obj, (datetime.datetime, datetime.date)):
366369
return obj.isoformat()
370+
elif isinstance(obj, decimal.Decimal):
371+
return str(obj)
367372

368373
elif isinstance(obj, dict):
369374
obj_dict = obj
@@ -455,6 +460,8 @@ def __deserialize(self, data, klass):
455460
return self.__deserialize_date(data)
456461
elif klass == datetime.datetime:
457462
return self.__deserialize_datetime(data)
463+
elif klass == decimal.Decimal:
464+
return decimal.Decimal(data)
458465
elif issubclass(klass, Enum):
459466
return self.__deserialize_enum(data, klass)
460467
else:

samples/client/echo_api/python/openapi_client/api_client.py

+7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import datetime
1717
from dateutil.parser import parse
1818
from enum import Enum
19+
import decimal
1920
import json
2021
import mimetypes
2122
import os
@@ -67,6 +68,7 @@ class ApiClient:
6768
'bool': bool,
6869
'date': datetime.date,
6970
'datetime': datetime.datetime,
71+
'decimal': decimal.Decimal,
7072
'object': object,
7173
}
7274
_pool = None
@@ -339,6 +341,7 @@ def sanitize_for_serialization(self, obj):
339341
If obj is str, int, long, float, bool, return directly.
340342
If obj is datetime.datetime, datetime.date
341343
convert to string in iso8601 format.
344+
If obj is decimal.Decimal return string representation.
342345
If obj is list, sanitize each element in the list.
343346
If obj is dict, return the dict.
344347
If obj is OpenAPI model, return the properties dict.
@@ -364,6 +367,8 @@ def sanitize_for_serialization(self, obj):
364367
)
365368
elif isinstance(obj, (datetime.datetime, datetime.date)):
366369
return obj.isoformat()
370+
elif isinstance(obj, decimal.Decimal):
371+
return str(obj)
367372

368373
elif isinstance(obj, dict):
369374
obj_dict = obj
@@ -455,6 +460,8 @@ def __deserialize(self, data, klass):
455460
return self.__deserialize_date(data)
456461
elif klass == datetime.datetime:
457462
return self.__deserialize_datetime(data)
463+
elif klass == decimal.Decimal:
464+
return decimal.Decimal(data)
458465
elif issubclass(klass, Enum):
459466
return self.__deserialize_enum(data, klass)
460467
else:

samples/openapi3/client/petstore/python-aiohttp/petstore_api/api_client.py

+7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import datetime
1616
from dateutil.parser import parse
1717
from enum import Enum
18+
import decimal
1819
import json
1920
import mimetypes
2021
import os
@@ -66,6 +67,7 @@ class ApiClient:
6667
'bool': bool,
6768
'date': datetime.date,
6869
'datetime': datetime.datetime,
70+
'decimal': decimal.Decimal,
6971
'object': object,
7072
}
7173
_pool = None
@@ -341,6 +343,7 @@ def sanitize_for_serialization(self, obj):
341343
If obj is str, int, long, float, bool, return directly.
342344
If obj is datetime.datetime, datetime.date
343345
convert to string in iso8601 format.
346+
If obj is decimal.Decimal return string representation.
344347
If obj is list, sanitize each element in the list.
345348
If obj is dict, return the dict.
346349
If obj is OpenAPI model, return the properties dict.
@@ -366,6 +369,8 @@ def sanitize_for_serialization(self, obj):
366369
)
367370
elif isinstance(obj, (datetime.datetime, datetime.date)):
368371
return obj.isoformat()
372+
elif isinstance(obj, decimal.Decimal):
373+
return str(obj)
369374

370375
elif isinstance(obj, dict):
371376
obj_dict = obj
@@ -457,6 +462,8 @@ def __deserialize(self, data, klass):
457462
return self.__deserialize_date(data)
458463
elif klass == datetime.datetime:
459464
return self.__deserialize_datetime(data)
465+
elif klass == decimal.Decimal:
466+
return decimal.Decimal(data)
460467
elif issubclass(klass, Enum):
461468
return self.__deserialize_enum(data, klass)
462469
else:

samples/openapi3/client/petstore/python/petstore_api/api_client.py

+7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import datetime
1616
from dateutil.parser import parse
1717
from enum import Enum
18+
import decimal
1819
import json
1920
import mimetypes
2021
import os
@@ -66,6 +67,7 @@ class ApiClient:
6667
'bool': bool,
6768
'date': datetime.date,
6869
'datetime': datetime.datetime,
70+
'decimal': decimal.Decimal,
6971
'object': object,
7072
}
7173
_pool = None
@@ -338,6 +340,7 @@ def sanitize_for_serialization(self, obj):
338340
If obj is str, int, long, float, bool, return directly.
339341
If obj is datetime.datetime, datetime.date
340342
convert to string in iso8601 format.
343+
If obj is decimal.Decimal return string representation.
341344
If obj is list, sanitize each element in the list.
342345
If obj is dict, return the dict.
343346
If obj is OpenAPI model, return the properties dict.
@@ -363,6 +366,8 @@ def sanitize_for_serialization(self, obj):
363366
)
364367
elif isinstance(obj, (datetime.datetime, datetime.date)):
365368
return obj.isoformat()
369+
elif isinstance(obj, decimal.Decimal):
370+
return str(obj)
366371

367372
elif isinstance(obj, dict):
368373
obj_dict = obj
@@ -454,6 +459,8 @@ def __deserialize(self, data, klass):
454459
return self.__deserialize_date(data)
455460
elif klass == datetime.datetime:
456461
return self.__deserialize_datetime(data)
462+
elif klass == decimal.Decimal:
463+
return decimal.Decimal(data)
457464
elif issubclass(klass, Enum):
458465
return self.__deserialize_enum(data, klass)
459466
else:

samples/openapi3/client/petstore/python/tests/test_api_client.py

+6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"""
1111

1212
import unittest
13+
from decimal import Decimal
1314
from enum import Enum
1415

1516
from dateutil.parser import parse
@@ -180,6 +181,11 @@ def test_sanitize_for_serialization_datetime(self):
180181
result = self.api_client.sanitize_for_serialization(data)
181182
self.assertEqual(result, "1997-07-16T19:20:30.450000+01:00")
182183

184+
def test_sanitize_for_serialization_decimal(self):
185+
data = Decimal("1.0")
186+
result = self.api_client.sanitize_for_serialization(data)
187+
self.assertEquals(result, "1.0")
188+
183189
def test_sanitize_for_serialization_list_enum(self):
184190
class EnumSerialization(int, Enum):
185191
NUMBER_0 = 0

samples/openapi3/client/petstore/python/tests/test_deserialization.py

+10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import time
1515
import unittest
1616
import datetime
17+
from decimal import Decimal
1718

1819
import pytest as pytest
1920

@@ -130,6 +131,15 @@ def test_deserialize_datetime(self):
130131
deserialized = self.deserialize(response, "datetime", 'application/json')
131132
self.assertTrue(isinstance(deserialized, datetime.datetime))
132133

134+
def test_deserialize_decimal(self):
135+
""" deserialize decimal """
136+
data = 1.1
137+
response = json.dumps(data)
138+
139+
deserialized = self.deserialize(response, "decimal", 'application/json')
140+
self.assertTrue(isinstance(deserialized, Decimal))
141+
self.assertEqual(deserialized, Decimal(1.1))
142+
133143
def test_deserialize_pet(self):
134144
""" deserialize pet """
135145
data = {

0 commit comments

Comments
 (0)