Skip to content

Commit 49a0dd9

Browse files
authored
Re-introduce array container models (#1503)
* Revert "Add back array models for compatibility (#1499)" This reverts commit 1c813ad. * re-add old models * generate * cleanup * add back list models to apis * fix naming * fix typing * fix more models and typing info * remove models that didnt exist in 2.12.0 * docs * cleanup generator * update examples * fix * fix Simple model unparsed * undo models added after 2.12.0
1 parent e0ef5af commit 49a0dd9

File tree

132 files changed

+1577
-979
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+1577
-979
lines changed

.generator/conftest.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
from generator import openapi
1919

20-
from generator.formatter import format_parameters, format_data_with_schema, safe_snake_case, snake_case
20+
from generator.formatter import format_parameters, format_data_with_schema, safe_snake_case, snake_case, set_api_version
2121

2222

2323
MODIFIED_FEATURES = {
@@ -156,6 +156,7 @@ def code_examples():
156156
@pytest.fixture
157157
def api_version(request):
158158
path = pathlib.Path(request.node.__scenario_report__.scenario.feature.filename)
159+
set_api_version(path.parent.parent.name)
159160
return path.parent.parent.name
160161

161162

.generator/src/generator/cli.py

+2-7
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ def cli(specs, output):
6464
models_j2 = env.get_template("models.j2")
6565
init_j2 = env.get_template("init.j2")
6666
configuration_j2 = env.get_template("configuration.j2")
67-
compat_j2 = env.get_template("compat.j2")
6867

6968
extra_files = {
7069
"api_client.py": env.get_template("api_client.j2"),
@@ -73,6 +72,7 @@ def cli(specs, output):
7372
"rest.py": env.get_template("rest.j2"),
7473
}
7574

75+
7676
top_package = output / PACKAGE_NAME
7777
top_package.mkdir(parents=True, exist_ok=True)
7878

@@ -90,6 +90,7 @@ def cli(specs, output):
9090

9191
version = spec_path.parent.name
9292
env.globals["version"] = version
93+
formatter.set_api_version(version)
9394

9495
all_specs[version] = spec
9596

@@ -141,9 +142,3 @@ def cli(specs, output):
141142
filename = top_package / "configuration.py"
142143
with filename.open("w") as fp:
143144
fp.write(configuration_j2.render(specs=all_specs, apis=all_apis))
144-
145-
with (pathlib.Path(__file__).parent / "compat-files").open() as fp:
146-
for compat_file in fp:
147-
compat_file, compat_model = compat_file.strip().split(":")
148-
with top_package.joinpath(compat_file).open("w") as model_fp:
149-
model_fp.write(compat_j2.render(model=compat_model))

.generator/src/generator/compat-files

-41
This file was deleted.

.generator/src/generator/formatter.py

+63
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,52 @@
2020
with replacement_file.open() as f:
2121
EDGE_CASES.update(json.load(f))
2222

23+
API_VERSION = None
24+
WHITELISTED_LIST_MODELS={
25+
"v1": (
26+
"AgentCheck",
27+
"AzureAccountListResponse",
28+
"DashboardBulkActionDataList",
29+
"DistributionPoint",
30+
"DistributionPointData",
31+
"GCPAccountListResponse",
32+
"HTTPLog",
33+
"LogsPipelineList",
34+
"MonitorSearchCount",
35+
"Point",
36+
"ServiceChecks",
37+
"SharedDashboardInvitesDataList",
38+
"SlackIntegrationChannels",
39+
"SyntheticsRestrictedRoles",
40+
"UsageAttributionAggregates",
41+
),
42+
"v2": (
43+
"CIAppAggregateBucketValueTimeseries",
44+
"EventsQueryGroupBys",
45+
"GroupTags",
46+
"HTTPLog",
47+
"IncidentTodoAssigneeArray",
48+
"LogsAggregateBucketValueTimeseries",
49+
"MetricBulkTagConfigEmailList",
50+
"MetricBulkTagConfigTagNameList",
51+
"MetricCustomAggregations",
52+
"MetricSuggestedAggregations",
53+
"RUMAggregateBucketValueTimeseries",
54+
"ScalarFormulaRequestQueries",
55+
"SecurityMonitoringSignalIncidentIds",
56+
"SensitiveDataScannerGetConfigIncludedArray",
57+
"SensitiveDataScannerStandardPatternsResponse",
58+
"TagsEventAttribute",
59+
"TeamPermissionSettingValues",
60+
"TimeseriesFormulaRequestQueries",
61+
"TimeseriesResponseSeriesList",
62+
"TimeseriesResponseTimes",
63+
"TimeseriesResponseValues",
64+
"TimeseriesResponseValuesList",
65+
66+
),
67+
}
68+
2369
KEYWORDS = set(keyword.kwlist)
2470
KEYWORDS.add("property")
2571
KEYWORDS.add("cls")
@@ -30,6 +76,15 @@
3076
PATTERN_WHITESPACE = re.compile(r"\W")
3177

3278

79+
def set_api_version(version):
80+
global API_VERSION
81+
API_VERSION = version
82+
83+
84+
def is_list_model_whitelisted(name):
85+
return name in WHITELISTED_LIST_MODELS[API_VERSION]
86+
87+
3388
def snake_case(value):
3489
s1 = PATTERN_LEADING_ALPHA.sub(r"\1_\2", value)
3590
s1 = PATTERN_FOLLOWING_ALPHA.sub(r"\1_\2", s1).lower()
@@ -237,7 +292,11 @@ def format_data_with_schema_list(
237292
):
238293
"""Format data with schema."""
239294
assert version is not None
295+
240296
imports = imports or defaultdict(set)
297+
name, r_imports = get_name_and_imports(schema, version, None)
298+
if is_list_model_whitelisted(name):
299+
imports.update(r_imports)
241300

242301
if "oneOf" in schema:
243302
for sub_schema in schema["oneOf"]:
@@ -246,6 +305,7 @@ def format_data_with_schema_list(
246305
data,
247306
sub_schema,
248307
replace_values=replace_values,
308+
default_name=name if is_list_model_whitelisted(name) else None,
249309
version=version,
250310
)
251311
except (KeyError, ValueError):
@@ -269,6 +329,9 @@ def format_data_with_schema_list(
269329
imports = _merge_imports(imports, extra_imports)
270330
parameters = f"[{parameters}]"
271331

332+
if name and is_list_model_whitelisted(name):
333+
return f"{name}({parameters})", imports
334+
272335
return parameters, imports
273336

274337

.generator/src/generator/openapi.py

+41-15
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from . import formatter
1212

13+
1314
PRIMITIVE_TYPES = ["string", "number", "boolean", "integer"]
1415

1516

@@ -24,7 +25,6 @@ def type_to_python_helper(type_, schema, alternative_name=None, in_list=False, t
2425
if typing:
2526
return "Any"
2627
return "bool, date, datetime, dict, float, int, list, str, none_type"
27-
2828
if type_ == "integer":
2929
return "int"
3030
elif type_ == "number":
@@ -71,11 +71,13 @@ def type_to_python_helper(type_, schema, alternative_name=None, in_list=False, t
7171

7272
def type_to_python(schema, alternative_name=None, in_list=False, typing=False):
7373
"""Return Python type name for the type."""
74+
7475
name = formatter.get_name(schema)
75-
if name and "items" not in schema:
76+
# TODO: double check
77+
if name and "items" not in schema or formatter.is_list_model_whitelisted(name):
7678
if "enum" in schema:
7779
return name
78-
if schema.get("type", "object") == "object":
80+
if schema.get("type", "object") == "object" or formatter.is_list_model_whitelisted(name):
7981
if typing and "oneOf" in schema:
8082
types = [name]
8183
types.extend(get_oneof_types(schema, typing=typing))
@@ -168,7 +170,7 @@ def child_models(schema, alternative_name=None, seen=None, in_list=False):
168170

169171
has_sub_models = False
170172
if "oneOf" in schema:
171-
has_sub_models = not in_list
173+
has_sub_models = not in_list and not formatter.is_list_model_whitelisted(name)
172174
for child in schema["oneOf"]:
173175
sub_models = list(child_models(child, seen=seen))
174176
if sub_models:
@@ -178,7 +180,12 @@ def child_models(schema, alternative_name=None, seen=None, in_list=False):
178180
return
179181

180182
if "items" in schema:
181-
yield from child_models(schema["items"], alternative_name=name + "Item" if name is not None else None, seen=seen, in_list=True)
183+
if formatter.is_list_model_whitelisted(name):
184+
alt_name = None
185+
else:
186+
alt_name = name + "Item" if name is not None else None
187+
188+
yield from child_models(schema["items"], alternative_name=alt_name, seen=seen, in_list=True)
182189

183190
if schema.get("type") == "object" or "properties" in schema or has_sub_models:
184191
if not has_sub_models and name is None:
@@ -202,6 +209,15 @@ def child_models(schema, alternative_name=None, seen=None, in_list=False):
202209
for key, child in schema.get("properties", {}).items():
203210
yield from child_models(child, alternative_name=name + formatter.camel_case(key), seen=seen)
204211

212+
if current_name and schema.get("type") == "array":
213+
if name in seen:
214+
return
215+
216+
if formatter.is_list_model_whitelisted(name):
217+
seen.add(name)
218+
yield name, schema
219+
220+
205221
if "enum" in schema:
206222
if name is None:
207223
raise ValueError(f"Schema {schema} has no name")
@@ -271,11 +287,17 @@ def get_references_for_model(model, model_name):
271287
if name:
272288
result[name] = None
273289
elif definition.get("type") == "array":
274-
name = formatter.get_name(definition.get("items"))
275-
if name and find_non_primitive_type(definition["items"]):
290+
name = formatter.get_name(definition)
291+
if name and formatter.is_list_model_whitelisted(name):
276292
result[name] = None
277-
elif formatter.get_name(definition) and definition["items"].get("type") not in PRIMITIVE_TYPES:
278-
result[formatter.get_name(definition) + "Item"] = None
293+
else:
294+
name = formatter.get_name(definition.get("items"))
295+
if name and find_non_primitive_type(definition["items"]):
296+
result[name] = None
297+
elif name and formatter.is_list_model_whitelisted(name):
298+
result[name] = None
299+
elif formatter.get_name(definition) and definition["items"].get("type") not in PRIMITIVE_TYPES:
300+
result[formatter.get_name(definition) + "Item"] = None
279301

280302
elif definition.get("properties") and top_name:
281303
result[top_name + formatter.camel_case(key)] = None
@@ -305,8 +327,10 @@ def get_oneof_references_for_model(model, model_name, seen=None):
305327
if model.get("oneOf"):
306328
for schema in model["oneOf"]:
307329
type_ = schema.get("type", "object")
308-
if type_ == "object":
309-
result[formatter.get_name(schema)] = None
330+
331+
oneof_name = formatter.get_name(schema)
332+
if type_ == "object" or formatter.is_list_model_whitelisted(oneof_name):
333+
result[oneof_name] = None
310334
elif type_ == "array":
311335
sub_name = formatter.get_name(schema["items"])
312336
if sub_name:
@@ -336,8 +360,9 @@ def get_oneof_parameters(model):
336360
def get_oneof_types(model, typing=False):
337361
for schema in model["oneOf"]:
338362
type_ = schema.get("type", "object")
339-
if type_ == "object":
340-
yield formatter.get_name(schema)
363+
name = formatter.get_name(schema)
364+
if type_ == "object" or formatter.is_list_model_whitelisted(name):
365+
yield name
341366
elif type_ == "array":
342367
name = formatter.get_name(schema["items"])
343368
if name:
@@ -361,8 +386,9 @@ def get_oneof_models(model):
361386
result = []
362387
for schema in model["oneOf"]:
363388
type_ = schema.get("type", "object")
364-
if type_ == "object":
365-
result.append(formatter.get_name(schema))
389+
name = formatter.get_name(schema)
390+
if type_ == "object" or formatter.is_list_model_whitelisted(name):
391+
result.append(name)
366392
elif type_ == "array":
367393
name = formatter.get_name(schema["items"])
368394
if name:

.generator/src/generator/templates/compat.j2

-12
This file was deleted.

.generator/src/generator/templates/model_utils.j2

+4-3
Original file line numberDiff line numberDiff line change
@@ -1527,9 +1527,10 @@ def get_oneof_instance(cls, model_kwargs, constant_kwargs, model_arg=None):
15271527
if list_oneof_instance:
15281528
oneof_instances.append(list_oneof_instance)
15291529
elif issubclass(oneof_class, ModelSimple):
1530-
oneof_instance = oneof_class(model_arg, **constant_kwargs)
1531-
if not oneof_instance._unparsed:
1532-
oneof_instances.append(oneof_instance)
1530+
if model_arg is not None:
1531+
oneof_instance = oneof_class(model_arg, **constant_kwargs)
1532+
if not oneof_instance._unparsed:
1533+
oneof_instances.append(oneof_instance)
15331534
elif oneof_class in PRIMITIVE_TYPES:
15341535
oneof_instance = validate_and_convert_types(
15351536
model_arg,

docs/datadog_api_client.v1.model.rst

-21
Original file line numberDiff line numberDiff line change
@@ -2052,13 +2052,6 @@ monitor\_search\_count
20522052
:members:
20532053
:show-inheritance:
20542054

2055-
monitor\_search\_count\_item
2056-
----------------------------
2057-
2058-
.. automodule:: datadog_api_client.v1.model.monitor_search_count_item
2059-
:members:
2060-
:show-inheritance:
2061-
20622055
monitor\_search\_response
20632056
-------------------------
20642057

@@ -2500,27 +2493,13 @@ notify\_end\_state
25002493
:members:
25012494
:show-inheritance:
25022495

2503-
notify\_end\_states
2504-
-------------------
2505-
2506-
.. automodule:: datadog_api_client.v1.model.notify_end_states
2507-
:members:
2508-
:show-inheritance:
2509-
25102496
notify\_end\_type
25112497
-----------------
25122498

25132499
.. automodule:: datadog_api_client.v1.model.notify_end_type
25142500
:members:
25152501
:show-inheritance:
25162502

2517-
notify\_end\_types
2518-
------------------
2519-
2520-
.. automodule:: datadog_api_client.v1.model.notify_end_types
2521-
:members:
2522-
:show-inheritance:
2523-
25242503
on\_missing\_data\_option
25252504
-------------------------
25262505

0 commit comments

Comments
 (0)