Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ public PythonFastAPIServerCodegen() {
languageSpecificPrimitives.add("Dict");
typeMapping.put("array", "List");
typeMapping.put("map", "Dict");
// Binary response body: map OAS file/binary to built-in bytes (not the invalid Py2 type `file`).
// Multipart upload fields remain UploadFile via overrideFileFormParamTyping (#23793).
// See https://github.com/OpenAPITools/openapi-generator/issues/20775
typeMapping.put("file", "bytes");
typeMapping.put("binary", "bytes");

outputFolder = "generated-code" + File.separator + NAME;
modelTemplateFiles.put("model.mustache", ".py");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,23 @@ public void testBinaryMultipartFieldUsesUploadFile() throws IOException {
assertFileContains(baseApi, "csv_file: UploadFile,");
assertFileContains(baseApi, "image: Optional[UploadFile],");
}

@Test(description = "binary response body is typed as bytes, not invalid file (#20775)")
public void testBinaryResponseUsesBytesNotFile() throws IOException {
final DefaultCodegen codegen = new PythonFastAPIServerCodegen();
final String outputPath = generateFiles(codegen, "src/test/resources/3_0/issue_20775.yaml");
final Path api = Paths.get(outputPath + "src/openapi_server/apis/resource_api.py");
final Path baseApi = Paths.get(outputPath + "src/openapi_server/apis/resource_api_base.py");

assertFileExists(api);
assertFileExists(baseApi);

assertFileContains(api, "-> bytes");
assertFileContains(api, "\"model\": bytes");
assertFileNotContains(api, "-> file");
assertFileNotContains(api, "\"model\": file");

assertFileContains(baseApi, "-> bytes");
assertFileNotContains(baseApi, "-> file");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,32 @@ public void testRegexPatternCheckedForArrayItems() throws IOException {
TestUtils.assertFileContains(Paths.get(output + "/src/openapi_server/models/test_object.py"),
"raise ValueError(r\"must validate the regular expression /^[A-Z0-9_\\- ]+$/\")");
}

@Test
public void testBinaryResponseUsesBytesNotFile() throws IOException {
// Regression for https://github.com/OpenAPITools/openapi-generator/issues/20775
// Repro: src/test/resources/3_0/issue_20775.yaml
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();

final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("python-fastapi")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"))
.setInputSpec("src/test/resources/3_0/issue_20775.yaml");

DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);

final String apiFile = output + "/src/openapi_server/apis/resource_api.py";
final String baseApiFile = output + "/src/openapi_server/apis/resource_api_base.py";

TestUtils.assertFileContains(Paths.get(apiFile), "-> bytes");
TestUtils.assertFileContains(Paths.get(apiFile), "\"model\": bytes");
TestUtils.assertFileNotContains(Paths.get(apiFile), "-> file");
TestUtils.assertFileNotContains(Paths.get(apiFile), "\"model\": file");

TestUtils.assertFileContains(Paths.get(baseApiFile), "-> bytes");
TestUtils.assertFileNotContains(Paths.get(baseApiFile), "-> file");
}
}
37 changes: 37 additions & 0 deletions modules/openapi-generator/src/test/resources/3_0/issue_20775.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
openapi: 3.0.1
info:
title: binary response typing
version: 1.0.0
paths:
/resource:
get:
tags:
- resource
description: Binary response body (full or partial)
operationId: resourceInResponse
parameters:
- name: Range
in: header
required: false
schema:
type: string
responses:
"200":
description: Full binary body
content:
application/octet-stream:
schema:
type: string
format: binary
"206":
description: Partial binary body
headers:
Content-Range:
required: true
schema:
type: string
content:
application/octet-stream:
schema:
type: string
format: binary
Loading