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

Feature/wo read only init #9395

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from 21 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ When code is generated from this project, it shall be considered **AS IS** and o

### [3.5 - IDE Integration](#table-of-contents)

Here is a list of community-conitributed IDE plug-ins that integrate with OpenAPI Generator:
Here is a list of community-contributed IDE plug-ins that integrate with OpenAPI Generator:

- Eclipse: [Codewind OpenAPI Tools for Eclipse](https://www.eclipse.org/codewind/open-api-tools-for-eclipse.html) by [IBM](https://www.ibm.com)
- IntelliJ IDEA: [OpenAPI Generator](https://plugins.jetbrains.com/plugin/8433-openapi-generator) by [Jim Schubert](https://jimschubert.us/#/)
Expand Down
4 changes: 2 additions & 2 deletions bin/configs/ktorm-schema.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
generatorName: ktorm-schema
outputDir: samples/schema/petstore/ktorm
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated, why is it being changed?

templateDir: modules/openapi-generator/src/main/resources/ktorm-schema
additionalProperties:
hideGenerationTimestamp: true
importModelPackageName: org.openapitools.client.models
importModelPackageName: org.openapitools.client.models
2 changes: 1 addition & 1 deletion bin/configs/nim.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
generatorName: nim
outputDir: samples/client/petstore/nim
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/nim-client
additionalProperties:
packageName: petstore
5 changes: 4 additions & 1 deletion bin/configs/python-oas2.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# this file exists because in this file we omit setting disallowAdditionalPropertiesIfNotPresent
# which makes it default to false
# that false setting is needed for composed schemas to work
# Composed schemas are schemas that contain the allOf/oneOf/anyOf keywords. v2 specs only support the allOf keyword.
generatorName: python
outputDir: samples/client/petstore/python
inputSpec: modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/python
additionalProperties:
disallowAdditionalPropertiesIfNotPresent: "true"
packageName: petstore_api
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
generatorName: python
outputDir: samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent
inputSpec: modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/python
additionalProperties:
disallowAdditionalPropertiesIfNotPresent: "true"
packageName: petstore_api
2 changes: 1 addition & 1 deletion modules/openapi-generator-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>
Expand Down
2 changes: 1 addition & 1 deletion modules/openapi-generator-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<artifactId>openapi-generator-project</artifactId>
<groupId>org.openapitools</groupId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>
Expand Down
2 changes: 1 addition & 1 deletion modules/openapi-generator-gradle-plugin/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RELEASE_VERSION
openApiGeneratorVersion=5.1.1-SNAPSHOT
openApiGeneratorVersion=5.2.0-SNAPSHOT
# /RELEASE_VERSION

# BEGIN placeholders
Expand Down
2 changes: 1 addition & 1 deletion modules/openapi-generator-gradle-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# RELEASE_VERSION
openApiGeneratorVersion=5.1.1-SNAPSHOT
openApiGeneratorVersion=5.2.0-SNAPSHOT
# /RELEASE_VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
Expand Down
2 changes: 1 addition & 1 deletion modules/openapi-generator-maven-plugin/examples/kotlin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<dependencies>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
Expand Down
2 changes: 1 addition & 1 deletion modules/openapi-generator-maven-plugin/examples/spring.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
Expand Down
2 changes: 1 addition & 1 deletion modules/openapi-generator-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>
Expand Down
2 changes: 1 addition & 1 deletion modules/openapi-generator-online/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>
Expand Down
2 changes: 1 addition & 1 deletion modules/openapi-generator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.1-SNAPSHOT</version>
<version>5.2.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@ public PythonClientCodegen() {
// in other code generators, support needs to be enabled on a case-by-case basis.
supportsAdditionalPropertiesWithComposedSchema = true;

// When the 'additionalProperties' keyword is not present in a OAS schema, allow
// undeclared properties. This is compliant with the JSON schema specification.
this.setDisallowAdditionalPropertiesIfNotPresent(false);

modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML, WireFormatFeature.Custom))
Expand All @@ -96,9 +92,8 @@ public PythonClientCodegen() {
ParameterFeature.Cookie
)
);

// this may set datatype right for additional properties
instantiationTypes.put("map", "dict");
// needed for type object with additionalProperties: false
typeMapping.put("object", "dict");

languageSpecificPrimitives.add("file_type");
languageSpecificPrimitives.add("none_type");
Expand All @@ -113,6 +108,20 @@ public PythonClientCodegen() {
cliOptions.add(new CliOption(CodegenConstants.PYTHON_ATTR_NONE_IF_UNSET, CodegenConstants.PYTHON_ATTR_NONE_IF_UNSET_DESC)
.defaultValue(Boolean.FALSE.toString()));

// option to change how we process + set the data in the 'additionalProperties' keyword.
CliOption disallowAdditionalPropertiesIfNotPresentOpt = CliOption.newBoolean(
CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT,
CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT_DESC).defaultValue(Boolean.FALSE.toString());
Map<String, String> disallowAdditionalPropertiesIfNotPresentOpts = new HashMap<>();
disallowAdditionalPropertiesIfNotPresentOpts.put("false",
"The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.");
disallowAdditionalPropertiesIfNotPresentOpts.put("true",
"Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default. NOTE: "+
"this option breaks composition and will be removed in 6.0.0"
);
disallowAdditionalPropertiesIfNotPresentOpt.setEnum(disallowAdditionalPropertiesIfNotPresentOpts);
cliOptions.add(disallowAdditionalPropertiesIfNotPresentOpt);

generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
.stability(Stability.EXPERIMENTAL)
.build();
Expand Down Expand Up @@ -162,6 +171,18 @@ public void processOpts() {
}
additionalProperties.put("attrNoneIfUnset", attrNoneIfUnset);

// When the 'additionalProperties' keyword is not present in a OAS schema, allow
// undeclared properties. This is compliant with the JSON schema specification.
// setting this to false is required to have composed schemas work because:
// anyOf SchemaA + SchemaB, requires that props present only in A are accepted in B because in B
// they are additional properties
Boolean disallowAddProps = false;
if (additionalProperties.containsKey(CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT)) {
disallowAddProps = Boolean.valueOf(additionalProperties.get(CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT).toString());
}
this.setDisallowAdditionalPropertiesIfNotPresent(disallowAddProps);


// check library option to ensure only urllib3 is supported
if (!DEFAULT_LIBRARY.equals(getLibrary())) {
throw new RuntimeException("Only the `urllib3` library is supported in the refactored `python` client generator at the moment. Please fall back to `python-legacy` client generator for the time being. We welcome contributions to add back `asyncio`, `tornado` support to the `python` client generator.");
Expand Down Expand Up @@ -730,6 +751,62 @@ public String getModelName(Schema sc) {
return null;
}

@Override
protected Schema getAdditionalProperties(Schema schema) {
/*
Use cases:
1. addProps set to schema in spec: return that schema
2. addProps unset w/ getDisallowAdditionalPropertiesIfNotPresent -> null
3. addProps unset w/ getDisallowAdditionalPropertiesIfNotPresent=False -> new Schema()
4. addProps true -> new Schema() NOTE: v3 only
5. addprops false -> null NOTE: v3 only
*/
Object addProps = schema.getAdditionalProperties();
if (addProps instanceof Schema) {
return (Schema) addProps;
}
if (addProps == null) {
// When reaching this code path, this should indicate the 'additionalProperties' keyword is
// not present in the OAS schema. This is true for OAS 3.0 documents.
// However, the parsing logic is broken for OAS 2.0 documents because of the
// https://github.com/swagger-api/swagger-parser/issues/1369 issue.
// When OAS 2.0 documents are parsed, the swagger-v2-converter ignores the 'additionalProperties'
// keyword if the value is boolean. That means codegen is unable to determine whether
// additional properties are allowed or not.
//
// The original behavior was to assume additionalProperties had been set to false.
if (getDisallowAdditionalPropertiesIfNotPresent()) {
// If the 'additionalProperties' keyword is not present in a OAS schema,
// interpret as if the 'additionalProperties' keyword had been set to false.
// This is NOT compliant with the JSON schema specification. It is the original
// 'openapi-generator' behavior.
return null;
}
/*
// The disallowAdditionalPropertiesIfNotPresent CLI option has been set to true,
// but for now that only works with OAS 3.0 documents.
// The new behavior does not work with OAS 2.0 documents.
if (extensions == null || !extensions.containsKey(EXTENSION_OPENAPI_DOC_VERSION)) {
// Fallback to the legacy behavior.
return null;
}
// Get original swagger version from OAS extension.
// Note openAPI.getOpenapi() is always set to 3.x even when the document
// is converted from a OAS/Swagger 2.0 document.
// https://github.com/swagger-api/swagger-parser/pull/1374
SemVer version = new SemVer((String)extensions.get(EXTENSION_OPENAPI_DOC_VERSION));
if (version.major != 3) {
return null;
}
*/
}
if (addProps == null || (addProps instanceof Boolean && (Boolean) addProps)) {
// Return empty schema to allow any type
return new Schema();
}
return null;
}

/**
* Return a string representation of the Python types for the specified OAS schema.
* Primitive types in the OAS specification are implemented in Python using the corresponding
Expand Down Expand Up @@ -769,16 +846,39 @@ private String getTypeString(Schema p, String prefix, String suffix, List<String
}
}
if (isAnyTypeSchema(p)) {
// for v2 specs only, swagger-parser never generates an AnyType schemas even though it should generate them
// https://github.com/swagger-api/swagger-parser/issues/1378
// switch to v3 if you need AnyType to work
return prefix + "bool, date, datetime, dict, float, int, list, str, none_type" + suffix;
}
String originalSpecVersion = "X";
if (this.openAPI.getExtensions() != null && this.openAPI.getExtensions().containsKey("x-original-swagger-version")) {
originalSpecVersion = (String) this.openAPI.getExtensions().get("x-original-swagger-version");
originalSpecVersion = originalSpecVersion.substring(0, 1);

}
Boolean v2DisallowAdditionalPropertiesIfNotPresentAddPropsNullCase = (getAdditionalProperties(p) == null && this.getDisallowAdditionalPropertiesIfNotPresent() && originalSpecVersion.equals("2"));
Schema emptySchema = new Schema();
Boolean v2WithCompositionAddPropsAnyTypeSchemaCase = (getAdditionalProperties(p) != null && emptySchema.equals(getAdditionalProperties(p)) && originalSpecVersion.equals("2"));
if (isFreeFormObject(p) && (v2DisallowAdditionalPropertiesIfNotPresentAddPropsNullCase || v2WithCompositionAddPropsAnyTypeSchemaCase)) {
// for v2 specs only, input AnyType schemas (type unset) or schema {} results in FreeFromObject schemas
// per https://github.com/swagger-api/swagger-parser/issues/1378
// v2 spec uses cases
// 1. AnyType schemas
// 2. type object schema with no other info
// use case 1 + 2 -> both become use case 1
// switch to v3 if you need use cases 1 + 2 to work correctly
return prefix + "bool, date, datetime, dict, float, int, list, str, none_type" + fullSuffix;
}
// Resolve $ref because ModelUtils.isXYZ methods do not automatically resolve references.
if (ModelUtils.isNullable(ModelUtils.getReferencedSchema(this.openAPI, p))) {
fullSuffix = ", none_type" + suffix;
}
if (isFreeFormObject(p) && getAdditionalProperties(p) == null) {
return prefix + "bool, date, datetime, dict, float, int, list, str" + fullSuffix;
}
if ((ModelUtils.isMapSchema(p) || "object".equals(p.getType())) && getAdditionalProperties(p) != null) {
Boolean v3WithCompositionAddPropsAnyTypeSchemaCase = (getAdditionalProperties(p) != null && emptySchema.equals(getAdditionalProperties(p)) && originalSpecVersion.equals("3"));
if (isFreeFormObject(p) && v3WithCompositionAddPropsAnyTypeSchemaCase) {
// v3 code path, use case: type object schema with no other schema info
return prefix + "{str: (bool, date, datetime, dict, float, int, list, str, none_type)}" + fullSuffix;
} else if ((ModelUtils.isMapSchema(p) || "object".equals(p.getType())) && getAdditionalProperties(p) != null) {
Schema inner = getAdditionalProperties(p);
return prefix + "{str: " + getTypeString(inner, "(", ")", referencedModelNames) + "}" + fullSuffix;
} else if (ModelUtils.isArraySchema(p)) {
Expand Down Expand Up @@ -837,7 +937,7 @@ protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Sc
// The 'addProps' may be a reference, getTypeDeclaration will resolve
// the reference.
List<String> referencedModelNames = new ArrayList<String>();
codegenModel.additionalPropertiesType = getTypeString(addProps, "", "", referencedModelNames);
getTypeString(addProps, "", "", referencedModelNames);
if (referencedModelNames.size() != 0) {
// Models that are referenced in the 'additionalPropertiesType' keyword
// must be added to the imports.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class PythonLegacyClientCodegen extends AbstractPythonCodegen implements
// nose is a python testing framework, we use pytest if USE_NOSE is unset
public static final String USE_NOSE = "useNose";
public static final String RECURSION_LIMIT = "recursionLimit";
public static final String PYTHON_ATTR_NONE_IF_UNSET = "pythonAttrNoneIfUnset";

protected String packageUrl;
protected String apiDocPath = "docs/";
Expand Down
Loading