diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonConnexionServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonConnexionServerCodegen.java index f7b7202d543a..a286e60e01a0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonConnexionServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonConnexionServerCodegen.java @@ -724,6 +724,11 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List testParameters = openAPI.getPaths().get("/test").getGet().getParameters(); + CodegenParameter freeFormParam = codegen.fromParameter(testParameters.get(3), new HashSet<>()); + CodegenParameter anyValParam = codegen.fromParameter(testParameters.get(4), new HashSet<>()); + + assertThat(freeFormParam.paramName).isEqualTo("free_form"); + assertThat(freeFormParam.isFreeFormObject).isTrue(); + assertThat(freeFormParam.isAnyType).isFalse(); + assertThat(freeFormParam.isContainer).isFalse(); + assertThat(freeFormParam.isPrimitiveType).isFalse(); + assertThat(freeFormParam.dataType).isEqualTo("object"); + + assertThat(anyValParam.paramName).isEqualTo("any_val"); + assertThat(anyValParam.isFreeFormObject).isFalse(); + assertThat(anyValParam.isAnyType).isTrue(); + assertThat(anyValParam.isContainer).isFalse(); + assertThat(anyValParam.isPrimitiveType).isFalse(); + assertThat(anyValParam.dataType).isEqualTo("object"); + + OpenAPI composedOpenAPI = new OpenAPIParser().readLocation(composedSpecPath, null, new ParseOptions()).getOpenAPI(); + PythonAiohttpConnexionServerCodegen composedCodegen = new PythonAiohttpConnexionServerCodegen(); + composedCodegen.setOpenAPI(composedOpenAPI); + List probeParameters = composedOpenAPI.getPaths().get("/t").getGet().getParameters(); + CodegenParameter composedParam = composedCodegen.fromParameter(probeParameters.get(0), new HashSet<>()); + CodegenParameter oneOfParam = composedCodegen.fromParameter(probeParameters.get(1), new HashSet<>()); + CodegenParameter addlParam = composedCodegen.fromParameter(probeParameters.get(2), new HashSet<>()); + assertThat(composedParam.isAnyType).isTrue(); + assertThat(composedParam.dataType).isEqualTo("Composed"); + assertThat(oneOfParam.isAnyType).isTrue(); + assertThat(oneOfParam.dataType).isEqualTo("OneOfM"); + assertThat(addlParam.paramName).isEqualTo("addl"); + assertThat(addlParam.isMap).isTrue(); + assertThat(addlParam.isContainer).isTrue(); + assertThat(addlParam.isFreeFormObject).isFalse(); + assertThat(addlParam.isAnyType).isFalse(); + assertThat(addlParam.dataType).isEqualTo("WithAddl"); + + File aiohttpOutput = Files.createTempDirectory("test-aiohttp-freeform-params").toFile().getCanonicalFile(); + try { + CodegenConfigurator aiohttpConfig = new CodegenConfigurator() + .setGeneratorName("python-aiohttp") + .setInputSpec(specPath) + .setOutputDir(aiohttpOutput.getAbsolutePath()); + new DefaultGenerator().opts(aiohttpConfig.toClientOptInput()).generate(); + + Path aiohttpController = Paths.get( + aiohttpOutput.getAbsolutePath(), + "openapi_server", + "controllers", + "default_controller.py"); + assertFileExists(aiohttpController); + assertFileNotContains( + aiohttpController, + "free_form = ", + "any_val = "); + } finally { + FileUtils.deleteDirectory(aiohttpOutput); + } + + File blueplanetOutput = Files.createTempDirectory("test-blueplanet-freeform-params").toFile().getCanonicalFile(); + try { + CodegenConfigurator blueplanetConfig = new CodegenConfigurator() + .setGeneratorName("python-blueplanet") + .setInputSpec(specPath) + .setOutputDir(blueplanetOutput.getAbsolutePath()); + new DefaultGenerator().opts(blueplanetConfig.toClientOptInput()).generate(); + + Path blueplanetController = Paths.get( + blueplanetOutput.getAbsolutePath(), + "app", + "openapi_server", + "controllers", + "default_controller.py"); + assertFileExists(blueplanetController); + assertFileNotContains( + blueplanetController, + "free_form = ", + "any_val = "); + } finally { + FileUtils.deleteDirectory(blueplanetOutput); + } + + File flaskOutput = Files.createTempDirectory("test-flask-freeform-params").toFile().getCanonicalFile(); + try { + CodegenConfigurator flaskConfig = new CodegenConfigurator() + .setGeneratorName("python-flask") + .setInputSpec(specPath) + .setOutputDir(flaskOutput.getAbsolutePath()); + new DefaultGenerator().opts(flaskConfig.toClientOptInput()).generate(); + + Path flaskController = Paths.get( + flaskOutput.getAbsolutePath(), + "openapi_server", + "controllers", + "default_controller.py"); + assertFileExists(flaskController); + assertFileNotContains( + flaskController, + "free_form =", + "any_val ="); + } finally { + FileUtils.deleteDirectory(flaskOutput); + } + + File flaskComposedOutput = Files.createTempDirectory("test-flask-composed-params").toFile().getCanonicalFile(); + try { + CodegenConfigurator flaskComposedConfig = new CodegenConfigurator() + .setGeneratorName("python-flask") + .setInputSpec(composedSpecPath) + .setOutputDir(flaskComposedOutput.getAbsolutePath()); + new DefaultGenerator().opts(flaskComposedConfig.toClientOptInput()).generate(); + + Path flaskComposedController = Paths.get( + flaskComposedOutput.getAbsolutePath(), + "openapi_server", + "controllers", + "default_controller.py"); + assertFileExists(flaskComposedController); + assertFileContains( + flaskComposedController, + ":type addl: Dict[str, str]", + "composed = Composed.from_dict(flask.request.get_json()) # noqa: E501", + "oneof = OneOfM.from_dict(flask.request.get_json()) # noqa: E501", + "plain = Pet.from_dict(flask.request.get_json()) # noqa: E501"); + assertFileNotContains( + flaskComposedController, + "addl ="); + } finally { + FileUtils.deleteDirectory(flaskComposedOutput); + } + } + } diff --git a/modules/openapi-generator/src/test/resources/3_1/python/composed-query-params.yaml b/modules/openapi-generator/src/test/resources/3_1/python/composed-query-params.yaml new file mode 100644 index 000000000000..568115a63362 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_1/python/composed-query-params.yaml @@ -0,0 +1,70 @@ +openapi: 3.1.0 + +info: + title: Composed and model query parameter test + version: 1.0.0 + +paths: + /t: + get: + operationId: probe + parameters: + - name: composed + in: query + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Composed' + - name: oneof + in: query + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/OneOfM' + - name: addl + in: query + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/WithAddl' + - name: plain + in: query + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + responses: + '200': + description: OK + +components: + schemas: + Pet: + type: object + properties: + name: + type: string + Tag: + type: object + properties: + label: + type: string + Composed: + allOf: + - $ref: '#/components/schemas/Pet' + - $ref: '#/components/schemas/Tag' + OneOfM: + oneOf: + - $ref: '#/components/schemas/Pet' + - $ref: '#/components/schemas/Tag' + WithAddl: + type: object + properties: + a: + type: string + additionalProperties: + type: string diff --git a/modules/openapi-generator/src/test/resources/3_1/python/map-and-freeform-params.yaml b/modules/openapi-generator/src/test/resources/3_1/python/map-and-freeform-params.yaml new file mode 100644 index 000000000000..248151bf6638 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_1/python/map-and-freeform-params.yaml @@ -0,0 +1,51 @@ +openapi: 3.1.0 + +info: + title: Map and free-form parameter test + version: 1.0.0 + +paths: + /test: + get: + operationId: testParams + parameters: + - name: date_map + in: query + schema: + type: object + additionalProperties: + type: string + format: date + - name: datetime_map + in: query + schema: + type: object + additionalProperties: + type: string + format: date-time + - name: model_map + in: query + schema: + type: object + additionalProperties: + $ref: '#/components/schemas/Tag' + - name: free_form + in: query + schema: + type: object + - name: any_val + in: query + schema: {} + responses: + '200': + description: OK + +components: + schemas: + Tag: + type: object + properties: + id: + type: integer + name: + type: string