fix(python-flask, python-aiohttp, python-blueplanet): don't HTML-escape names inside generated Python string literals

KH
1d ago
+221-9

Mustache's {{...}} HTML-escapes its value. The Connexion server templates write property and parameter names into Python string literals that way, so a model property named a&b produces

self.attribute_map = {
    'ab': 'a&b'
}

and from_dict({'a&b': 'x'}) silently drops the value (ab is None). A ' in a name becomes '.

Changes

  • These names are now rendered with {{{...}}} from vendor extensions that hold them escaped for a single-quoted Python literal. The escaping is lossless: \, ', newline, CR, tab and other control characters. It is used for:
    • the model attribute_map (python-flask, python-aiohttp, python-blueplanet);
    • the query keys in the generated controller tests (python-flask, python-aiohttp), and the header names in python-blueplanet's generated tests.
  • Parameters get x-python-connexion-quoted-name, with the same name and meaning as in #25427. That PR covers the header/cookie lookups in the python-flask/python-aiohttp controllers and tests, so this PR leaves those lines alone to avoid conflicts.
  • The generated tests sent an apiKey under the security scheme's name instead of its header name (keyParamName). With scheme apiKeyAuth and header X-Api-Key, the generated test got 401. They now send keyParamName, and only for apiKeys in a header.

Verification

  • Python*Test / AbstractPython*Test pass. A new spec has properties a&b, o'k, back\slash, dq"x and unicodeé, a query parameter q&we's, a header X-A&B'Head, and an apiKey header X-A&B'Key; the test asserts the rendered names for all three generators, plus a unit test for the escaper. The tests fail without the template change.
  • For python-flask, python-aiohttp and python-blueplanet, all generated .py files pass python -m compileall. For python-flask, on Connexion 2.14.2, EscapedNames.from_dict({...}) keeps all five values, and before the change they were dropped.
  • bin/generate-samples.sh bin/configs/python*.yaml produces no diff; no sample uses such names.

Not changed (known)

  • apiKeys in a query parameter or a cookie are still not sent by the generated tests, as before.
  • info.title is still HTML-escaped where it goes into a Python literal (arguments={'title': ...}). This only affects the Swagger UI title.

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
    
    Regenerated all bin/configs/python*.yaml samples: no diff. 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, with reviews by Codex and Fable) and reviewed and verified by me.

🤖 Generated with Claude Code


Summary by cubic

Stops Mustache's HTML escaping from corrupting property and parameter names in generated Python Connexion servers. Names like a&b or o'k were written into Python string literals as a&b or o'k, so from_dict silently dropped such values and generated tests sent wrong keys. These names are now escaped losslessly for single-quoted Python literals via vendor extensions.

Bug Fixes

  • Applies to the model attribute_map in python-flask, python-aiohttp, and python-blueplanet, and to query keys and blueplanet header names in generated tests; parameters use x-python-connexion-quoted-name to match #25427 and avoid conflicts on controller lines.
  • Generated tests now send apiKeys under the header name (keyParamName) instead of the security scheme name, and only for apiKeys in a header.