Skip to content

Commit

Permalink
Adding usePythonSrcRootInImports logic to AbstractPythonConnexionServ…
Browse files Browse the repository at this point in the history
…erCodegen. (OpenAPITools#9558)
  • Loading branch information
tray2100 committed May 23, 2021
1 parent 7c152da commit 97e0780
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 4 deletions.
1 change: 1 addition & 0 deletions docs/generators/python-aiohttp.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|supportPython2|support python2. This option has been deprecated and will be removed in the 5.x release.| |false|
|useNose|use the nose test framework| |false|
|usePythonSrcRootInImports|include pythonSrcRoot in import namespaces.| |false|

## IMPORT MAPPING

Expand Down
1 change: 1 addition & 0 deletions docs/generators/python-blueplanet.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|supportPython2|support python2. This option has been deprecated and will be removed in the 5.x release.| |false|
|useNose|use the nose test framework| |false|
|usePythonSrcRootInImports|include pythonSrcRoot in import namespaces.| |false|

## IMPORT MAPPING

Expand Down
1 change: 1 addition & 0 deletions docs/generators/python-flask.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|supportPython2|support python2. This option has been deprecated and will be removed in the 5.x release.| |false|
|useNose|use the nose test framework| |false|
|usePythonSrcRootInImports|include pythonSrcRoot in import namespaces.| |false|

## IMPORT MAPPING

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ public String patternCorrection(String pattern) {

public void setPackageName(String packageName) {
this.packageName = packageName;
additionalProperties.put(CodegenConstants.PACKAGE_NAME, this.packageName);
}

public void setProjectName(String projectName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public abstract class AbstractPythonConnexionServerCodegen extends AbstractPytho
// 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 PYTHON_SRC_ROOT = "pythonSrcRoot";
public static final String USE_PYTHON_SRC_ROOT_IN_IMPORTS = "usePythonSrcRootInImports";
static final String MEDIA_TYPE = "mediaType";

protected int serverPort = 8080;
Expand All @@ -62,6 +63,7 @@ public abstract class AbstractPythonConnexionServerCodegen extends AbstractPytho
protected boolean featureCORS = Boolean.FALSE;
protected boolean useNose = Boolean.FALSE;
protected String pythonSrcRoot;
protected boolean usePythonSrcRootInImports = Boolean.FALSE;

public AbstractPythonConnexionServerCodegen(String templateDirectory, boolean fixBodyNameValue) {
super();
Expand All @@ -79,7 +81,7 @@ public AbstractPythonConnexionServerCodegen(String templateDirectory, boolean fi
typeMapping.put("map", "Dict");

// set the output folder here
outputFolder = "generated-code/connexion";
outputFolder = "generated-code" + File.separatorChar + "connexion";

apiTemplateFiles.put("controller.mustache", ".py");
modelTemplateFiles.put("model.mustache", ".py");
Expand Down Expand Up @@ -132,6 +134,8 @@ public AbstractPythonConnexionServerCodegen(String templateDirectory, boolean fi
defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(PYTHON_SRC_ROOT, "put python sources in this subdirectory of output folder (defaults to \"\" for). Use this for src/ layout.").
defaultValue(""));
cliOptions.add(new CliOption(USE_PYTHON_SRC_ROOT_IN_IMPORTS, "include pythonSrcRoot in import namespaces.").
defaultValue("false"));
}

protected void addSupportingFiles() {
Expand All @@ -147,7 +151,6 @@ public void processOpts() {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
} else {
setPackageName("openapi_server");
additionalProperties.put(CodegenConstants.PACKAGE_NAME, this.packageName);
}
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
Expand Down Expand Up @@ -177,9 +180,19 @@ public void processOpts() {
if (additionalProperties.containsKey(USE_NOSE)) {
setUseNose((String) additionalProperties.get(USE_NOSE));
}
if (additionalProperties.containsKey(USE_PYTHON_SRC_ROOT_IN_IMPORTS)) {
setUsePythonSrcRootInImports((String) additionalProperties.get(USE_PYTHON_SRC_ROOT_IN_IMPORTS));
}
if (additionalProperties.containsKey(PYTHON_SRC_ROOT)) {
setPythonSrcRoot((String) additionalProperties.get(PYTHON_SRC_ROOT));
additionalProperties.put(PYTHON_SRC_ROOT, pythonSrcRoot);
String pythonSrcRoot = (String) additionalProperties.get(PYTHON_SRC_ROOT);
if (usePythonSrcRootInImports) {
// if we prepend the package name if the pythonSrcRoot we get the desired effect.
// but we also need to set pythonSrcRoot itself to "" to ensure all the paths are
// what we expect.
setPackageName(pythonSrcRoot + "." + packageName);
pythonSrcRoot = "";
}
setPythonSrcRoot(pythonSrcRoot);
} else {
setPythonSrcRoot("");
}
Expand Down Expand Up @@ -218,6 +231,11 @@ public void setPythonSrcRoot(String val) {
} else {
this.pythonSrcRoot = pySrcRoot + File.separator;
}
additionalProperties.put(PYTHON_SRC_ROOT, StringUtils.defaultIfBlank(this.pythonSrcRoot, null));
}

public void setUsePythonSrcRootInImports(String val) {
this.usePythonSrcRootInImports = Boolean.parseBoolean(val);
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package org.openapitools.codegen.python;

import static org.openapitools.codegen.languages.AbstractPythonConnexionServerCodegen.PYTHON_SRC_ROOT;
import static org.openapitools.codegen.languages.AbstractPythonConnexionServerCodegen.USE_PYTHON_SRC_ROOT_IN_IMPORTS;

import java.io.File;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;

import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.languages.AbstractPythonConnexionServerCodegen;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class AbstractPythonConnexionServerCodegenTest {

/**
* Passing "description" as first param to succinctly identify the significance of test parameters.
*/
@Test(dataProvider = "data")
public void test(String description, Map<String, Object> additionalProperties, String modelName,
ExpectedValues expectedValues) {
AbstractPythonConnexionServerCodegen codegen = new MockAbstractPythonConnexionServerCodegen("", false);
codegen.additionalProperties().putAll(additionalProperties);
codegen.processOpts();
String pythonSrcRoot = Objects.toString(codegen.additionalProperties().get(PYTHON_SRC_ROOT), null);
Assert.assertEquals(pythonSrcRoot, expectedValues.pythonSrcRoot);
Assert.assertEquals(codegen.apiPackage(), expectedValues.expectedApiPackage);
Assert.assertEquals(codegen.modelFileFolder(), expectedValues.expectedModelFileFolder);
Assert.assertEquals(codegen.apiFileFolder(), expectedValues.expectedApiFileFolder);
Assert.assertEquals(codegen.toModelImport(modelName), expectedValues.expectedImport);
}

@DataProvider
public Object[][] data() {
return new Object[][]{
new Object[]{
"Default setup",
Collections.emptyMap(),
"TestModel",
new ExpectedValues("from openapi_server.models.test_model import TestModel",
"openapi_server.controllers",
platformAgnosticPath("generated-code", "connexion", "openapi_server", "models"),
platformAgnosticPath("generated-code", "connexion", "openapi_server", "controllers"),
null)
},
new Object[]{
"Default setup with Python src root",
ImmutableMap.of(PYTHON_SRC_ROOT, "test_root"),
"TestModel",
new ExpectedValues("from openapi_server.models.test_model import TestModel",
"openapi_server.controllers",
platformAgnosticPath("generated-code", "connexion", "test_root", "openapi_server", "models"),
platformAgnosticPath("generated-code", "connexion", "test_root", "openapi_server", "controllers"),
"test_root")
},
new Object[]{
"Python src in import",
ImmutableMap.of(PYTHON_SRC_ROOT, "test_root", USE_PYTHON_SRC_ROOT_IN_IMPORTS, "true"),
"TestModel",
new ExpectedValues("from test_root.openapi_server.models.test_model import TestModel",
"test_root.openapi_server.controllers",
platformAgnosticPath("generated-code", "connexion", "test_root", "openapi_server", "models"),
platformAgnosticPath("generated-code", "connexion", "test_root", "openapi_server", "controllers"),
null)
},
new Object[]{
"Python src in import with specified package",
ImmutableMap.of(PYTHON_SRC_ROOT, "test_root",
USE_PYTHON_SRC_ROOT_IN_IMPORTS, "true",
CodegenConstants.PACKAGE_NAME, "test_package"),
"TestModel",
new ExpectedValues("from test_root.test_package.models.test_model import TestModel",
"test_root.test_package.controllers",
platformAgnosticPath("generated-code", "connexion", "test_root", "test_package", "models"),
platformAgnosticPath("generated-code", "connexion", "test_root", "test_package", "controllers"),
null)
}
};
}

private static String platformAgnosticPath(String... nodes) {
return StringUtils.join(nodes, File.separatorChar);
}

private static class MockAbstractPythonConnexionServerCodegen extends AbstractPythonConnexionServerCodegen {
public MockAbstractPythonConnexionServerCodegen(String templateDirectory, boolean fixBodyNameValue) {
super(templateDirectory, fixBodyNameValue);
}
}

private static class ExpectedValues {
public final String expectedImport;
public final String expectedApiPackage;
public final String expectedModelFileFolder;
public final String expectedApiFileFolder;
public final String pythonSrcRoot;

public ExpectedValues(String expectedImport, String expectedApiPackage, String expectedModelFileFolder,
String expectedApiFileFolder, String pythonSrcRoot) {
this.expectedImport = expectedImport;
this.expectedApiPackage = expectedApiPackage;
this.expectedModelFileFolder = expectedModelFileFolder;
this.expectedApiFileFolder = expectedApiFileFolder;
this.pythonSrcRoot = pythonSrcRoot != null ? pythonSrcRoot + File.separatorChar : null;
}
}

}

0 comments on commit 97e0780

Please sign in to comment.