Repository navigation
fix(python-flask, python-aiohttp): handle JSON content header/cookie params in generated tests and controllers - #25487
Open
khayashi4337 wants to merge 1 commit into
Conversation
…params in generated tests and controllers
Header and cookie parameters declared with `content: application/json`
had two defects in the generated python-flask/python-aiohttp servers:
- The generated test sent `None` as the header value, because the generic
example lookup never inspects parameter content media types, so
`json.loads("None")` made requests fail with HTTP 500. A valid JSON
string literal is now resolved for the test templates from the media
type example, the first `examples` entry (`$ref` resolved), the media
type schema example (`$ref` resolved), or a minimal JSON value derived
from the schema type.
- The generated controller called `X.from_dict()` for every non-primitive
header/cookie param, which rendered `object.from_dict()` (a class that
does not exist) for inline `type: object` schemas and crashed at
runtime. The conversion is now emitted only when the parameter type is
an actual generated model class (`isModel` with a real class name), so
inline objects, free-form objects, maps and primitives pass the
`json.loads` result through unchanged while `$ref` model parameters
keep their existing `Model.from_dict()` conversion.
The same vendor extension covers python-blueplanet templates.
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
2 issues found across 6 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="modules/openapi-generator/src/main/resources/python-flask/controller_test.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/python-flask/controller_test.mustache:31">
P2: Generated tests still omit cookie parameters: `cookieParams` is separate from `headerParams`, so this block never sends the JSON cookie value computed by the generator. Add cookie parameters to the request in both Flask and aiohttp test templates.</violation>
</file>
<file name="modules/openapi-generator/src/test/java/org/openapitools/codegen/python/AbstractPythonConnexionServerCodegenTest.java">
<violation number="1" location="modules/openapi-generator/src/test/java/org/openapitools/codegen/python/AbstractPythonConnexionServerCodegenTest.java:725">
P3: The variant list and per-generator output-path selection are copied into both new tests. Extract a helper that generates each variant once and resolves the test and controller paths, then reuse it in both tests.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
| 'Accept': '{{{mediaType}}}',{{/vendorExtensions.x-preferred-produce}}{{#vendorExtensions.x-preferred-consume}} | ||
| 'Content-Type': '{{{mediaType}}}',{{/vendorExtensions.x-preferred-consume}}{{#headerParams}} | ||
| '{{baseName}}': {{{example}}},{{/headerParams}}{{#authMethods}} | ||
| '{{baseName}}': {{#vendorExtensions.x-python-connexion-test-header-value}}{{{vendorExtensions.x-python-connexion-test-header-value}}}{{/vendorExtensions.x-python-connexion-test-header-value}}{{^vendorExtensions.x-python-connexion-test-header-value}}{{{example}}}{{/vendorExtensions.x-python-connexion-test-header-value}},{{/headerParams}}{{#authMethods}} |
Contributor
There was a problem hiding this comment.
P2: Generated tests still omit cookie parameters: cookieParams is separate from headerParams, so this block never sends the JSON cookie value computed by the generator. Add cookie parameters to the request in both Flask and aiohttp test templates.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At modules/openapi-generator/src/main/resources/python-flask/controller_test.mustache, line 31:
<comment>Generated tests still omit cookie parameters: `cookieParams` is separate from `headerParams`, so this block never sends the JSON cookie value computed by the generator. Add cookie parameters to the request in both Flask and aiohttp test templates.</comment>
<file context>
@@ -28,7 +28,7 @@ class {{#operations}}Test{{classname}}(BaseTestCase):
'Accept': '{{{mediaType}}}',{{/vendorExtensions.x-preferred-produce}}{{#vendorExtensions.x-preferred-consume}}
'Content-Type': '{{{mediaType}}}',{{/vendorExtensions.x-preferred-consume}}{{#headerParams}}
- '{{baseName}}': {{{example}}},{{/headerParams}}{{#authMethods}}
+ '{{baseName}}': {{#vendorExtensions.x-python-connexion-test-header-value}}{{{vendorExtensions.x-python-connexion-test-header-value}}}{{/vendorExtensions.x-python-connexion-test-header-value}}{{^vendorExtensions.x-python-connexion-test-header-value}}{{{example}}}{{/vendorExtensions.x-python-connexion-test-header-value}},{{/headerParams}}{{#authMethods}}
{{#isOAuth}}'Authorization': 'Bearer special-key',{{/isOAuth}}{{#isApiKey}}'{{name}}': 'special-key',{{/isApiKey}}{{#isBasicBasic}}'Authorization': 'Basic Zm9vOmJhcg==',{{/isBasicBasic}}{{#isBasicBearer}}'Authorization': 'Bearer special-key',{{/isBasicBearer}}{{/authMethods}}
}
</file context>
| } | ||
|
|
||
| @Test(description = "content (application/json) header/cookie params get X.from_dict() only for generated model classes; inline object schemas pass the json.loads result through") | ||
| public void testJsonContentHeaderParamsConvertOnlyGeneratedModels() throws IOException { |
Contributor
There was a problem hiding this comment.
P3: The variant list and per-generator output-path selection are copied into both new tests. Extract a helper that generates each variant once and resolves the test and controller paths, then reuse it in both tests.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At modules/openapi-generator/src/test/java/org/openapitools/codegen/python/AbstractPythonConnexionServerCodegenTest.java, line 725:
<comment>The variant list and per-generator output-path selection are copied into both new tests. Extract a helper that generates each variant once and resolves the test and controller paths, then reuse it in both tests.</comment>
<file context>
@@ -674,6 +674,93 @@ public void testSecuritySchemeNamesProduceValidPythonFunctions() throws IOExcept
+ }
+
+ @Test(description = "content (application/json) header/cookie params get X.from_dict() only for generated model classes; inline object schemas pass the json.loads result through")
+ public void testJsonContentHeaderParamsConvertOnlyGeneratedModels() throws IOException {
+ String specPath = "src/test/resources/3_0/python/connexion-json-header-test-values.yaml";
+
</file context>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Header and cookie parameters defined with
content: application/json(instead ofschema) don't work end to end in python-flask / python-aiohttp. There are two problems:None. The generic example lookup (DefaultCodegen.setParameterExampleValue) only looks atparameter.example,parameter.examplesandparameter.schema.example. Acontentparameter has noschema, and its example lives in the media type. The generated test therefore sends'X-Json-Header': None. The controller'sjson.loads(...)fails, and the test gets a 500.object.from_dict(...). When the media type schema is an inline object rather than a$refmodel, the generated controller emitsx_json_header = object.from_dict(x_json_header). That also gives a 500.I didn't find an existing issue for this.
Changes
Example value.
AbstractPythonConnexionServerCodegenoverridessetParameterExampleValuefor JSON content header/cookie parameters. It takes the example from the first media type, in this order:example;examples($refresolved);example($refresolved);The value is serialized to JSON and emitted as a Python string literal through the
x-python-connexion-test-header-valuevendor extension. The flask, aiohttp and blueplanet test templates use it when present.from_dictcall. The controller callsX.from_dict(...)for a header/cookie parameter only when its type is an actual generated model, i.e.isModeland not plainobject. Inline objects, free-form values, maps and primitives get thejson.loadsresult as is.$refmodels generate exactly as before.Parameters defined with
schemaare unchanged.Verification
New tests in
AbstractPythonConnexionServerCodegenTest:example,examples,$ref'd examples, schemaexample, and none;$refcontent headers/cookies.They fail without the change.
Python*Test/AbstractPython*Testpass, including forbiddenapis.The generated tests were run against Connexion 2.14.2 (flask), Connexion 3.3.0 (flask,
useConnexion3) and aiohttp, using specs with inline and$refcontent headers. They return 200, where before they returned 500.bin/generate-samples.sh bin/configs/python*.yaml: no diff.Not covered here: query/path parameters with an inline object
contentschema may hit the sameobject.from_dictissue. This PR keeps to header/cookie parameters.PR checklist
bin/configs/python*.yamlsamples: no diff. Generator options and docs are unchanged.cc @cbornet @tomplus @krjakbrjak @fa0311 (Python technical committee)
Parts of this change were drafted with AI coding assistants (Devin, Claude Code) and reviewed and verified by me.
🤖 Generated with Claude Code
Summary by cubic
Fixes JSON content header/cookie parameters (declared with
content: application/json) in python-flask and python-aiohttp generated tests and controllers, which previously sentNonein tests and crashed controllers with 500 errors.example, firstexamplesentry ($refresolved), schemaexample, or a minimal JSON value derived from the schema type, and emits them as JSON string literals in generated tests.Model.from_dict()conversion when the parameter type is an actual generated model class; inline objects, free-form objects, maps, and primitives pass the parsed JSON through unchanged.schemaare unchanged.Written for commit 8b07eb2. Summary will update on new commits.