fix(python-flask, python-aiohttp): handle JSON content header/cookie params in generated tests and controllers

KH
1d ago
+297-8

Header and cookie parameters defined with content: application/json (instead of schema) don't work end to end in python-flask / python-aiohttp. There are two problems:

  1. The generated test sends None. The generic example lookup (DefaultCodegen.setParameterExampleValue) only looks at parameter.example, parameter.examples and parameter.schema.example. A content parameter has no schema, and its example lives in the media type. The generated test therefore sends 'X-Json-Header': None. The controller's json.loads(...) fails, and the test gets a 500.
  2. The controller calls object.from_dict(...). When the media type schema is an inline object rather than a $ref model, the generated controller emits x_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. AbstractPythonConnexionServerCodegen overrides setParameterExampleValue for JSON content header/cookie parameters. It takes the example from the first media type, in this order:

    1. the media type's example;
    2. the first entry of examples ($ref resolved);
    3. the schema's example ($ref resolved);
    4. otherwise a minimal JSON value derived from the schema type.

    The value is serialized to JSON and emitted as a Python string literal through the x-python-connexion-test-header-value vendor extension. The flask, aiohttp and blueplanet test templates use it when present.

  • from_dict call. The controller calls X.from_dict(...) for a header/cookie parameter only when its type is an actual generated model, i.e. isModel and not plain object. Inline objects, free-form values, maps and primitives get the json.loads result as is. $ref models generate exactly as before.

  • Parameters defined with schema are unchanged.

Verification

  • New tests in AbstractPythonConnexionServerCodegenTest:

    • the example taken from the media type example, examples, $ref'd examples, schema example, and none;
    • the controller lines for inline and $ref content headers/cookies.

    They fail without the change. Python*Test / AbstractPython*Test pass, 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 $ref content 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 content schema may hit the same object.from_dict issue. This PR keeps to header/cookie parameters.

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) 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 sent None in tests and crashed controllers with 500 errors.

  • Resolves example values from the media type example, first examples entry ($ref resolved), schema example, or a minimal JSON value derived from the schema type, and emits them as JSON string literals in generated tests.
  • Only emits 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.
  • Applies to python-flask, python-aiohttp, and python-blueplanet templates; parameters defined with schema are unchanged.