fix(python-flask, python-aiohttp): embed info.title, info.description and contact.email as Python literals

KH
7h ago
+263-21

The python server generators (python-flask, python-aiohttp, python-blueplanet) put {{appName}}, {{appDescription}} and {{infoEmail}} into generated Python source. They are used in __main__.py / __init__.py (add_api(..., arguments={'title': ...})) and in setup.py. Those values are HTML-escaped for markup, so:

  • a title such as Tom & Jerry <Service> becomes 'Tom &amp; Jerry &lt;Service&gt;' in the app arguments and in setup.py;
  • the backticks in the petstore description become &#x60; in every setup.py sample;
  • a description containing """ or a backslash produces a setup.py that doesn't compile.

I didn't find an existing issue for this.

Changes

  • AbstractPythonConnexionServerCodegen.preprocessOpenAPI derives Python-safe forms from the raw info values:
    • a single-quoted and a double-quoted literal for the title, matching how each template site quotes it;
    • a double-quoted literal for contact.email;
    • the body of the existing long_description="""...""". Backslashes, runs of " that could close the string, and ASCII control characters are escaped. Newlines are kept, so the """ layout doesn't change.
  • The helpers live in PythonStringUtils. The existing toPythonStringLiteral / toPythonSingleQuotedStringLiteral are reused, and toPythonTripleQuotedStringContent is added.
  • The templates render these values with triple braces. Documentation templates are unchanged.

Verification

  • Python*Test / AbstractPython*Test pass. The new test uses a spec whose title, description and email contain & < ' " \, """, newlines, NUL and \x01. It reads the generated setup.py and app files with Python's ast and checks that the values equal the spec values. It fails without the change.
  • Generated python-flask, python-flask with useConnexion3, python-aiohttp and python-blueplanet from that spec. All .py files pass py_compile with SyntaxWarning treated as an error.
  • python-flask on Connexion 2.14.2 serves the original title in /openapi.json.
  • bin/generate-samples.sh bin/configs/python*.yaml: the only diffs are one line in four setup.py samples, where &#x60; becomes the backtick from the spec.

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 (diff described above). 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 the Python server generators (python-flask, python-aiohttp, python-blueplanet) to embed info.title, info.description, and contact.email as proper Python literals instead of HTML-escaped strings, so generated __main__.py, __init__.py, and setup.py are valid and contain the exact spec values.

Previously, values like &, <, backticks, or triple quotes were HTML-escaped (e.g. &amp;, &#x60;) or could produce setup.py that fails to compile. Now all three generators derive Python-safe forms (single- and double-quoted literals for the title, double-quoted for email, and triple-quoted content for the description) in preprocessOpenAPI and render them via the templates. Added tests that parse generated files with Python's ast and verify the values match the spec; the only sample diffs are four setup.py lines where escaped backticks revert to actual backticks.

  • When the spec declares no contact email, a caller-provided infoEmail is still carried into the setup.py author_email literal instead of collapsing to an empty string.