diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java index 080112520cae4acf1c9109f1bfeb437708dad323..fa38462af854f1820eace915887529f34317a8d9 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java @@ -637,6 +637,8 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co String sanitizedName = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. // remove dollar sign sanitizedName = sanitizedName.replaceAll("$", ""); + // remove whitespace + sanitizedName = sanitizedName.replaceAll("\\s+", ""); String nameWithPrefixSuffix = sanitizedName; if (!StringUtils.isEmpty(modelNamePrefix)) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonExperimentalClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonExperimentalClientCodegen.java index 09708dd1daf9d2d13ad2dc559e9f6b83249acc28..dac8c99bc5680d720d6f6db2ac2e95ecca5bd366 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonExperimentalClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonExperimentalClientCodegen.java @@ -98,6 +98,14 @@ public class PythonExperimentalClientCodegen extends AbstractPythonCodegen { protected CodegenIgnoreProcessor ignoreProcessor; protected TemplateProcessor templateProcessor = null; + // for apis.tags imports + private Map<String, String> tagModuleNameToApiClassname = new LinkedHashMap<>(); + // for apis.tags enum tag definition + private Map<String, String> enumToTag = new LinkedHashMap<>(); + // for apis.tags tag api definition + private Map<String, String> tagEnumToApiClassname = new LinkedHashMap<>(); + + public PythonExperimentalClientCodegen() { super(); loadDeepObjectIntoItems = false; @@ -473,6 +481,14 @@ public class PythonExperimentalClientCodegen extends AbstractPythonCodegen { } } + @Override + public String toApiName(String name) { + if (name.length() == 0) { + return "DefaultApi"; + } + return toModelName(name) + apiNameSuffix; + } + /* I made this method because endpoint parameters not contain a lot of needed metadata It is very verbose to write all of this info into the api template @@ -491,11 +507,38 @@ public class PythonExperimentalClientCodegen extends AbstractPythonCodegen { List<List<Object>> testFiles = new ArrayList<>(); String outputFilename; + // endpoint tags may not exist in the root of the spec file + // this is allowed per openapi + // because spec tags may be empty ro incomplete, tags are also accumulated from endpoints + List<Tag> tags = openAPI.getTags(); + if (tags != null) { + for (Tag tag: tags) { + String tagName = tag.getName(); + String tagModuleName = toApiFilename(tagName); + String apiClassname = toApiName(tagName); + tagModuleNameToApiClassname.put(tagModuleName, apiClassname); + String tagEnum = toEnumVarName(tagName, "str"); + enumToTag.put(tagEnum, tagName); + tagEnumToApiClassname.put(tagEnum, apiClassname); + } + } + OperationMap operations = objs.getOperations(); List<CodegenOperation> codegenOperations = operations.getOperation(); HashMap<String, String> pathModuleToPath = new HashMap<>(); // paths.some_path.post.py (single endpoint definition) for (CodegenOperation co: codegenOperations) { + if (co.tags != null) { + for (Tag tag: co.tags) { + String tagName = tag.getName(); + String tagModuleName = toApiFilename(tagName); + String apiClassname = toApiName(tagName); + tagModuleNameToApiClassname.put(tagModuleName, apiClassname); + String tagEnum = toEnumVarName(tagName, "str"); + enumToTag.put(tagEnum, tagName); + tagEnumToApiClassname.put(tagEnum, apiClassname); + } + } String path = co.path; String pathModuleName = co.nickname; if (!pathModuleToPath.containsKey(pathModuleName)) { @@ -530,22 +573,6 @@ public class PythonExperimentalClientCodegen extends AbstractPythonCodegen { pathEnumToApiClassname.put(pathEnumVar, apiClassName); pathModuleToApiClassname.put(toVarName(path), apiClassName); } - List<Tag> tags = openAPI.getTags(); - // for imports - Map<String, String> tagModuleNameToApiClassname = new LinkedHashMap<>(); - // for enum tag definition - Map<String, String> enumToTag = new LinkedHashMap<>(); - // for tag api definition - Map<String, String> tagEnumToApiClassname = new LinkedHashMap<>(); - for (Tag tag: tags) { - String tagName = tag.getName(); - String tagModuleName = toApiFilename(tagName); - String apiClassname = toApiName(tagName); - tagModuleNameToApiClassname.put(tagModuleName, apiClassname); - String tagEnum = toEnumVarName(tagName, "str"); - enumToTag.put(tagEnum, tagName); - tagEnumToApiClassname.put(tagEnum, apiClassname); - } // Note: __init__apis.handlebars is generated as a supporting file // apis.tag_to_api.py Map<String, Object> tagToApiMap = new HashMap<>(); @@ -2617,6 +2644,17 @@ public class PythonExperimentalClientCodegen extends AbstractPythonCodegen { } } + /** + * Note: a custom version of this function is used so the original tag value can be used + * + * @param tag Tag + * @return the tag to use + */ + @Override + public String sanitizeTag(String tag) { + return tag; + } + @Override public void postProcess() { System.out.println("################################################################################"); diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/apis/tag_to_api.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/apis/tag_to_api.py index 553855d9707d194ee5686cd687ad88969ddbcc98..c94ea467e25a7e37a1f84374849f9c7a650a5f4f 100644 --- a/samples/openapi3/client/petstore/python-experimental/petstore_api/apis/tag_to_api.py +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/apis/tag_to_api.py @@ -4,6 +4,10 @@ from petstore_api.apis.tags import TagValues from petstore_api.apis.tags.pet_api import PetApi from petstore_api.apis.tags.store_api import StoreApi from petstore_api.apis.tags.user_api import UserApi +from petstore_api.apis.tags.another_fake_api import AnotherFakeApi +from petstore_api.apis.tags.default_api import DefaultApi +from petstore_api.apis.tags.fake_api import FakeApi +from petstore_api.apis.tags.fake_classname_tags123_api import FakeClassnameTags123Api TagToApi = typing.TypedDict( 'TagToApi', @@ -11,6 +15,10 @@ TagToApi = typing.TypedDict( TagValues.PET: PetApi, TagValues.STORE: StoreApi, TagValues.USER: UserApi, + TagValues.ANOTHERFAKE: AnotherFakeApi, + TagValues.DEFAULT: DefaultApi, + TagValues.FAKE: FakeApi, + TagValues.FAKE_CLASSNAME_TAGS_123: FakeClassnameTags123Api, } ) @@ -19,5 +27,9 @@ tag_to_api = TagToApi( TagValues.PET: PetApi, TagValues.STORE: StoreApi, TagValues.USER: UserApi, + TagValues.ANOTHERFAKE: AnotherFakeApi, + TagValues.DEFAULT: DefaultApi, + TagValues.FAKE: FakeApi, + TagValues.FAKE_CLASSNAME_TAGS_123: FakeClassnameTags123Api, } ) diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/apis/tags/__init__.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/apis/tags/__init__.py index d24757e1cbbb5ec1956f9660e7982abf9d9621a7..a8ec6fddd9a1bec65fb46c9e67399bc9c0e92205 100644 --- a/samples/openapi3/client/petstore/python-experimental/petstore_api/apis/tags/__init__.py +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/apis/tags/__init__.py @@ -9,3 +9,7 @@ class TagValues(str, enum.Enum): PET = "pet" STORE = "store" USER = "user" + ANOTHERFAKE = "$another-fake?" + DEFAULT = "default" + FAKE = "fake" + FAKE_CLASSNAME_TAGS_123 = "fake_classname_tags 123#$%^"