From 442cb09189282aae5f7e3d76b7c08a0691330ad9 Mon Sep 17 00:00:00 2001 From: chyroc Date: Thu, 26 Feb 2026 17:48:03 +0800 Subject: [PATCH 1/2] refactor(py): remove files_before_body config support --- config/generator.yaml | 3 --- internal/config/config.go | 1 - internal/generator/generator_test.go | 13 ++++++------- internal/generator/python/operation_render.go | 12 +----------- 4 files changed, 7 insertions(+), 22 deletions(-) diff --git a/config/generator.yaml b/config/generator.yaml index c10650c..c7f88e6 100644 --- a/config/generator.yaml +++ b/config/generator.yaml @@ -4785,7 +4785,6 @@ api: top_k: int sample_rate: int channel: int - files_before_body: true response_type: SpeakerIdentifyResp - path: /v1/audio/voiceprint_groups/{group_id}/features method: post @@ -4811,7 +4810,6 @@ api: desc: str sample_rate: int channel: int - files_before_body: true response_type: CreateVoicePrintGroupFeatureResp - path: /v1/audio/voiceprint_groups/{group_id}/features/{feature_id} method: put @@ -4835,7 +4833,6 @@ api: file: Optional[FileTypes] sample_rate: int channel: int - files_before_body: true response_type: UpdateVoicePrintGroupFeatureResp - path: /v1/audio/voiceprint_groups/{group_id}/features/{feature_id} method: delete diff --git a/internal/config/config.go b/internal/config/config.go index a7616b8..2fd52a3 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -160,7 +160,6 @@ type OperationMapping struct { BodyFixedValues map[string]string `yaml:"body_fixed_values"` BodyBuilder string `yaml:"body_builder"` FilesFields []string `yaml:"files_fields"` - FilesBeforeBody bool `yaml:"files_before_body"` PreDocstringCode []string `yaml:"pre_docstring_code"` PreBodyCode []string `yaml:"pre_body_code"` BodyRequiredFields []string `yaml:"body_required_fields"` diff --git a/internal/generator/generator_test.go b/internal/generator/generator_test.go index 5ee6fb8..ed96aba 100644 --- a/internal/generator/generator_test.go +++ b/internal/generator/generator_test.go @@ -1306,7 +1306,7 @@ func TestRenderOperationMethodPageSizeDefaultAsyncOverride(t *testing.T) { } } -func TestRenderOperationMethodFilesBeforeBody(t *testing.T) { +func TestRenderOperationMethodFilesAfterBody(t *testing.T) { doc := mustParseSwagger(t) details := openapi.OperationDetails{ Path: "/v1/demo/{group_id}/features", @@ -1328,10 +1328,9 @@ func TestRenderOperationMethodFilesBeforeBody(t *testing.T) { MethodName: "create", Details: details, Mapping: &config.OperationMapping{ - BodyBuilder: "remove_none_values", - BodyFields: []string{"name"}, - FilesFields: []string{"file"}, - FilesBeforeBody: true, + BodyBuilder: "remove_none_values", + BodyFields: []string{"name"}, + FilesFields: []string{"file"}, ArgTypes: map[string]string{ "group_id": "str", "name": "str", @@ -1344,8 +1343,8 @@ func TestRenderOperationMethodFilesBeforeBody(t *testing.T) { headersIdx := strings.Index(code, "headers: Optional[dict] = kwargs.get(\"headers\")") filesIdx := strings.Index(code, "files = {\"file\": _try_fix_file(file)}") bodyIdx := strings.Index(code, "body = remove_none_values(") - if headersIdx < 0 || filesIdx < 0 || bodyIdx < 0 || !(headersIdx < filesIdx && filesIdx < bodyIdx) { - t.Fatalf("expected files assignment before body assignment:\n%s", code) + if headersIdx < 0 || filesIdx < 0 || bodyIdx < 0 || !(headersIdx < bodyIdx && bodyIdx < filesIdx) { + t.Fatalf("expected files assignment after body assignment:\n%s", code) } } diff --git a/internal/generator/python/operation_render.go b/internal/generator/python/operation_render.go index 61a3c85..58b486e 100644 --- a/internal/generator/python/operation_render.go +++ b/internal/generator/python/operation_render.go @@ -569,7 +569,6 @@ func renderOperationMethodWithContext( bodyFieldNames := make([]string, 0) bodyFixedValues := map[string]string{} filesFieldNames := make([]string, 0) - filesBeforeBody := false if binding.Mapping != nil && len(binding.Mapping.BodyFields) > 0 { bodyFieldNames = append(bodyFieldNames, binding.Mapping.BodyFields...) } @@ -581,9 +580,6 @@ func renderOperationMethodWithContext( if binding.Mapping != nil && len(binding.Mapping.FilesFields) > 0 { filesFieldNames = append(filesFieldNames, binding.Mapping.FilesFields...) } - if binding.Mapping != nil { - filesBeforeBody = binding.Mapping.FilesBeforeBody - } if !shouldGenerateImplicitRequestBody(details.Method, binding.Mapping, details.RequestBodySchema) { requestBodyType = "" bodyRequired = false @@ -1128,10 +1124,6 @@ func renderOperationMethodWithContext( return true } - if filesBeforeBody { - renderFilesAssignment() - } - if len(bodyFieldNames) > 0 { if bodyBuilder == "raw" { buf.WriteString(fmt.Sprintf(" %s = {\n", bodyVarAssign)) @@ -1213,9 +1205,7 @@ func renderOperationMethodWithContext( buf.WriteString(" request_body = body.model_dump(exclude_none=True) if hasattr(body, \"model_dump\") else body\n") } } - if !filesBeforeBody { - renderFilesAssignment() - } + renderFilesAssignment() if headersExpr == "" && !headersAssigned && includeKwargsHeaders && !isTokenPagination(paginationMode) && !isNumberPagination(paginationMode) && len(details.HeaderParameters) == 0 { needsBlankLine := len(queryFields) > 0 || len(bodyFieldNames) > 0 || From 6c1eac68af2691483b8fad341ade5018a6ef3349 Mon Sep 17 00:00:00 2001 From: chyroc Date: Thu, 26 Feb 2026 20:39:08 +0800 Subject: [PATCH 2/2] refactor(py): unify single-file upload guard expression --- internal/generator/generator_test.go | 4 ++-- internal/generator/python/operation_render.go | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/internal/generator/generator_test.go b/internal/generator/generator_test.go index ed96aba..5672af3 100644 --- a/internal/generator/generator_test.go +++ b/internal/generator/generator_test.go @@ -54,7 +54,7 @@ func TestGeneratePythonAudioTranscriptionsAsyncCreateFromMapping(t *testing.T) { if got := strings.Count(module, "async def create("); got != 1 { t.Fatalf("expected exactly one async create method, got %d", got) } - if !strings.Contains(module, "files = {\"file\": _try_fix_file(file)}") { + if !strings.Contains(module, "files = {\"file\": _try_fix_file(file)} if file else {}") { t.Fatalf("expected generated files payload from mapping/rendering, got:\n%s", module) } if !strings.Contains(module, "return await self._requester.arequest(") { @@ -1341,7 +1341,7 @@ func TestRenderOperationMethodFilesAfterBody(t *testing.T) { code := pygen.RenderOperationMethod(doc, binding, false) headersIdx := strings.Index(code, "headers: Optional[dict] = kwargs.get(\"headers\")") - filesIdx := strings.Index(code, "files = {\"file\": _try_fix_file(file)}") + filesIdx := strings.Index(code, "files = {\"file\": _try_fix_file(file)} if file else {}") bodyIdx := strings.Index(code, "body = remove_none_values(") if headersIdx < 0 || filesIdx < 0 || bodyIdx < 0 || !(headersIdx < bodyIdx && bodyIdx < filesIdx) { t.Fatalf("expected files assignment after body assignment:\n%s", code) diff --git a/internal/generator/python/operation_render.go b/internal/generator/python/operation_render.go index 58b486e..8c10d21 100644 --- a/internal/generator/python/operation_render.go +++ b/internal/generator/python/operation_render.go @@ -1106,11 +1106,7 @@ func renderOperationMethodWithContext( fieldName := filesFieldNames[0] argName := OperationArgName(fieldName, paramAliases) valueExpr := fmt.Sprintf("_try_fix_file(%s)", argName) - if !bodyRequiredSet[fieldName] { - buf.WriteString(fmt.Sprintf(" files = {%q: %s} if %s else {}\n", fieldName, valueExpr, argName)) - return true - } - buf.WriteString(fmt.Sprintf(" files = {%q: %s}\n", fieldName, valueExpr)) + buf.WriteString(fmt.Sprintf(" files = {%q: %s} if %s else {}\n", fieldName, valueExpr, argName)) return true }