Skip to content

fix(python-aiohttp, python-blueplanet, python-flask): map params iterate .items(); free-form params skip from_dict - #25361

Open
khayashi4337 wants to merge 3 commits into
OpenAPITools:masterfrom
khayashi4337:fix/python-aiohttp-map-and-freeform-params
Open

khayashi4337 wants to merge 3 commits into
OpenAPITools:masterfrom
khayashi4337:fix/python-aiohttp-map-and-freeform-params

Conversation

@khayashi4337

@khayashi4337 khayashi4337 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Two small template bugs in the Connexion-based Python server generators (python-aiohttp, python-blueplanet, python-flask), both reproduced with the released openapi-generator-cli 7.26.0.

1. python-aiohttp: map parameters iterate the dict's keys

python-aiohttp/controller.mustache renders map conversions as {k: ...(v) for k, v in {{paramName}}}, without .items(). At runtime this tries to unpack each key string into k, v, which fails with ValueError. The python-blueplanet and python-flask templates already use .items(). This PR adds .items(), and also guards optional map parameters with if {{paramName}} is not None:, since they default to None.

2. Free-form / any-type parameters call object.from_dict(...)

For a non-container parameter whose schema is free-form ({type: object} with no properties) or empty ({}), the type is plain object, and the templates emit x = object.from_dict(x) (python-flask), or x = .from_dict(x) (python-aiohttp and python-blueplanet, which fail to import with SyntaxError). object has no from_dict, so the handler fails at runtime.

AbstractPythonConnexionServerCodegen now marks parameters that are free-form or any-type and whose dataType is plain object with the vendor extension x-python-connexion-skip-from-dict. The templates skip the conversion for those parameters, so they receive the raw value. Parameters whose type is a model are not affected, including typeless composed models (allOf / oneOf refs), which are also any-type but carry a model dataType.

Tests and verification

  • New specs: src/test/resources/3_1/python/map-and-freeform-params.yaml and composed-query-params.yaml. New tests in AbstractPythonConnexionServerCodegenTest. They check that .items() and the None guard are emitted, that free-form and {} parameters get no from_dict, and that Composed.from_dict / OneOfM.from_dict / Pet.from_dict are still emitted for model parameters. Each test fails without its fix.
  • Python*Test, AbstractPython*Test: 164 tests, 0 failures. Samples for bin/configs/python-aiohttp*, python-blueplanet* and python-flask* regenerate with no changes.
  • Compared with 7.26.0 output: for composed-query-params.yaml, default_controller.py is identical in all three generators. For map-and-freeform-params.yaml, the python-aiohttp and python-blueplanet controllers no longer fail py_compile, and the python-flask object.from_dict lines are gone.
  • Called the generated python-aiohttp handler with real map and free-form values, and with the optional maps omitted. It returned 200.

Note on overlap

This touches the same {{^isContainer}}…{{^isPrimitiveType}} blocks of the three controller templates as #25352 and #25362. Whichever lands first, I'll rebase the others.

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    Ran the Python generator tests listed above and regenerated the samples for the three affected generators' configs. No sample changed. Generator options and docs are unchanged.
  • 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 two template bugs in the Python Connexion server generators (python-aiohttp, python-blueplanet, python-flask): map parameters now iterate dict.items(), and free-form or untyped object parameters no longer get deserialized via from_dict.

Bug Fixes

  • Adds .items() to map parameter comprehensions in python-aiohttp and guards optional maps with a None check.
  • Marks free-form and {} schema parameters (with plain object dataType) with the vendor extension x-python-connexion-skip-from-dict, so controllers receive raw values; model and composed model parameters remain unchanged.
  • Adds test specs and generator tests covering map, free-form, and composed model parameters, including maps with additionalProperties.

Written for commit 88f4c75. Summary will update on new commits.

View guided diff

khayashi4337 and others added 2 commits October 22, 2026 13:47
…ms and skip from_dict on free-form params

In python-aiohttp controller.mustache, map parameter comprehensions iterated
over dict keys instead of .items(), raising ValueError at runtime when
unpacking (k, v). Add .items() to match python-blueplanet and python-flask.

In python-aiohttp, python-blueplanet, and python-flask controller.mustache,
guard non-container model deserialization with {{^isFreeFormObject}} and
{{^isAnyType}} so free-form object (schema: {type: object}) and untyped
(schema: {}) parameters are not deserialized via .from_dict().

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…t dataType and guard None map params

Composed schemas without an explicit type (such as allOf or oneOf model $refs)
also set CodegenParameter.isAnyType=true while setting dataType to the model
class name, so guarding controller templates directly with {{^isAnyType}}
skipped Model.from_dict() on composed model parameters. Set the vendor
extension x-python-connexion-skip-from-dict in
AbstractPythonConnexionServerCodegen#postProcessOperationsWithModels only when
(isFreeFormObject || isAnyType) and dataType is "object", and guard the
python-aiohttp map parameter comprehensions with `if <param> is not None:`.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 7 files

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

…ery param test

Verify that the WithAddl query parameter (which defines both properties and
additionalProperties: {type: string}) is classified by DefaultCodegen as a map
container (`isMap=true`, `isContainer=true`) and therefore emits `:type addl:
Dict[str, str]` in the docstring without a `.from_dict()` conversion line in
the controller body, matching 7.26.0 output.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant