Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UUID format support #1743

Merged
merged 25 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0446f0f
change formatter
HantingZhang2 Sep 15, 2023
f1934d9
Adds UUID type
HantingZhang2 Sep 20, 2023
696f0a0
Merge branch 'master' into hzhang/add_uuid_type
HantingZhang2 Sep 20, 2023
a57e8a3
change uuid order
HantingZhang2 Sep 20, 2023
bd64905
pre-commit fixes
Sep 20, 2023
fa3a42d
Update api template
HantingZhang2 Sep 22, 2023
126d45e
Merge branch 'master' into hzhang/add_uuid_type
HantingZhang2 Sep 22, 2023
d713b06
Update openapi.yaml remove added format
HantingZhang2 Sep 22, 2023
c6c97cd
pre-commit fixes
Sep 22, 2023
69e433e
add de/serialization tests
HantingZhang2 Sep 25, 2023
205d65c
Merge branch 'master' into hzhang/add_uuid_type
HantingZhang2 Sep 25, 2023
87dfd00
pre-commit fixes
Sep 25, 2023
428f6c8
test if adding format
HantingZhang2 Sep 25, 2023
c1cd31f
pre-commit fixes
Sep 25, 2023
cdb9b85
Merge master into datadog-api-spec/test/hzhang/user-invitation-test-uuid
api-clients-generation-pipeline[bot] Sep 26, 2023
84e0155
Merge master into datadog-api-spec/test/hzhang/user-invitation-test-uuid
api-clients-generation-pipeline[bot] Sep 28, 2023
861d3e1
Merge branch 'master' into datadog-api-spec/test/hzhang/user-invitati…
HantingZhang2 Sep 29, 2023
06fba5c
remove open api change
HantingZhang2 Sep 29, 2023
01d90e8
Merge branch 'master' into datadog-api-spec/test/hzhang/user-invitati…
HantingZhang2 Oct 23, 2023
d6e0ed3
Merge master into datadog-api-spec/test/hzhang/user-invitation-test-uuid
api-clients-generation-pipeline[bot] Oct 24, 2023
f03a4ef
Merge branch 'master' into datadog-api-spec/test/hzhang/user-invitati…
HantingZhang2 Oct 25, 2023
bae4ccb
Raise the error instead of print
HantingZhang2 Oct 26, 2023
2135adb
Merge branch 'master' into datadog-api-spec/test/hzhang/user-invitati…
HantingZhang2 Oct 26, 2023
b2f974b
Merge branch 'master' into hzhang/user-invitation-test-uuid
HantingZhang2 Oct 27, 2023
f6a5dbf
pre-commit fixes
Oct 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .generator/src/generator/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import keyword
import warnings
import re

from uuid import UUID
import dateutil.parser
import m2r2

Expand Down Expand Up @@ -296,6 +296,11 @@ def format_datetime(x):
if "tzoffset" in result:
imports["dateutil.tz"].add("tzoffset")
return result

def format_uuid(x):
imports["uuid"].add("UUID")
result = repr(UUID(x))
return result

formatter = {
"double": lambda s: repr(float(s)),
Expand All @@ -305,7 +310,8 @@ def format_datetime(x):
"date-time": format_datetime,
"binary": lambda s: f'open("{s}", "rb")',
"email": repr,
None: repr,
"uuid": format_uuid,
None: repr,
}[schema.get("format")]

# TODO format date and datetime
Expand Down
4 changes: 3 additions & 1 deletion .generator/src/generator/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def basic_type_to_python(type_, schema, typing=False):
if type_ is None:
if typing:
return "Any"
return "bool, date, datetime, dict, float, int, list, str, none_type"
return "bool, date, datetime, dict, float, int, list, str, UUID, none_type"
if type_ == "integer":
return "int"
elif type_ == "number":
Expand All @@ -35,6 +35,8 @@ def basic_type_to_python(type_, schema, typing=False):
return "datetime"
elif format_ == "binary":
return "file_type"
elif format_ == "uuid":
return "UUID"
return "str"
elif type_ == "boolean":
return "bool"
Expand Down
1 change: 1 addition & 0 deletions .generator/src/generator/templates/api.j2
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ from {{ package }}.model_utils import (
none_type,
UnsetType,
unset,
UUID,
)
{%- for model in get_api_models(operations) %}
from {{ package }}.{{ version }}.model.{{ model|safe_snake_case }} import {{ model }}
Expand Down
3 changes: 3 additions & 0 deletions .generator/src/generator/templates/api_client.j2
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import warnings
import multiprocessing
from multiprocessing.pool import ThreadPool
from datetime import date, datetime
from uuid import UUID
import io
import os
import re
Expand Down Expand Up @@ -177,6 +178,8 @@ class ApiClient:
if getattr(obj, "tzinfo", None) is not None:
return obj.isoformat()
return "{}Z".format(obj.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3])
elif isinstance(obj, UUID ):
return str(obj)
elif isinstance(obj, ModelSimple):
return cls.sanitize_for_serialization(obj.value)
elif isinstance(obj, (list, tuple)):
Expand Down
1 change: 1 addition & 0 deletions .generator/src/generator/templates/model.j2
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ from {{ package }}.model_utils import (
none_type,
unset,
UnsetType,
UUID,
)

{% if "enum" in model -%}
Expand Down
27 changes: 20 additions & 7 deletions .generator/src/generator/templates/model_utils.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from contextlib import suppress
from datetime import date, datetime
from uuid import UUID
import enum
import inspect
import io
Expand Down Expand Up @@ -52,7 +53,7 @@ class cached_property(object):
return result


PRIMITIVE_TYPES = (list, float, int, bool, datetime, date, str, file_type)
PRIMITIVE_TYPES = (list, float, int, bool, datetime, date, str, UUID, file_type)


def allows_single_value_input(cls):
Expand Down Expand Up @@ -567,7 +568,8 @@ COERCION_INDEX_BY_TYPE = {
datetime: 9,
date: 10,
str: 11,
file_type: 12, # 'file_type' is an alias for the built-in 'file' or 'io.IOBase' type.
UUID: 12,
file_type: 13, # 'file_type' is an alias for the built-in 'file' or 'io.IOBase' type.
}

# these are used to limit what type conversions we try to do
Expand All @@ -576,6 +578,7 @@ COERCION_INDEX_BY_TYPE = {
UPCONVERSION_TYPE_PAIRS = (
(str, datetime),
(str, date),
(str, UUID),
(int, float), # A float may be serialized as an integer, e.g. '3' is a valid serialized float.
(list, ModelComposed),
(dict, ModelComposed),
Expand Down Expand Up @@ -624,6 +627,7 @@ COERCIBLE_TYPE_PAIRS = {
# (str, float),
(str, datetime),
(str, date),
(str, UUID),
# (int, str),
# (float, str),
(str, file_type),
Expand Down Expand Up @@ -664,6 +668,8 @@ def get_simple_class(input_value):
return date
elif isinstance(input_value, str):
return str
elif isinstance(input_value, UUID):
return UUID
return type(input_value)


Expand All @@ -675,7 +681,7 @@ def check_allowed_values(allowed_values, input_variable, input_values):
:type input_variable: str
:param input_values: The values that we are checking to see if they are in
allowed_values.
:type input_values: list/str/int/float/date/datetime
:type input_values: list/str/int/float/date/datetime/uuid
"""
if isinstance(input_values, list) and not set(input_values).issubset(allowed_values):
invalid_values = (", ".join(map(str, set(input_values) - allowed_values)),)
Expand Down Expand Up @@ -721,7 +727,7 @@ def check_validations(validations, input_variable, input_values, configuration=N
:param input_variable: The name of the input variable.
:type input_variable: str
:param input_values: The values that we are checking.
:type input_values: list/str/int/float/date/datetime
:type input_values: list/str/int/float/date/datetime/uuid
:param configuration: The configuration instance.
:type configuration: Configuration
"""
Expand Down Expand Up @@ -1014,7 +1020,7 @@ def deserialize_primitive(data, klass, path_to_item):
:param klass: The class to convert to.
:type klass: str/class

:rtype: int, float, str, bool, date, datetime
:rtype: int, float, str, bool, date, datetime, UUID
"""
additional_message = ""
try:
Expand Down Expand Up @@ -1042,11 +1048,18 @@ def deserialize_primitive(data, klass, path_to_item):
raise ValueError("This is not a date")
return parse(data).date()
else:
converted_value = klass(data)
if isinstance(data, str) and klass == UUID:
try:
converted_value = UUID(data)
except ValueError:
raise ValueError("This is not an UUID")
if isinstance(data, str) and klass == float:
converted_value = float(data)
if str(converted_value) != data:
# '7' -> 7.0 -> '7.0' != '7'
raise ValueError("This is not a float")
else:
converted_value = klass(data)
return converted_value
except (OverflowError, ValueError) as ex:
# parse can raise OverflowError
Expand Down Expand Up @@ -1479,7 +1492,7 @@ def get_oneof_instance(cls, model_kwargs, constant_kwargs, model_arg=None):
Notes:
- this is only passed in when oneOf includes types which are not object
- None is used to suppress handling of model_arg, nullable models are handled in __new__
:type model_arg: int, float, bool, str, date, datetime, ModelSimple, None
:type model_arg: int, float, bool, str, date, datetime, ModelSimple, UUID, None
"""
if len(cls._composed_schemas["oneOf"]) == 0:
return None
Expand Down
3 changes: 3 additions & 0 deletions src/datadog_api_client/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import multiprocessing
from multiprocessing.pool import ThreadPool
from datetime import date, datetime
from uuid import UUID
import io
import os
import re
Expand Down Expand Up @@ -179,6 +180,8 @@ def sanitize_for_serialization(cls, obj):
if getattr(obj, "tzinfo", None) is not None:
return obj.isoformat()
return "{}Z".format(obj.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3])
elif isinstance(obj, UUID):
return str(obj)
elif isinstance(obj, ModelSimple):
return cls.sanitize_for_serialization(obj.value)
elif isinstance(obj, (list, tuple)):
Expand Down
27 changes: 20 additions & 7 deletions src/datadog_api_client/model_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from contextlib import suppress
from datetime import date, datetime
from uuid import UUID
import enum
import inspect
import io
Expand Down Expand Up @@ -54,7 +55,7 @@ def __get__(self, instance, cls=None):
return result


PRIMITIVE_TYPES = (list, float, int, bool, datetime, date, str, file_type)
PRIMITIVE_TYPES = (list, float, int, bool, datetime, date, str, UUID, file_type)


def allows_single_value_input(cls):
Expand Down Expand Up @@ -570,7 +571,8 @@ def __eq__(self, other):
datetime: 9,
date: 10,
str: 11,
file_type: 12, # 'file_type' is an alias for the built-in 'file' or 'io.IOBase' type.
UUID: 12,
file_type: 13, # 'file_type' is an alias for the built-in 'file' or 'io.IOBase' type.
}

# these are used to limit what type conversions we try to do
Expand All @@ -579,6 +581,7 @@ def __eq__(self, other):
UPCONVERSION_TYPE_PAIRS = (
(str, datetime),
(str, date),
(str, UUID),
(int, float), # A float may be serialized as an integer, e.g. '3' is a valid serialized float.
(list, ModelComposed),
(dict, ModelComposed),
Expand Down Expand Up @@ -627,6 +630,7 @@ def __eq__(self, other):
# (str, float),
(str, datetime),
(str, date),
(str, UUID),
# (int, str),
# (float, str),
(str, file_type),
Expand Down Expand Up @@ -667,6 +671,8 @@ def get_simple_class(input_value):
return date
elif isinstance(input_value, str):
return str
elif isinstance(input_value, UUID):
return UUID
return type(input_value)


Expand All @@ -678,7 +684,7 @@ def check_allowed_values(allowed_values, input_variable, input_values):
:type input_variable: str
:param input_values: The values that we are checking to see if they are in
allowed_values.
:type input_values: list/str/int/float/date/datetime
:type input_values: list/str/int/float/date/datetime/uuid
"""
if isinstance(input_values, list) and not set(input_values).issubset(allowed_values):
invalid_values = (", ".join(map(str, set(input_values) - allowed_values)),)
Expand Down Expand Up @@ -724,7 +730,7 @@ def check_validations(validations, input_variable, input_values, configuration=N
:param input_variable: The name of the input variable.
:type input_variable: str
:param input_values: The values that we are checking.
:type input_values: list/str/int/float/date/datetime
:type input_values: list/str/int/float/date/datetime/uuid
:param configuration: The configuration instance.
:type configuration: Configuration
"""
Expand Down Expand Up @@ -1017,7 +1023,7 @@ def deserialize_primitive(data, klass, path_to_item):
:param klass: The class to convert to.
:type klass: str/class

:rtype: int, float, str, bool, date, datetime
:rtype: int, float, str, bool, date, datetime, UUID
"""
additional_message = ""
try:
Expand Down Expand Up @@ -1045,11 +1051,18 @@ def deserialize_primitive(data, klass, path_to_item):
raise ValueError("This is not a date")
return parse(data).date()
else:
converted_value = klass(data)
if isinstance(data, str) and klass == UUID:
try:
converted_value = UUID(data)
except ValueError:
raise ValueError("This is not an UUID")
if isinstance(data, str) and klass == float:
converted_value = float(data)
if str(converted_value) != data:
# '7' -> 7.0 -> '7.0' != '7'
raise ValueError("This is not a float")
else:
converted_value = klass(data)
return converted_value
except (OverflowError, ValueError) as ex:
# parse can raise OverflowError
Expand Down Expand Up @@ -1482,7 +1495,7 @@ def get_oneof_instance(cls, model_kwargs, constant_kwargs, model_arg=None):
Notes:
- this is only passed in when oneOf includes types which are not object
- None is used to suppress handling of model_arg, nullable models are handled in __new__
:type model_arg: int, float, bool, str, date, datetime, ModelSimple, None
:type model_arg: int, float, bool, str, date, datetime, ModelSimple, UUID, None
"""
if len(cls._composed_schemas["oneOf"]) == 0:
return None
Expand Down
5 changes: 3 additions & 2 deletions src/datadog_api_client/v1/model/agent_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
date,
datetime,
none_type,
UUID,
)


Expand All @@ -18,11 +19,11 @@ class AgentCheck(ModelSimple):
Array of strings.


:type value: [bool, date, datetime, dict, float, int, list, str, none_type]
:type value: [bool, date, datetime, dict, float, int, list, str, UUID, none_type]
"""

@cached_property
def openapi_types(_):
return {
"value": ([bool, date, datetime, dict, float, int, list, str, none_type],),
"value": ([bool, date, datetime, dict, float, int, list, str, UUID, none_type],),
}
Loading