Skip to content

Commit 8b3ad9b

Browse files
committed
#3: The generator supports inheritance
1 parent e56fb85 commit 8b3ad9b

File tree

3 files changed

+286
-1
lines changed

3 files changed

+286
-1
lines changed

openapi-generator/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
</dependencies>
140140
<properties>
141141
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
142-
<openapi-generator-version>4.0.2</openapi-generator-version>
142+
<openapi-generator-version>3.3.4</openapi-generator-version>
143143
<maven-plugin-version>1.0.0</maven-plugin-version>
144144
<junit-version>4.8.1</junit-version>
145145
</properties>

openapi-generator/src/main/java/org/influxdata/codegen/InfluxPythonGenerator.java

+45
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
package org.influxdata.codegen;
22

3+
import java.util.ArrayList;
34
import java.util.Arrays;
5+
import java.util.HashMap;
46
import java.util.List;
7+
import java.util.Map;
58
import java.util.stream.Collectors;
69

10+
import javax.annotation.Nonnull;
11+
12+
import io.swagger.v3.oas.models.media.Schema;
13+
import org.openapitools.codegen.CodegenModel;
714
import org.openapitools.codegen.languages.PythonClientCodegen;
815

916
import static org.openapitools.codegen.utils.StringUtils.camelize;
@@ -53,6 +60,36 @@ public void processOpts() {
5360
.collect(Collectors.toList());
5461
}
5562

63+
@Override
64+
public CodegenModel fromModel(final String name, final Schema model, final Map<String, Schema> allDefinitions) {
65+
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
66+
67+
return codegenModel;
68+
}
69+
70+
@Override
71+
public Map<String, Object> postProcessAllModels(final Map<String, Object> models) {
72+
73+
Map<String, Object> allModels = super.postProcessAllModels(models);
74+
75+
for (Map.Entry<String, Object> entry : allModels.entrySet()) {
76+
77+
String modelName = entry.getKey();
78+
Object modelConfig = entry.getValue();
79+
80+
CodegenModel model = getModel((HashMap) modelConfig);
81+
82+
if (model.getParent() != null) {
83+
CodegenModel parentModel = getModel((HashMap) allModels.get(model.getParent()));
84+
model.vendorExtensions.put("x-parent-classFilename", parentModel.getClassFilename());
85+
model.vendorExtensions.put("x-has-parent-vars", Boolean.TRUE);
86+
model.vendorExtensions.put("x-parent-vars", parentModel.getVars());
87+
}
88+
}
89+
90+
return allModels;
91+
}
92+
5693
@Override
5794
public String toApiName(String name) {
5895
if (name.length() == 0) {
@@ -79,4 +116,12 @@ public String toApiFilename(String name) {
79116
// e.g. PhoneNumberService.py => phone_number_service.py
80117
return underscore(name) + "_service";
81118
}
119+
120+
@Nonnull
121+
private CodegenModel getModel(@Nonnull final HashMap modelConfig) {
122+
123+
HashMap models = (HashMap) ((ArrayList) modelConfig.get("models")).get(0);
124+
125+
return (CodegenModel) models.get("model");
126+
}
82127
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
# coding: utf-8
2+
3+
{{>partial_header}}
4+
5+
import pprint
6+
import re # noqa: F401
7+
8+
import six
9+
{{#models}}
10+
{{#model}}
11+
{{#parent}}
12+
from influxdb2.domain.{{{vendorExtensions.x-parent-classFilename}}} import {{{parent}}}
13+
{{/parent}}
14+
{{/model}}
15+
{{/models}}
16+
17+
18+
{{#models}}
19+
{{#model}}
20+
class {{classname}}({{#parent}}{{{parent}}}{{/parent}}{{^parent}}object{{/parent}}):
21+
"""NOTE: This class is auto generated by OpenAPI Generator.
22+
Ref: https://openapi-generator.tech
23+
24+
Do not edit the class manually.
25+
"""{{#allowableValues}}
26+
27+
"""
28+
allowed enum values
29+
"""
30+
{{#enumVars}}
31+
{{name}} = {{{value}}}{{^-last}}
32+
{{/-last}}
33+
{{/enumVars}}{{/allowableValues}}
34+
35+
"""
36+
Attributes:
37+
openapi_types (dict): The key is attribute name
38+
and the value is attribute type.
39+
attribute_map (dict): The key is attribute name
40+
and the value is json key in definition.
41+
"""
42+
openapi_types = {
43+
{{#vars}}
44+
'{{name}}': '{{{dataType}}}'{{#hasMore}},{{/hasMore}}{{^hasMore}}{{#model.vendorExtensions.x-has-parent-vars}},{{/model.vendorExtensions.x-has-parent-vars}}{{/hasMore}}
45+
{{/vars}}
46+
{{#vendorExtensions.x-parent-vars}}
47+
'{{name}}': '{{{dataType}}}'{{#hasMore}},{{/hasMore}}
48+
{{/vendorExtensions.x-parent-vars}}
49+
}
50+
51+
attribute_map = {
52+
{{#vars}}
53+
'{{name}}': '{{baseName}}'{{#hasMore}},{{/hasMore}}{{^hasMore}}{{#model.vendorExtensions.x-has-parent-vars}},{{/model.vendorExtensions.x-has-parent-vars}}{{/hasMore}}
54+
{{/vars}}
55+
{{#vendorExtensions.x-parent-vars}}
56+
'{{name}}': '{{baseName}}'{{#hasMore}},{{/hasMore}}
57+
{{/vendorExtensions.x-parent-vars}}
58+
}
59+
{{#discriminator}}
60+
61+
discriminator_value_class_map = {
62+
{{#children}}'{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}': '{{{classname}}}'{{^-last}},
63+
{{/-last}}{{/children}}
64+
}
65+
{{/discriminator}}
66+
67+
def __init__(self{{#vars}}, {{name}}={{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{/vars}}{{#vendorExtensions.x-parent-vars}}, {{name}}={{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{/vendorExtensions.x-parent-vars}}): # noqa: E501
68+
"""{{classname}} - a model defined in OpenAPI""" # noqa: E501
69+
{{#parent}}
70+
{{{parent}}}.__init__(self{{#vendorExtensions.x-parent-vars}}, {{name}}={{name}}{{/vendorExtensions.x-parent-vars}})
71+
{{/parent}}
72+
{{#vars}}{{#-first}}
73+
{{/-first}}
74+
self._{{name}} = None
75+
{{/vars}}
76+
self.discriminator = {{#discriminator}}'{{{discriminatorName}}}'{{/discriminator}}{{^discriminator}}None{{/discriminator}}
77+
{{#vars}}{{#-first}}
78+
{{/-first}}
79+
{{#required}}
80+
self.{{name}} = {{name}}
81+
{{/required}}
82+
{{^required}}
83+
{{#isNullable}}
84+
self.{{name}} = {{name}}
85+
{{/isNullable}}
86+
{{^isNullable}}
87+
if {{name}} is not None:
88+
self.{{name}} = {{name}}
89+
{{/isNullable}}
90+
{{/required}}
91+
{{/vars}}
92+
93+
{{#vars}}
94+
@property
95+
def {{name}}(self):
96+
"""Gets the {{name}} of this {{classname}}. # noqa: E501
97+
98+
{{#description}}
99+
{{{description}}} # noqa: E501
100+
{{/description}}
101+
102+
:return: The {{name}} of this {{classname}}. # noqa: E501
103+
:rtype: {{dataType}}
104+
"""
105+
return self._{{name}}
106+
107+
@{{name}}.setter
108+
def {{name}}(self, {{name}}):
109+
"""Sets the {{name}} of this {{classname}}.
110+
111+
{{#description}}
112+
{{{description}}} # noqa: E501
113+
{{/description}}
114+
115+
:param {{name}}: The {{name}} of this {{classname}}. # noqa: E501
116+
:type: {{dataType}}
117+
"""
118+
{{^isNullable}}
119+
{{#required}}
120+
if {{name}} is None:
121+
raise ValueError("Invalid value for `{{name}}`, must not be `None`") # noqa: E501
122+
{{/required}}
123+
{{/isNullable}}
124+
{{#isEnum}}
125+
{{#isContainer}}
126+
allowed_values = [{{#isNullable}}None,{{/isNullable}}{{#allowableValues}}{{#values}}{{#items.isString}}"{{/items.isString}}{{{this}}}{{#items.isString}}"{{/items.isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501
127+
{{#isListContainer}}
128+
if not set({{{name}}}).issubset(set(allowed_values)):
129+
raise ValueError(
130+
"Invalid values for `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501
131+
.format(", ".join(map(str, set({{{name}}}) - set(allowed_values))), # noqa: E501
132+
", ".join(map(str, allowed_values)))
133+
)
134+
{{/isListContainer}}
135+
{{#isMapContainer}}
136+
if not set({{{name}}}.keys()).issubset(set(allowed_values)):
137+
raise ValueError(
138+
"Invalid keys in `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501
139+
.format(", ".join(map(str, set({{{name}}}.keys()) - set(allowed_values))), # noqa: E501
140+
", ".join(map(str, allowed_values)))
141+
)
142+
{{/isMapContainer}}
143+
{{/isContainer}}
144+
{{^isContainer}}
145+
allowed_values = [{{#isNullable}}None,{{/isNullable}}{{#allowableValues}}{{#values}}{{#isString}}"{{/isString}}{{{this}}}{{#isString}}"{{/isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501
146+
if {{{name}}} not in allowed_values:
147+
raise ValueError(
148+
"Invalid value for `{{{name}}}` ({0}), must be one of {1}" # noqa: E501
149+
.format({{{name}}}, allowed_values)
150+
)
151+
{{/isContainer}}
152+
{{/isEnum}}
153+
{{^isEnum}}
154+
{{#hasValidation}}
155+
{{#maxLength}}
156+
if {{name}} is not None and len({{name}}) > {{maxLength}}:
157+
raise ValueError("Invalid value for `{{name}}`, length must be less than or equal to `{{maxLength}}`") # noqa: E501
158+
{{/maxLength}}
159+
{{#minLength}}
160+
if {{name}} is not None and len({{name}}) < {{minLength}}:
161+
raise ValueError("Invalid value for `{{name}}`, length must be greater than or equal to `{{minLength}}`") # noqa: E501
162+
{{/minLength}}
163+
{{#maximum}}
164+
if {{name}} is not None and {{name}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}: # noqa: E501
165+
raise ValueError("Invalid value for `{{name}}`, must be a value less than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}`{{maximum}}`") # noqa: E501
166+
{{/maximum}}
167+
{{#minimum}}
168+
if {{name}} is not None and {{name}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}: # noqa: E501
169+
raise ValueError("Invalid value for `{{name}}`, must be a value greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}`{{minimum}}`") # noqa: E501
170+
{{/minimum}}
171+
{{#pattern}}
172+
if {{name}} is not None and not re.search(r'{{{vendorExtensions.x-regex}}}', {{name}}{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501
173+
raise ValueError(r"Invalid value for `{{name}}`, must be a follow pattern or equal to `{{{pattern}}}`") # noqa: E501
174+
{{/pattern}}
175+
{{#maxItems}}
176+
if {{name}} is not None and len({{name}}) > {{maxItems}}:
177+
raise ValueError("Invalid value for `{{name}}`, number of items must be less than or equal to `{{maxItems}}`") # noqa: E501
178+
{{/maxItems}}
179+
{{#minItems}}
180+
if {{name}} is not None and len({{name}}) < {{minItems}}:
181+
raise ValueError("Invalid value for `{{name}}`, number of items must be greater than or equal to `{{minItems}}`") # noqa: E501
182+
{{/minItems}}
183+
{{/hasValidation}}
184+
{{/isEnum}}
185+
186+
self._{{name}} = {{name}}
187+
188+
{{/vars}}
189+
{{#discriminator}}
190+
def get_real_child_model(self, data):
191+
"""Returns the real base class specified by the discriminator"""
192+
discriminator_key = self.attribute_map[self.discriminator]
193+
discriminator_value = data[discriminator_key]
194+
return self.discriminator_value_class_map.get(discriminator_value)
195+
196+
{{/discriminator}}
197+
def to_dict(self):
198+
"""Returns the model properties as a dict"""
199+
result = {}
200+
201+
for attr, _ in six.iteritems(self.openapi_types):
202+
value = getattr(self, attr)
203+
if isinstance(value, list):
204+
result[attr] = list(map(
205+
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
206+
value
207+
))
208+
elif hasattr(value, "to_dict"):
209+
result[attr] = value.to_dict()
210+
elif isinstance(value, dict):
211+
result[attr] = dict(map(
212+
lambda item: (item[0], item[1].to_dict())
213+
if hasattr(item[1], "to_dict") else item,
214+
value.items()
215+
))
216+
else:
217+
result[attr] = value
218+
219+
return result
220+
221+
def to_str(self):
222+
"""Returns the string representation of the model"""
223+
return pprint.pformat(self.to_dict())
224+
225+
def __repr__(self):
226+
"""For `print` and `pprint`"""
227+
return self.to_str()
228+
229+
def __eq__(self, other):
230+
"""Returns true if both objects are equal"""
231+
if not isinstance(other, {{classname}}):
232+
return False
233+
234+
return self.__dict__ == other.__dict__
235+
236+
def __ne__(self, other):
237+
"""Returns true if both objects are not equal"""
238+
return not self == other
239+
{{/model}}
240+
{{/models}}

0 commit comments

Comments
 (0)