fix(python-aiohttp, python-blueplanet): avoid '= .from_dict(' for $ref header/query parameters
For a parameter whose schema is a $ref to a model and that is not a container ā for example a header defined with content: application/json + $ref ā DefaultCodegen.fromParameter leaves baseType null (it is only set for map and array parameters). The python-aiohttp and python-blueplanet controller templates render {{baseType}}.from_dict(...), so the generated controller contains
x_json_arg = .from_dict(x_json_arg) # python-aiohttp
x_json_arg = .from_dict(connexion.request.get_json()) # noqa: E501 # python-blueplanet
and the module fails to import (SyntaxError: invalid syntax). Reproduced with the released openapi-generator-cli 7.26.0 and src/test/resources/3_1/python/json-header-content.yaml.
Change
Apply the fallback that python-flask's controller.mustache already uses ({{baseType}}{{^baseType}}{{#dataType}}{{.}}{{/dataType}}{{/baseType}}) to the python-aiohttp and python-blueplanet controller templates, so the line becomes x_json_arg = HeaderArg.from_dict(...). CodegenParameter has no complexType field, and dataType is the field that holds the model name for these parameters. The template is changed rather than DefaultCodegen, because filling baseType there would affect every generator's {{#baseType}} branches.
Only lines that previously rendered as = .from_dict( change. Comparing 7.26.0 and this branch on a spec with ~20 parameter shapes ($ref enum/object/allOf, inline and free-form objects, uuid/binary/date, arrays, maps, bodies, header/query/path/cookie), every other line is identical. python-flask output is unchanged.
Tests
- Two tests in
AbstractPythonConnexionServerCodegenTest(python-aiohttp and python-blueplanet) generate from the existingjson-header-content.yaml. They assertHeaderArg.from_dict(is emitted and= .from_dict(is not. Both fail without the template change. Python*Test,AbstractPython*Test: 164 run, 0 failures. Samples forbin/configs/python-aiohttp*,python-blueplanet*,python-flask*regenerate with no changes.
Scope and known limitations (pre-existing, not changed here)
This makes the generated controllers importable again. It does not make JSON header parameters work end to end:
- Connexion does not pass
in: headerparameters to handler functions. Only path, query, body and files are injected (see Connexion's request handling docs and the 2.14.2 / 3.x argument-building code). Handlers that declare a header argument therefore still fail at request time in python-aiohttp, python-blueplanet and python-flask alike. - python-blueplanet and python-flask deserialize non-body model parameters from
request.get_json(), which is the request body. - A free-form
type: objectparameter rendersobject.from_dict(...)(previously.from_dict(...)), which is the same as python-flask's current output.
These look like separate issues and I'm happy to open them if that's useful.
PR checklist
- Read the contribution guidelines.
- Run the following to build the project and update samples:
Ran./mvnw clean package || exit ./bin/generate-samples.sh ./bin/configs/*.yaml || exit ./bin/utils/export_docs_generators.sh || exit./mvnw -pl modules/openapi-generator test(5521 tests, 0 failures),./bin/generate-samples.shfor the three affected generators' configs, and./bin/utils/export_docs_generators.sh. Neither produced changed files. - If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.
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 invalid .from_dict(...) calls in generated python-aiohttp and python-blueplanet controllers when a header or query parameter references a model via $ref. The controller templates now fall back to dataType when baseType is null, matching the existing python-flask pattern, so the generated module imports without a SyntaxError.
Adds tests for both generators using the existing json-header-content.yaml fixture, asserting HeaderArg.from_dict( is emitted and no = .from_dict( appears.